Whamcloud - gitweb
LU-17705 ptlrpc: replace synchronize_rcu() with rcu_barrier()
[fs/lustre-release.git] / lustre / obdclass / obd_config.c
index 69ca1b4..ed6fa85 100644 (file)
@@ -27,7 +27,6 @@
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
  *
  * lustre/obdclass/obd_config.c
  *
@@ -86,7 +85,6 @@ static const struct rhashtable_params uuid_hash_params = {
        .key_offset     = offsetof(struct obd_export, exp_client_uuid),
        .head_offset    = offsetof(struct obd_export, exp_uuid_hash),
        .obj_cmpfn      = uuid_keycmp,
-       .max_size       = MAX_OBD_DEVICES,
        .automatic_shrinking = true,
 };
 
@@ -170,10 +168,10 @@ static u32 nid_keyhash(const void *data, u32 key_len, u32 seed)
 static int
 nid_keycmp(struct rhashtable_compare_arg *arg, const void *obj)
 {
-       const lnet_nid_t *nid = arg->key;
+       const struct lnet_nid *nid = arg->key;
        const struct obd_export *exp = obj;
 
-       if (exp->exp_connection->c_peer.nid == *nid)
+       if (nid_same(&exp->exp_connection->c_peer.nid, nid))
                return 0;
 
        return -ESRCH;
@@ -188,7 +186,7 @@ nid_export_exit(void *vexport, void *data)
 }
 
 static const struct rhashtable_params nid_hash_params = {
-       .key_len                = sizeof(lnet_nid_t),
+       .key_len                = sizeof(struct lnet_nid),
        .head_offset            = offsetof(struct obd_export, exp_nid_hash),
        .obj_hashfn             = nid_keyhash,
        .obj_cmpfn              = nid_keycmp,
@@ -234,7 +232,7 @@ void obd_nid_del(struct obd_device *obd, struct obd_export *exp)
 }
 EXPORT_SYMBOL(obd_nid_del);
 
-int obd_nid_export_for_each(struct obd_device *obd, lnet_nid_t nid,
+int obd_nid_export_for_each(struct obd_device *obd, struct lnet_nid *nid,
                            int cb(struct obd_export *exp, void *data),
                            void *data)
 {
@@ -243,7 +241,7 @@ int obd_nid_export_for_each(struct obd_device *obd, lnet_nid_t nid,
        int ret = 0;
 
        rcu_read_lock();
-       exports = rhltable_lookup(&obd->obd_nid_hash, &nid, nid_hash_params);
+       exports = rhltable_lookup(&obd->obd_nid_hash, nid, nid_hash_params);
        if (!exports) {
                ret = -ENODEV;
                goto out_unlock;
@@ -411,10 +409,9 @@ EXPORT_SYMBOL(class_match_param);
 
 static int parse_nid(char *buf, void *value, int quiet)
 {
-       lnet_nid_t *nid = (lnet_nid_t *)value;
+       struct lnet_nid *nid = value;
 
-       *nid = libcfs_str2nid(buf);
-       if (*nid != LNET_NID_ANY)
+       if (libcfs_strnid(nid, buf) == 0)
                return 0;
 
        if (!quiet)
@@ -446,18 +443,41 @@ static int class_parse_value(char *buf, int opc, void *value, char **endh,
                             int quiet)
 {
        char *endp;
-       char  tmp;
-       int   rc = 0;
+       char tmp;
+       int rc = 0;
+       int ncolons = 0;
 
        if (!buf)
                return 1;
-       while (*buf == ',' || *buf == ':')
+
+       while (*buf == ',' || *buf == ':') {
+               if (*buf == ':')
+                       ncolons++;
+               else
+                       ncolons = 0;
                buf++;
+       }
+
+       /* IPv6 addresses can start with '::' */
+       if (opc == CLASS_PARSE_NID && ncolons >= 2)
+               buf = buf - 2;
+
        if (*buf == ' ' || *buf == '/' || *buf == '\0')
                return 1;
 
-       /* NID separators or end of NIDs */
-       endp = strpbrk(buf, ",: /");
+       /* NID separators or end of NIDs. Large NIDs can contain ':' so
+        * skip ahead to @ and then look for one of the delimiters.
+        */
+       if (opc == CLASS_PARSE_NID) {
+               endp = strchr(buf, '@');
+               if (!endp)
+                       return 1;
+
+               endp = strpbrk(endp, ",: /");
+       } else {
+               endp = strpbrk(buf, ",: /");
+       }
+
        if (!endp)
                endp = buf + strlen(buf);
 
@@ -481,13 +501,13 @@ static int class_parse_value(char *buf, int opc, void *value, char **endh,
        return 0;
 }
 
-int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
+int class_parse_nid(char *buf, struct lnet_nid *nid, char **endh)
 {
        return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 0);
 }
 EXPORT_SYMBOL(class_parse_nid);
 
-int class_parse_nid_quiet(char *buf, lnet_nid_t *nid, char **endh)
+int class_parse_nid_quiet(char *buf, struct lnet_nid *nid, char **endh)
 {
        return class_parse_value(buf, CLASS_PARSE_NID, (void *)nid, endh, 1);
 }
@@ -503,9 +523,9 @@ int class_parse_net(char *buf, __u32 *net, char **endh)
  * 0 param contains key and not match
  * -1 param does not contain key
  */
-int class_match_nid(char *buf, char *key, lnet_nid_t nid)
+int class_match_nid(char *buf, char *key, struct lnet_nid *nid)
 {
-       lnet_nid_t tmp;
+       struct lnet_nid tmp;
        int rc = -1;
 
        while (class_find_param(buf, key, &buf) == 0) {
@@ -514,13 +534,14 @@ int class_match_nid(char *buf, char *key, lnet_nid_t nid)
                 * the specified NIDs
                 */
                while (class_parse_nid(buf, &tmp, &buf) == 0) {
-                       if (tmp == nid)
+                       if (nid_same(&tmp, nid))
                                return 1;
                }
                rc = 0;
        }
        return rc;
 }
+EXPORT_SYMBOL(class_match_nid);
 
 int class_match_net(char *buf, char *key, __u32 net)
 {
@@ -540,6 +561,7 @@ int class_match_net(char *buf, char *key, __u32 net)
        }
        return rc;
 }
+EXPORT_SYMBOL(class_match_net);
 
 char *lustre_cfg_string(struct lustre_cfg *lcfg, u32 index)
 {
@@ -622,10 +644,10 @@ int class_attach(struct lustre_cfg *lcfg)
                RETURN(rc);
        }
        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
-                "obd %p obd_magic %08X != %08X\n",
+                "obd %px obd_magic %08X != %08X\n",
                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
        LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0,
-                "%p obd_name %s != %s\n", obd, obd->obd_name, name);
+                "%px obd_name %s != %s\n", obd, obd->obd_name, name);
 
        exp = class_new_export_self(obd, &obd->obd_uuid);
        if (IS_ERR(exp)) {
@@ -646,7 +668,7 @@ int class_attach(struct lustre_cfg *lcfg)
 
        obd->obd_attached = 1;
        CDEBUG(D_IOCTL, "OBD: dev %d attached type %s with refcount %d\n",
-              obd->obd_minor, typename, atomic_read(&obd->obd_refcount));
+              obd->obd_minor, typename, kref_read(&obd->obd_refcount));
 
        RETURN(0);
 }
@@ -664,10 +686,10 @@ int class_setup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
        LASSERT(obd != NULL);
        LASSERTF(obd == class_num2obd(obd->obd_minor),
-                "obd %p != obd_devs[%d] %p\n",
+                "obd %px != obd_devs[%d] %px\n",
                 obd, obd->obd_minor, class_num2obd(obd->obd_minor));
        LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC,
-                "obd %p obd_magic %08x != %08x\n",
+                "obd %px obd_magic %08x != %08x\n",
                 obd, obd->obd_magic, OBD_DEVICE_MAGIC);
 
        /* have we attached a type to this device? */
@@ -797,10 +819,10 @@ int class_detach(struct obd_device *obd, struct lustre_cfg *lcfg)
                RETURN(-ENODEV);
        }
        obd->obd_attached = 0;
-       spin_unlock(&obd->obd_dev_lock);
 
        /* cleanup in progress. we don't like to find this device after now */
        class_unregister_device(obd);
+       spin_unlock(&obd->obd_dev_lock);
 
        CDEBUG(D_IOCTL, "detach on obd %s (uuid %s)\n",
               obd->obd_name, obd->obd_uuid.uuid);
@@ -822,7 +844,7 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
        char *flag;
        ENTRY;
 
-       OBD_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
+       CFS_RACE(OBD_FAIL_LDLM_RECOV_CLIENTS);
 
        if (!obd->obd_set_up) {
                CERROR("Device %d not setup\n", obd->obd_minor);
@@ -840,8 +862,8 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
        spin_unlock(&obd->obd_dev_lock);
 
        /* wait for already-arrived-connections to finish. */
-       while (obd->obd_conn_inprogress > 0)
-               yield();
+       wait_var_event(&obd->obd_conn_inprogress,
+                      atomic_read(&obd->obd_conn_inprogress) == 0);
        smp_rmb();
 
        if (lcfg->lcfg_bufcount >= 2 && LUSTRE_CFG_BUFLEN(lcfg, 1) > 0) {
@@ -851,8 +873,8 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
                                obd->obd_force = 1;
                                break;
                        case 'A':
-                               LCONSOLE_WARN("Failing over %s\n",
-                                             obd->obd_name);
+                               LCONSOLE(D_WARNING, "Failing over %s\n",
+                                        obd->obd_name);
                                spin_lock(&obd->obd_dev_lock);
                                obd->obd_fail = 1;
 #ifdef HAVE_SERVER_SUPPORT
@@ -860,7 +882,7 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
 #endif
                                obd->obd_no_recov = 1;
                                spin_unlock(&obd->obd_dev_lock);
-                               if (OBP(obd, iocontrol)) {
+                               if (obd->obd_type->typ_dt_ops->o_iocontrol) {
                                        obd_iocontrol(OBD_IOC_SYNC,
                                                      obd->obd_self_export,
                                                      0, NULL, NULL);
@@ -875,7 +897,7 @@ int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg)
 
        CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d/%d\n",
               obd->obd_name, obd->obd_num_exports,
-              atomic_read(&obd->obd_refcount) - 2);
+              kref_read(&obd->obd_refcount) - 2);
        dump_exports(obd, 0, D_HA);
        class_disconnect_exports(obd);
 
@@ -915,40 +937,40 @@ struct obd_device *class_incref(struct obd_device *obd,
                                const void *source)
 {
        lu_ref_add_atomic(&obd->obd_reference, scope, source);
-       atomic_inc(&obd->obd_refcount);
-       CDEBUG(D_INFO, "incref %s (%p) now %d\n", obd->obd_name, obd,
-              atomic_read(&obd->obd_refcount));
+       kref_get(&obd->obd_refcount);
+       CDEBUG(D_INFO, "incref %s (%p) now %d - %s\n", obd->obd_name, obd,
+              kref_read(&obd->obd_refcount), scope);
 
        return obd;
 }
 EXPORT_SYMBOL(class_incref);
 
-void class_decref(struct obd_device *obd, const char *scope, const void *source)
+static void class_decref_free(struct kref *kref)
 {
-       int last;
+       struct obd_device *obd;
+       struct obd_export *exp;
 
-       CDEBUG(D_INFO, "Decref %s (%p) now %d - %s\n", obd->obd_name, obd,
-              atomic_read(&obd->obd_refcount), scope);
+       obd = container_of(kref, struct obd_device, obd_refcount);
+       LASSERT(!obd->obd_attached);
+       /*
+        * All exports have been destroyed; there should
+        * be no more in-progress ops by this point.
+        */
+       exp = obd->obd_self_export;
 
+       if (exp) {
+               exp->exp_flags |= exp_flags_from_obd(obd);
+               class_unlink_export(exp);
+       }
+}
+
+void class_decref(struct obd_device *obd, const char *scope, const void *source)
+{
+       CDEBUG(D_INFO, "Decref %s (%p) now %d - %s\n", obd->obd_name, obd,
+              kref_read(&obd->obd_refcount), scope);
        LASSERT(obd->obd_num_exports >= 0);
-       last = atomic_dec_and_test(&obd->obd_refcount);
+       kref_put(&obd->obd_refcount, class_decref_free);
        lu_ref_del(&obd->obd_reference, scope, source);
-
-       if (last) {
-               struct obd_export *exp;
-
-               LASSERT(!obd->obd_attached);
-               /*
-                * All exports have been destroyed; there should
-                * be no more in-progress ops by this point.
-                */
-               exp = obd->obd_self_export;
-
-               if (exp) {
-                       exp->exp_flags |= exp_flags_from_obd(obd);
-                       class_unlink_export(exp);
-               }
-       }
 }
 EXPORT_SYMBOL(class_decref);
 
@@ -989,6 +1011,7 @@ int class_add_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
 
        RETURN(rc);
 }
+EXPORT_SYMBOL(class_add_conn);
 
 /** Remove a failover NID location. */
 static int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
@@ -1025,22 +1048,30 @@ static int class_del_conn(struct obd_device *obd, struct lustre_cfg *lcfg)
 static LIST_HEAD(lustre_profile_list);
 static DEFINE_SPINLOCK(lustre_profile_list_lock);
 
-struct lustre_profile *class_get_profile(const char *prof)
+static struct lustre_profile *class_get_profile_nolock(const char *prof)
 {
        struct lustre_profile *lprof;
 
        ENTRY;
-       spin_lock(&lustre_profile_list_lock);
        list_for_each_entry(lprof, &lustre_profile_list, lp_list) {
-               if (!strcmp(lprof->lp_profile, prof)) {
+               if (strcmp(lprof->lp_profile, prof) == 0) {
                        lprof->lp_refs++;
-                       spin_unlock(&lustre_profile_list_lock);
                        RETURN(lprof);
                }
        }
-       spin_unlock(&lustre_profile_list_lock);
        RETURN(NULL);
 }
+
+struct lustre_profile *class_get_profile(const char *prof)
+{
+       struct lustre_profile *lprof;
+
+       ENTRY;
+       spin_lock(&lustre_profile_list_lock);
+       lprof = class_get_profile_nolock(prof);
+       spin_unlock(&lustre_profile_list_lock);
+       RETURN(lprof);
+}
 EXPORT_SYMBOL(class_get_profile);
 
 /**
@@ -1110,9 +1141,9 @@ void class_del_profile(const char *prof)
 
        CDEBUG(D_CONFIG, "Del profile %s\n", prof);
 
-       lprof = class_get_profile(prof);
+       spin_lock(&lustre_profile_list_lock);
+       lprof = class_get_profile_nolock(prof);
        if (lprof) {
-               spin_lock(&lustre_profile_list_lock);
                /* because get profile increments the ref counter */
                lprof->lp_refs--;
                list_del(&lprof->lp_list);
@@ -1120,6 +1151,8 @@ void class_del_profile(const char *prof)
                spin_unlock(&lustre_profile_list_lock);
 
                class_put_profile(lprof);
+       } else {
+               spin_unlock(&lustre_profile_list_lock);
        }
        EXIT;
 }
@@ -1224,7 +1257,7 @@ struct lustre_cfg *lustre_cfg_rename(struct lustre_cfg *cfg,
        if (!new_param)
                GOTO(out_nocfg, new_cfg = ERR_PTR(-ENOMEM));
 
-       strlcpy(new_param, new_name, new_len);
+       strscpy(new_param, new_name, new_len);
        if (value)
                strcat(new_param, value);
 
@@ -1262,6 +1295,7 @@ static ssize_t process_param2_config(struct lustre_cfg *lcfg)
        char *upcall = lustre_cfg_string(lcfg, 2);
        struct kobject *kobj = NULL;
        const char *subsys = param;
+       char *newparam = NULL;
        char *argv[] = {
                [0] = "/usr/sbin/lctl",
                [1] = "set_param",
@@ -1278,15 +1312,15 @@ static ssize_t process_param2_config(struct lustre_cfg *lcfg)
 
        len = strcspn(param, ".=");
        if (!len)
-               return -EINVAL;
+               RETURN(-EINVAL);
 
        /* If we find '=' then its the top level sysfs directory */
        if (param[len] == '=')
-               return class_set_global(param);
+               RETURN(class_set_global(param));
 
        subsys = kstrndup(param, len, GFP_KERNEL);
        if (!subsys)
-               return -ENOMEM;
+               RETURN(-ENOMEM);
 
        kobj = kset_find_obj(lustre_kset, subsys);
        kfree(subsys);
@@ -1317,6 +1351,22 @@ static ssize_t process_param2_config(struct lustre_cfg *lcfg)
                RETURN(-EINVAL);
        }
 
+       /* root_squash and nosquash_nids settings must be applied to
+        * global subsystem (*.) so that it is taken into account by
+        * both client and server sides. So do the equivalent of a
+        * 's / mdt. / *. /'.
+        */
+       if ((strstr(param, PARAM_NOSQUASHNIDS) ||
+            strstr(param, PARAM_ROOTSQUASH)) &&
+           (param[0] != '*' || param[1] != '.')) {
+               newparam = kmalloc(strlen(param) + 1, GFP_NOFS);
+               if (!newparam)
+                       RETURN(-ENOMEM);
+
+               snprintf(newparam, strlen(param) + 1, "*%s", param + len);
+               argv[2] = (char *)newparam;
+       }
+
        start = ktime_get();
        rc = call_usermodehelper(argv[0], argv, NULL, UMH_WAIT_PROC);
        end = ktime_get();
@@ -1332,6 +1382,7 @@ static ssize_t process_param2_config(struct lustre_cfg *lcfg)
                       rc = 0;
        }
 
+       kfree(newparam);
        RETURN(rc);
 }
 
@@ -1343,20 +1394,6 @@ void lustre_register_quota_process_config(int (*qpc)(struct lustre_cfg *lcfg))
 EXPORT_SYMBOL(lustre_register_quota_process_config);
 #endif /* HAVE_SERVER_SUPPORT */
 
-#define QMT0_DEV_NAME_LEN (LUSTRE_MAXFSNAME + sizeof("-QMT0000"))
-static struct obd_device *obd_find_qmt0(char *obd_name)
-{
-       char qmt_name[QMT0_DEV_NAME_LEN];
-       struct obd_device *qmt = NULL;
-
-       if (!server_name2fsname(obd_name, qmt_name, NULL)) {
-               strlcat(qmt_name, "-QMT0000", QMT0_DEV_NAME_LEN);
-               qmt = class_name2obd(qmt_name);
-       }
-
-       return qmt;
-}
-
 /**
  * Process configuration commands given in lustre_cfg form.
  * These may come from direct calls (e.g. class_manual_cleanup)
@@ -1365,6 +1402,7 @@ static struct obd_device *obd_find_qmt0(char *obd_name)
 int class_process_config(struct lustre_cfg *lcfg)
 {
        struct obd_device *obd;
+       struct lnet_nid nid;
        int err;
 
        LASSERT(lcfg && !IS_ERR(lcfg));
@@ -1382,8 +1420,19 @@ int class_process_config(struct lustre_cfg *lcfg)
                       lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid,
                       libcfs_nid2str(lcfg->lcfg_nid));
 
-               err = class_add_uuid(lustre_cfg_string(lcfg, 1),
-                                    lcfg->lcfg_nid);
+               err = 0;
+               if (lcfg->lcfg_nid) {
+                       lnet_nid4_to_nid(lcfg->lcfg_nid, &nid);
+               } else {
+                       char *nidstr = lustre_cfg_string(lcfg, 2);
+
+                       if (nidstr)
+                               err = libcfs_strnid(&nid, nidstr);
+                       else
+                               err = -EINVAL;
+               }
+               if (!err)
+                       err = class_add_uuid(lustre_cfg_string(lcfg, 1), &nid);
                GOTO(out, err);
        }
        case LCFG_DEL_UUID: {
@@ -1421,6 +1470,7 @@ int class_process_config(struct lustre_cfg *lcfg)
                CDEBUG(D_IOCTL, "changing lustre timeout from %d to %d\n",
                       obd_timeout, lcfg->lcfg_num);
                obd_timeout = max(lcfg->lcfg_num, 1U);
+               ping_interval = max(obd_timeout / 4, 1U);
                obd_timeout_set = 1;
                GOTO(out, err = 0);
        }
@@ -1538,42 +1588,20 @@ int class_process_config(struct lustre_cfg *lcfg)
        }
        case LCFG_POOL_NEW: {
                err = obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
-               if (!err && !strcmp(obd->obd_type->typ_name, LUSTRE_LOD_NAME)) {
-                       obd = obd_find_qmt0(obd->obd_name);
-                       if (obd)
-                               obd_pool_new(obd, lustre_cfg_string(lcfg, 2));
-               }
                GOTO(out, err = 0);
        }
        case LCFG_POOL_ADD: {
                err = obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
                                    lustre_cfg_string(lcfg, 3));
-               if (!err && !strcmp(obd->obd_type->typ_name, LUSTRE_LOD_NAME)) {
-                       obd = obd_find_qmt0(obd->obd_name);
-                       if (obd)
-                               obd_pool_add(obd, lustre_cfg_string(lcfg, 2),
-                                            lustre_cfg_string(lcfg, 3));
-               }
                GOTO(out, err = 0);
        }
        case LCFG_POOL_REM: {
                err = obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
                                    lustre_cfg_string(lcfg, 3));
-               if (!err && !strcmp(obd->obd_type->typ_name, LUSTRE_LOD_NAME)) {
-                       obd = obd_find_qmt0(obd->obd_name);
-                       if (obd)
-                               obd_pool_rem(obd, lustre_cfg_string(lcfg, 2),
-                                            lustre_cfg_string(lcfg, 3));
-               }
                GOTO(out, err = 0);
        }
        case LCFG_POOL_DEL: {
                err = obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
-               if (!err && !strcmp(obd->obd_type->typ_name, LUSTRE_LOD_NAME)) {
-                       obd = obd_find_qmt0(obd->obd_name);
-                       if (obd)
-                               obd_pool_del(obd, lustre_cfg_string(lcfg, 2));
-               }
                GOTO(out, err = 0);
        }
        /*
@@ -1632,7 +1660,7 @@ EXPORT_SYMBOL(class_process_config);
 ssize_t class_modify_config(struct lustre_cfg *lcfg, const char *prefix,
                            struct kobject *kobj)
 {
-       struct kobj_type *typ;
+       const struct kobj_type *typ;
        ssize_t count = 0;
        int i;
 
@@ -1642,7 +1670,7 @@ ssize_t class_modify_config(struct lustre_cfg *lcfg, const char *prefix,
        }
 
        typ = get_ktype(kobj);
-       if (!typ || !typ->default_attrs)
+       if (!typ || !typ->default_groups)
                return -ENODEV;
 
        print_lustre_cfg(lcfg);
@@ -1653,11 +1681,10 @@ ssize_t class_modify_config(struct lustre_cfg *lcfg, const char *prefix,
         * or   lctl conf_param lustre-OST0000.osc.max_dirty_mb=36
         */
        for (i = 1; i < lcfg->lcfg_bufcount; i++) {
-               struct attribute *attr;
+               struct attribute *attr = NULL;
                size_t keylen;
                char *value;
                char *key;
-               int j;
 
                key = lustre_cfg_buf(lcfg, i);
                /* Strip off prefix */
@@ -1679,15 +1706,7 @@ ssize_t class_modify_config(struct lustre_cfg *lcfg, const char *prefix,
                keylen = value - key;
                value++;
 
-               attr = NULL;
-               for (j = 0; typ->default_attrs[j]; j++) {
-                       if (!strncmp(typ->default_attrs[j]->name, key,
-                                    keylen)) {
-                               attr = typ->default_attrs[j];
-                               break;
-                       }
-               }
-
+               attr = get_attr_starts_with(typ, key, keylen);
                if (!attr) {
                        char *envp[4], *param, *path;
 
@@ -1971,31 +1990,10 @@ int class_config_llog_handler(const struct lu_env *env,
                        }
                }
 
-               /*
-                * Skip add_conn command if uuid is
-                * not on restricted net
-                */
-               if (cfg && cfg->cfg_sb && s2lsi(cfg->cfg_sb) &&
-                   !IS_SERVER(s2lsi(cfg->cfg_sb))) {
-                       struct lustre_sb_info *lsi = s2lsi(cfg->cfg_sb);
-                       char *uuid_str = lustre_cfg_string(lcfg, 1);
-
-                       if (lcfg->lcfg_command == LCFG_ADD_CONN &&
-                           lsi->lsi_lmd->lmd_nidnet &&
-                           LNET_NIDNET(libcfs_str2nid(uuid_str)) !=
-                           libcfs_str2net(lsi->lsi_lmd->lmd_nidnet)) {
-                               CDEBUG(D_CONFIG, "skipping add_conn for %s\n",
-                                      uuid_str);
-                               rc = 0;
-                               /* No processing! */
-                               break;
-                       }
-               }
-
                OBD_ALLOC(lcfg_new, lustre_cfg_len(bufs.lcfg_bufcount,
                                                   bufs.lcfg_buflen));
                if (!lcfg_new)
-                       GOTO(out, rc = -ENOMEM);
+                       GOTO(out_inst, rc = -ENOMEM);
 
                lustre_cfg_init(lcfg_new, lcfg->lcfg_command, &bufs);
                lcfg_new->lcfg_num   = lcfg->lcfg_num;
@@ -2023,6 +2021,7 @@ int class_config_llog_handler(const struct lu_env *env,
                rc = class_process_config(lcfg_new);
                OBD_FREE(lcfg_new, lustre_cfg_len(lcfg_new->lcfg_bufcount,
                                                  lcfg_new->lcfg_buflens));
+out_inst:
                if (inst_name)
                        OBD_FREE(inst_name, inst_len);
                break;
@@ -2047,6 +2046,7 @@ int class_config_parse_llog(const struct lu_env *env, struct llog_ctxt *ctxt,
 {
        struct llog_process_cat_data cd = {
                .lpcd_first_idx = 0,
+               .lpcd_read_mode = LLOG_READ_MODE_NORMAL,
        };
        struct llog_handle *llh;
        llog_cb_t callback;
@@ -2087,6 +2087,29 @@ parse_out:
 EXPORT_SYMBOL(class_config_parse_llog);
 
 /**
+ * Get marker cfg_flag
+ */
+void llog_get_marker_cfg_flags(struct llog_rec_hdr *rec,
+                              unsigned int *cfg_flags)
+{
+       struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
+       struct cfg_marker *marker;
+
+       if (lcfg->lcfg_command == LCFG_MARKER) {
+               marker = lustre_cfg_buf(lcfg, 1);
+               if (marker->cm_flags & CM_START) {
+                       *cfg_flags = CFG_F_MARKER;
+                       if (marker->cm_flags & CM_SKIP)
+                               *cfg_flags = CFG_F_SKIP;
+               } else if (marker->cm_flags & CM_END) {
+                       *cfg_flags = 0;
+               }
+               CDEBUG(D_INFO, "index=%d, cm_flags=%#08x cfg_flags=%#08x\n",
+                      rec->lrh_index, marker->cm_flags, *cfg_flags);
+       }
+}
+
+/**
  * Parse config record and output dump in supplied buffer.
  *
  * This is separated from class_config_dump_handler() to use
@@ -2096,15 +2119,23 @@ EXPORT_SYMBOL(class_config_parse_llog);
  * - { index: 4, event: attach, device: lustrewt-clilov, type: lov,
  *     UUID: lustrewt-clilov_UUID }
  */
-int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size)
+int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size,
+                            unsigned int *cfg_flags, bool raw)
 {
        struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
        char *ptr = buf;
        char *end = buf + size;
        int rc = 0, i;
        struct lcfg_type_data *ldata;
+       int swab = 0;
 
        LASSERT(rec->lrh_type == OBD_CFG_REC);
+
+       if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
+               lustre_swab_lustre_cfg(lcfg);
+               swab = 1;
+       }
+
        rc = lustre_cfg_sanity_check(lcfg, rec->lrh_len);
        if (rc < 0)
                return rc;
@@ -2113,7 +2144,14 @@ int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size)
        if (!ldata)
                return -ENOTTY;
 
-       if (lcfg->lcfg_command == LCFG_MARKER)
+       llog_get_marker_cfg_flags(rec, cfg_flags);
+       if ((lcfg->lcfg_command == LCFG_MARKER) && likely(!raw))
+               return 0;
+       /* entries outside marker are skipped */
+       if (!(*cfg_flags & CFG_F_MARKER) && !raw)
+               return 0;
+       /* inside skipped marker */
+       if ((*cfg_flags & CFG_F_SKIP) && !raw)
                return 0;
 
        /* form YAML entity */
@@ -2175,6 +2213,25 @@ int class_config_yaml_output(struct llog_rec_hdr *rec, char *buf, int size)
                goto out_done;
        }
 
+       if (lcfg->lcfg_command == LCFG_MARKER) {
+               struct cfg_marker *marker;
+
+               marker = lustre_cfg_buf(lcfg, 1);
+               ptr += snprintf(ptr, end - ptr, ", flags: %#04x",
+                               marker->cm_flags);
+               ptr += snprintf(ptr, end - ptr, ", version: %d.%d.%d.%d",
+                               OBD_OCD_VERSION_MAJOR(marker->cm_vers),
+                               OBD_OCD_VERSION_MINOR(marker->cm_vers),
+                               OBD_OCD_VERSION_PATCH(marker->cm_vers),
+                               OBD_OCD_VERSION_FIX(marker->cm_vers));
+               ptr += snprintf(ptr, end - ptr, ", createtime: %lld",
+                               marker->cm_createtime);
+               ptr += snprintf(ptr, end - ptr, ", canceltime: %lld",
+                               marker->cm_canceltime);
+
+               goto out_done;
+       }
+
        for (i = 1; i < lcfg->lcfg_bufcount; i++) {
                if (LUSTRE_CFG_BUFLEN(lcfg, i) > 0) {
                        ptr += snprintf(ptr, end - ptr, ", %s: %s",
@@ -2332,10 +2389,10 @@ EXPORT_SYMBOL(class_manual_cleanup);
 /*
  * nid<->nidstats hash operations
  */
-static unsigned
-nidstats_hash(struct cfs_hash *hs, const void *key, unsigned int mask)
+static unsigned int
+nidstats_hash(struct cfs_hash *hs, const void *key, const unsigned int bits)
 {
-       return cfs_hash_djb2_hash(key, sizeof(lnet_nid_t), mask);
+       return cfs_hash_djb2_hash(key, sizeof(struct lnet_nid), bits);
 }
 
 static void *
@@ -2351,7 +2408,8 @@ nidstats_key(struct hlist_node *hnode)
 static int
 nidstats_keycmp(const void *key, struct hlist_node *hnode)
 {
-       return *(lnet_nid_t *)nidstats_key(hnode) == *(lnet_nid_t *)key;
+       return nid_same((struct lnet_nid *)nidstats_key(hnode),
+                        (struct lnet_nid *)key);
 }
 
 static void *
@@ -2379,23 +2437,23 @@ nidstats_put_locked(struct cfs_hash *hs, struct hlist_node *hnode)
 }
 
 static struct cfs_hash_ops nid_stat_hash_ops = {
-       .hs_hash        = nidstats_hash,
-       .hs_key         = nidstats_key,
-       .hs_keycmp      = nidstats_keycmp,
-       .hs_object      = nidstats_object,
-       .hs_get         = nidstats_get,
-       .hs_put_locked  = nidstats_put_locked,
+       .hs_hash        = nidstats_hash,
+       .hs_key         = nidstats_key,
+       .hs_keycmp      = nidstats_keycmp,
+       .hs_object      = nidstats_object,
+       .hs_get         = nidstats_get,
+       .hs_put_locked  = nidstats_put_locked,
 };
 
-
 /*
  * client_generation<->export hash operations
  */
 
-static unsigned
-gen_hash(struct cfs_hash *hs, const void *key, unsigned mask)
+static unsigned int
+gen_hash(struct cfs_hash *hs, const void *key, const unsigned int bits)
 {
-       return cfs_hash_djb2_hash(key, sizeof(__u32), mask);
+       /* XXX did hash needs ? */
+       return cfs_hash_djb2_hash(key, sizeof(__u32), bits);
 }
 
 static void *