Whamcloud - gitweb
LU-5396 lod: (and mdt, mgs) make some symbols static
[fs/lustre-release.git] / lustre / mgs / mgs_llog.c
index cd5264e..85a42a9 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Whamcloud, Inc.
+ * Copyright (c) 2011, 2014, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #define D_MGS D_CONFIG
 
 #include <obd.h>
-#include <obd_lov.h>
+#include <lustre_ioctl.h>
 #include <lustre_param.h>
 #include <lustre_sec.h>
-#include <lquota.h>
-#include <lustre_log.h>
+#include <lustre_quota.h>
 
 #include "mgs_internal.h"
 
 /********************** Class functions ********************/
 
-/* Caller must list_del and mgs_dirent_free() each dentry from the list */
+/* Find all logs in CONFIG directory and link then into list */
 int class_dentry_readdir(const struct lu_env *env,
-                        struct mgs_device *mgs, cfs_list_t *list)
+                        struct mgs_device *mgs, struct list_head *log_list)
 {
        struct dt_object    *dir = mgs->mgs_configs_dir;
        const struct dt_it_ops *iops;
@@ -67,10 +66,7 @@ int class_dentry_readdir(const struct lu_env *env,
        char                *key;
        int                  rc, key_sz;
 
-       CFS_INIT_LIST_HEAD(list);
-
-       if (!dt_try_as_dir(env, dir))
-               GOTO(out, rc = -ENOTDIR);
+       INIT_LIST_HEAD(log_list);
 
        LASSERT(dir);
        LASSERT(dir->do_index_ops);
@@ -110,10 +106,10 @@ int class_dentry_readdir(const struct lu_env *env,
                        break;
                }
 
-               memcpy(de->name, key, key_sz);
-               de->name[key_sz] = 0;
+               memcpy(de->mde_name, key, key_sz);
+               de->mde_name[key_sz] = 0;
 
-               cfs_list_add(&de->list, list);
+               list_add(&de->mde_list, log_list);
 
 next:
                rc = iops->next(env, it);
@@ -124,7 +120,6 @@ next:
 
 fini:
        iops->fini(env, it);
-out:
        if (rc)
                CERROR("%s: key failed when listing %s: rc = %d\n",
                       mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
@@ -200,7 +195,7 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
                 CDEBUG(D_MGS, "OST index for %s is %u (%s)\n",
                        lustre_cfg_string(lcfg, 1), index,
                        lustre_cfg_string(lcfg, 2));
-                cfs_set_bit(index, fsdb->fsdb_ost_index_map);
+               set_bit(index, fsdb->fsdb_ost_index_map);
         }
 
         /* Figure out mdt indicies */
@@ -216,7 +211,7 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
                 }
                 rc = 0;
                 CDEBUG(D_MGS, "MDT index is %u\n", index);
-                cfs_set_bit(index, fsdb->fsdb_mdt_index_map);
+               set_bit(index, fsdb->fsdb_mdt_index_map);
                 fsdb->fsdb_mdt_count ++;
         }
 
@@ -232,13 +227,13 @@ static int mgs_fsdb_handler(const struct lu_env *env, struct llog_handle *llh,
         /*
          * compat to 1.8, check osc name used by MDT0 to OSTs, bz18548.
          */
-        if (!cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
+       if (!test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags) &&
             lcfg->lcfg_command == LCFG_ATTACH &&
             strcmp(lustre_cfg_string(lcfg, 1), LUSTRE_OSC_NAME) == 0) {
                 if (OBD_OCD_VERSION_MAJOR(d->ver) == 1 &&
                     OBD_OCD_VERSION_MINOR(d->ver) <= 8) {
                         CWARN("MDT using 1.8 OSC name scheme\n");
-                        cfs_set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
+                       set_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags);
                 }
         }
 
@@ -260,42 +255,35 @@ static int mgs_get_fsdb_from_llog(const struct lu_env *env,
                                  struct mgs_device *mgs,
                                  struct fs_db *fsdb)
 {
-        char *logname;
-        struct llog_handle *loghandle;
-        struct lvfs_run_ctxt saved;
-        struct llog_ctxt *ctxt;
-        struct mgs_fsdb_handler_data d = { fsdb, 0 };
-        int rc, rc2;
-        ENTRY;
+       char                            *logname;
+       struct llog_handle              *loghandle;
+       struct llog_ctxt                *ctxt;
+       struct mgs_fsdb_handler_data     d = { fsdb, 0 };
+       int rc;
+
+       ENTRY;
 
        ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
         LASSERT(ctxt != NULL);
        rc = name_create(&logname, fsdb->fsdb_name, "-client");
        if (rc)
                GOTO(out_put, rc);
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       rc = llog_open_create(NULL, ctxt, &loghandle, NULL, logname);
+       rc = llog_open_create(env, ctxt, &loghandle, NULL, logname);
        if (rc)
                GOTO(out_pop, rc);
 
-       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
        if (rc)
                GOTO(out_close, rc);
 
        if (llog_get_size(loghandle) <= 1)
-               cfs_set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
+               set_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
 
-       rc = llog_process_or_fork(env, loghandle, mgs_fsdb_handler, (void *)&d,
-                                 NULL, false);
+       rc = llog_process(env, loghandle, mgs_fsdb_handler, (void *)&d, NULL);
        CDEBUG(D_INFO, "get_db = %d\n", rc);
 out_close:
-       rc2 = llog_close(NULL, loghandle);
-        if (!rc)
-                rc = rc2;
+       llog_close(env, loghandle);
 out_pop:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
         name_destroy(&logname);
 out_put:
         llog_ctxt_put(ctxt);
@@ -326,10 +314,10 @@ static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
 struct fs_db *mgs_find_fsdb(struct mgs_device *mgs, char *fsname)
 {
         struct fs_db *fsdb;
-        cfs_list_t *tmp;
+       struct list_head *tmp;
 
-        cfs_list_for_each(tmp, &mgs->mgs_fs_db_list) {
-                fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
+       list_for_each(tmp, &mgs->mgs_fs_db_list) {
+               fsdb = list_entry(tmp, struct fs_db, fsdb_list);
                 if (strcmp(fsdb->fsdb_name, fsname) == 0)
                         return fsdb;
         }
@@ -354,12 +342,12 @@ static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
                 RETURN(NULL);
 
         strcpy(fsdb->fsdb_name, fsname);
-        cfs_mutex_init(&fsdb->fsdb_mutex);
-        cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
+       mutex_init(&fsdb->fsdb_mutex);
+       set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
        fsdb->fsdb_gen = 1;
 
         if (strcmp(fsname, MGSSELF_NAME) == 0) {
-                cfs_set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
+               set_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags);
         } else {
                 OBD_ALLOC(fsdb->fsdb_ost_index_map, INDEX_MAP_SIZE);
                 OBD_ALLOC(fsdb->fsdb_mdt_index_map, INDEX_MAP_SIZE);
@@ -381,7 +369,7 @@ static struct fs_db *mgs_new_fsdb(const struct lu_env *env,
                lproc_mgs_add_live(mgs, fsdb);
         }
 
-        cfs_list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
+       list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
 
         RETURN(fsdb);
 err:
@@ -397,10 +385,10 @@ err:
 
 static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
 {
-        /* wait for anyone with the sem */
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
+       /* wait for anyone with the sem */
+       mutex_lock(&fsdb->fsdb_mutex);
        lproc_mgs_del_live(mgs, fsdb);
-        cfs_list_del(&fsdb->fsdb_list);
+       list_del(&fsdb->fsdb_list);
 
         /* deinitialize fsr */
        mgs_ir_fini_fs(mgs, fsdb);
@@ -412,27 +400,28 @@ static void mgs_free_fsdb(struct mgs_device *mgs, struct fs_db *fsdb)
         name_destroy(&fsdb->fsdb_clilov);
         name_destroy(&fsdb->fsdb_clilmv);
         mgs_free_fsdb_srpc(fsdb);
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
+       mutex_unlock(&fsdb->fsdb_mutex);
         OBD_FREE_PTR(fsdb);
 }
 
 int mgs_init_fsdb_list(struct mgs_device *mgs)
 {
-        CFS_INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
+       INIT_LIST_HEAD(&mgs->mgs_fs_db_list);
         return 0;
 }
 
 int mgs_cleanup_fsdb_list(struct mgs_device *mgs)
 {
-        struct fs_db *fsdb;
-        cfs_list_t *tmp, *tmp2;
-        cfs_mutex_lock(&mgs->mgs_mutex);
-        cfs_list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
-                fsdb = cfs_list_entry(tmp, struct fs_db, fsdb_list);
+       struct fs_db *fsdb;
+       struct list_head *tmp, *tmp2;
+
+       mutex_lock(&mgs->mgs_mutex);
+       list_for_each_safe(tmp, tmp2, &mgs->mgs_fs_db_list) {
+               fsdb = list_entry(tmp, struct fs_db, fsdb_list);
                mgs_free_fsdb(mgs, fsdb);
-        }
-        cfs_mutex_unlock(&mgs->mgs_mutex);
-        return 0;
+       }
+       mutex_unlock(&mgs->mgs_mutex);
+       return 0;
 }
 
 int mgs_find_or_make_fsdb(const struct lu_env *env,
@@ -442,27 +431,30 @@ int mgs_find_or_make_fsdb(const struct lu_env *env,
         struct fs_db *fsdb;
         int rc = 0;
 
-        cfs_mutex_lock(&mgs->mgs_mutex);
+       ENTRY;
+       mutex_lock(&mgs->mgs_mutex);
        fsdb = mgs_find_fsdb(mgs, name);
         if (fsdb) {
-                cfs_mutex_unlock(&mgs->mgs_mutex);
+               mutex_unlock(&mgs->mgs_mutex);
                 *dbh = fsdb;
-                return 0;
+               RETURN(0);
         }
 
         CDEBUG(D_MGS, "Creating new db\n");
        fsdb = mgs_new_fsdb(env, mgs, name);
-        cfs_mutex_unlock(&mgs->mgs_mutex);
+       /* lock fsdb_mutex until the db is loaded from llogs */
+       if (fsdb)
+               mutex_lock(&fsdb->fsdb_mutex);
+       mutex_unlock(&mgs->mgs_mutex);
         if (!fsdb)
-                return -ENOMEM;
+               RETURN(-ENOMEM);
 
-        if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
+       if (!test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
                 /* populate the db from the client llog */
                rc = mgs_get_fsdb_from_llog(env, mgs, fsdb);
                 if (rc) {
                         CERROR("Can't get db from client log %d\n", rc);
-                       mgs_free_fsdb(mgs, fsdb);
-                        return rc;
+                       GOTO(out_free, rc);
                 }
         }
 
@@ -470,13 +462,18 @@ int mgs_find_or_make_fsdb(const struct lu_env *env,
        rc = mgs_get_fsdb_srpc_from_llog(env, mgs, fsdb);
         if (rc) {
                 CERROR("Can't get db from params log %d\n", rc);
-               mgs_free_fsdb(mgs, fsdb);
-                return rc;
+               GOTO(out_free, rc);
         }
 
+       mutex_unlock(&fsdb->fsdb_mutex);
         *dbh = fsdb;
 
-        return 0;
+        RETURN(0);
+
+out_free:
+       mutex_unlock(&fsdb->fsdb_mutex);
+       mgs_free_fsdb(mgs, fsdb);
+       return rc;
 }
 
 /* 1 = index in use
@@ -499,7 +496,7 @@ int mgs_check_index(const struct lu_env *env,
                 RETURN(rc);
         }
 
-        if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
+       if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags))
                 RETURN(-1);
 
         if (mti->mti_flags & LDD_F_SV_TYPE_OST)
@@ -509,7 +506,7 @@ int mgs_check_index(const struct lu_env *env,
         else
                 RETURN(-EINVAL);
 
-        if (cfs_test_bit(mti->mti_stripe_index, imap))
+       if (test_bit(mti->mti_stripe_index, imap))
                 RETURN(1);
         RETURN(0);
 }
@@ -518,7 +515,7 @@ static __inline__ int next_index(void *index_map, int map_len)
 {
         int i;
         for (i = 0; i < map_len * 8; i++)
-                 if (!cfs_test_bit(i, index_map)) {
+               if (!test_bit(i, index_map)) {
                          return i;
                  }
         CERROR("max index %d exceeded.\n", i);
@@ -544,37 +541,34 @@ static int mgs_set_index(const struct lu_env *env,
                 RETURN(rc);
         }
 
+       mutex_lock(&fsdb->fsdb_mutex);
         if (mti->mti_flags & LDD_F_SV_TYPE_OST) {
                 imap = fsdb->fsdb_ost_index_map;
         } else if (mti->mti_flags & LDD_F_SV_TYPE_MDT) {
                 imap = fsdb->fsdb_mdt_index_map;
-                if (fsdb->fsdb_mdt_count >= MAX_MDT_COUNT) {
-                        LCONSOLE_ERROR_MSG(0x13f, "The max mdt count"
-                                           "is %d\n", (int)MAX_MDT_COUNT);
-                        RETURN(-ERANGE);
-                }
         } else {
-                RETURN(-EINVAL);
+               GOTO(out_up, rc = -EINVAL);
         }
 
         if (mti->mti_flags & LDD_F_NEED_INDEX) {
                 rc = next_index(imap, INDEX_MAP_SIZE);
                 if (rc == -1)
-                        RETURN(-ERANGE);
+                       GOTO(out_up, rc = -ERANGE);
                 mti->mti_stripe_index = rc;
                 if (mti->mti_flags & LDD_F_SV_TYPE_MDT)
                         fsdb->fsdb_mdt_count ++;
         }
 
-        if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8) {
-                LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %d, "
-                                   "but the max index is %d.\n",
-                                   mti->mti_svname, mti->mti_stripe_index,
-                                   INDEX_MAP_SIZE * 8);
-                RETURN(-ERANGE);
-        }
+       /* the last index(0xffff) is reserved for default value. */
+       if (mti->mti_stripe_index >= INDEX_MAP_SIZE * 8 - 1) {
+               LCONSOLE_ERROR_MSG(0x13f, "Server %s requested index %u, "
+                                  "but index must be less than %u.\n",
+                                  mti->mti_svname, mti->mti_stripe_index,
+                                  INDEX_MAP_SIZE * 8 - 1);
+               GOTO(out_up, rc = -ERANGE);
+       }
 
-        if (cfs_test_bit(mti->mti_stripe_index, imap)) {
+       if (test_bit(mti->mti_stripe_index, imap)) {
                 if ((mti->mti_flags & LDD_F_VIRGIN) &&
                     !(mti->mti_flags & LDD_F_WRITECONF)) {
                         LCONSOLE_ERROR_MSG(0x140, "Server %s requested index "
@@ -582,16 +576,17 @@ static int mgs_set_index(const struct lu_env *env,
                                            "use. Use --writeconf to force\n",
                                            mti->mti_svname,
                                            mti->mti_stripe_index);
-                        RETURN(-EADDRINUSE);
+                       GOTO(out_up, rc = -EADDRINUSE);
                 } else {
                         CDEBUG(D_MGS, "Server %s updating index %d\n",
                                mti->mti_svname, mti->mti_stripe_index);
-                        RETURN(EALREADY);
+                       GOTO(out_up, rc = EALREADY);
                 }
         }
 
-        cfs_set_bit(mti->mti_stripe_index, imap);
-        cfs_clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
+       set_bit(mti->mti_stripe_index, imap);
+       clear_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags);
+       mutex_unlock(&fsdb->fsdb_mutex);
        server_make_name(mti->mti_flags & ~(LDD_F_VIRGIN | LDD_F_WRITECONF),
                         mti->mti_stripe_index, mti->mti_fsname, mti->mti_svname);
 
@@ -599,6 +594,9 @@ static int mgs_set_index(const struct lu_env *env,
                mti->mti_stripe_index);
 
         RETURN(0);
+out_up:
+       mutex_unlock(&fsdb->fsdb_mutex);
+       return rc;
 }
 
 struct mgs_modify_lookup {
@@ -612,9 +610,8 @@ static int mgs_modify_handler(const struct lu_env *env,
 {
        struct mgs_modify_lookup *mml = data;
         struct cfg_marker *marker;
-        struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1);
-        int cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
-                sizeof(struct llog_rec_tail);
+       struct lustre_cfg *lcfg = REC_DATA(rec);
+       int cfg_len = REC_DATA_LEN(rec);
         int rc;
         ENTRY;
 
@@ -646,11 +643,7 @@ static int mgs_modify_handler(const struct lu_env *env,
                 marker->cm_flags &= ~CM_EXCLUDE; /* in case we're unexcluding */
                 marker->cm_flags |= mml->mml_marker.cm_flags;
                 marker->cm_canceltime = mml->mml_marker.cm_canceltime;
-                /* Header and tail are added back to lrh_len in
-                   llog_lvfs_write_rec */
-                rec->lrh_len = cfg_len;
-               rc = llog_write(NULL, llh, rec, NULL, 0, (void *)lcfg,
-                               rec->lrh_index);
+               rc = llog_write(env, llh, rec, rec->lrh_index);
                 if (!rc)
                          mml->mml_modified++;
         }
@@ -658,33 +651,38 @@ static int mgs_modify_handler(const struct lu_env *env,
         RETURN(rc);
 }
 
-/* Modify an existing config log record (for CM_SKIP or CM_EXCLUDE) */
+/**
+ * Modify an existing config log record (for CM_SKIP or CM_EXCLUDE)
+ * Return code:
+ * 0 - modified successfully,
+ * 1 - no modification was done
+ * negative - error
+ */
 static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
                      struct fs_db *fsdb, struct mgs_target_info *mti,
                      char *logname, char *devname, char *comment, int flags)
 {
         struct llog_handle *loghandle;
-        struct lvfs_run_ctxt saved;
         struct llog_ctxt *ctxt;
         struct mgs_modify_lookup *mml;
-        int rc, rc2;
+       int rc;
+
         ENTRY;
 
-        CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
-               flags);
+       LASSERT(mutex_is_locked(&fsdb->fsdb_mutex));
+       CDEBUG(D_MGS, "modify %s/%s/%s fl=%x\n", logname, devname, comment,
+              flags);
 
        ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
         LASSERT(ctxt != NULL);
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       rc = llog_open(NULL, ctxt, &loghandle, NULL, logname,
-                      LLOG_OPEN_EXISTS);
+       rc = llog_open(env, ctxt, &loghandle, NULL, logname, LLOG_OPEN_EXISTS);
        if (rc < 0) {
                if (rc == -ENOENT)
                        rc = 0;
                GOTO(out_pop, rc);
        }
 
-       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
@@ -694,66 +692,103 @@ static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
         OBD_ALLOC_PTR(mml);
         if (!mml)
                 GOTO(out_close, rc = -ENOMEM);
-        strcpy(mml->mml_marker.cm_comment, comment);
-        strcpy(mml->mml_marker.cm_tgtname, devname);
+       if (strlcpy(mml->mml_marker.cm_comment, comment,
+                   sizeof(mml->mml_marker.cm_comment)) >=
+           sizeof(mml->mml_marker.cm_comment))
+               GOTO(out_free, rc = -E2BIG);
+       if (strlcpy(mml->mml_marker.cm_tgtname, devname,
+                   sizeof(mml->mml_marker.cm_tgtname)) >=
+           sizeof(mml->mml_marker.cm_tgtname))
+               GOTO(out_free, rc = -E2BIG);
         /* Modify mostly means cancel */
         mml->mml_marker.cm_flags = flags;
         mml->mml_marker.cm_canceltime = flags ? cfs_time_current_sec() : 0;
         mml->mml_modified = 0;
-       rc = llog_process_or_fork(env, loghandle, mgs_modify_handler,
-                                 (void *)mml, NULL, false);
-        if (!rc && !mml->mml_modified)
+       rc = llog_process(env, loghandle, mgs_modify_handler, (void *)mml,
+                         NULL);
+       if (!rc && !mml->mml_modified)
                rc = 1;
+
+out_free:
         OBD_FREE_PTR(mml);
 
 out_close:
-       rc2 = llog_close(NULL, loghandle);
-        if (!rc)
-                rc = rc2;
+       llog_close(env, loghandle);
 out_pop:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
        if (rc < 0)
-                CERROR("modify %s/%s failed %d\n",
-                       mti->mti_svname, comment, rc);
+               CERROR("%s: modify %s/%s failed: rc = %d\n",
+                      mgs->mgs_obd->obd_name, mti->mti_svname, comment, rc);
         llog_ctxt_put(ctxt);
         RETURN(rc);
 }
 
-/******************** config log recording functions *********************/
+/** This structure is passed to mgs_replace_handler */
+struct mgs_replace_uuid_lookup {
+       /* Nids are replaced for this target device */
+       struct mgs_target_info target;
+       /* Temporary modified llog */
+       struct llog_handle *temp_llh;
+       /* Flag is set if in target block*/
+       int in_target_device;
+       /* Nids already added. Just skip (multiple nids) */
+       int device_nids_added;
+       /* Flag is set if this block should not be copied */
+       int skip_it;
+};
 
-static int record_lcfg(const struct lu_env *env, struct llog_handle *llh,
-                         struct lustre_cfg *lcfg)
+/**
+ * Check: a) if block should be skipped
+ * b) is it target block
+ *
+ * \param[in] lcfg
+ * \param[in] mrul
+ *
+ * \retval 0 should not to be skipped
+ * \retval 1 should to be skipped
+ */
+static int check_markers(struct lustre_cfg *lcfg,
+                        struct mgs_replace_uuid_lookup *mrul)
 {
-        struct lvfs_run_ctxt   saved;
-        struct llog_rec_hdr    rec;
-        int buflen, rc;
-       struct obd_device *obd = llh->lgh_ctxt->loc_obd;
-
-        if (!lcfg || !llh)
-                return -ENOMEM;
+        struct cfg_marker *marker;
+
+       /* Track markers. Find given device */
+       if (lcfg->lcfg_command == LCFG_MARKER) {
+               marker = lustre_cfg_buf(lcfg, 1);
+               /* Clean llog from records marked as CM_EXCLUDE.
+                  CM_SKIP records are used for "active" command
+                  and can be restored if needed */
+               if ((marker->cm_flags & (CM_EXCLUDE | CM_START)) ==
+                   (CM_EXCLUDE | CM_START)) {
+                       mrul->skip_it = 1;
+                       return 1;
+               }
 
-        LASSERT(llh->lgh_ctxt);
+               if ((marker->cm_flags & (CM_EXCLUDE | CM_END)) ==
+                   (CM_EXCLUDE | CM_END)) {
+                       mrul->skip_it = 0;
+                       return 1;
+               }
 
-        buflen = lustre_cfg_len(lcfg->lcfg_bufcount,
-                                lcfg->lcfg_buflens);
-        rec.lrh_len = llog_data_len(buflen);
-        rec.lrh_type = OBD_CFG_REC;
+               if (strcmp(mrul->target.mti_svname, marker->cm_tgtname) == 0) {
+                       LASSERT(!(marker->cm_flags & CM_START) ||
+                               !(marker->cm_flags & CM_END));
+                       if (marker->cm_flags & CM_START) {
+                               mrul->in_target_device = 1;
+                               mrul->device_nids_added = 0;
+                       } else if (marker->cm_flags & CM_END)
+                               mrul->in_target_device = 0;
+               }
+       }
 
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        /* idx = -1 means append */
-       rc = llog_write(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1);
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        if (rc)
-                CERROR("failed %d\n", rc);
-        return rc;
+       return 0;
 }
 
 static int record_base(const struct lu_env *env, struct llog_handle *llh,
                      char *cfgname, lnet_nid_t nid, int cmd,
                      char *s1, char *s2, char *s3, char *s4)
 {
-       struct mgs_thread_info *mgi = mgs_env_info(env);
-       struct lustre_cfg     *lcfg;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct llog_cfg_rec     *lcr;
        int rc;
 
        CDEBUG(D_MGS, "lcfg %s %#x %s %s %s %s\n", cfgname,
@@ -769,29 +804,27 @@ static int record_base(const struct lu_env *env, struct llog_handle *llh,
        if (s4)
                lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 4, s4);
 
-       lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
-       if (!lcfg)
+       lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+       if (lcr == NULL)
                return -ENOMEM;
-       lcfg->lcfg_nid = nid;
 
-       rc = record_lcfg(env, llh, lcfg);
+       lcr->lcr_cfg.lcfg_nid = nid;
+       rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
 
-       lustre_cfg_free(lcfg);
+       lustre_cfg_rec_free(lcr);
 
-        if (rc) {
-                CERROR("error %d: lcfg %s %#x %s %s %s %s\n", rc, cfgname,
-                       cmd, s1, s2, s3, s4);
-        }
+       if (rc < 0)
+               CDEBUG(D_MGS,
+                      "failed to write lcfg %s %#x %s %s %s %s: rc = %d\n",
+                      cfgname, cmd, s1, s2, s3, s4, rc);
        return rc;
 }
 
-
 static inline int record_add_uuid(const struct lu_env *env,
                                  struct llog_handle *llh,
                                  uint64_t nid, char *uuid)
 {
        return record_base(env, llh, NULL, nid, LCFG_ADD_UUID, uuid, 0, 0, 0);
-
 }
 
 static inline int record_add_conn(const struct lu_env *env,
@@ -815,38 +848,456 @@ static inline int record_setup(const struct lu_env *env,
        return record_base(env, llh, devname, 0, LCFG_SETUP, s1, s2, s3, s4);
 }
 
+/**
+ * \retval <0 record processing error
+ * \retval n record is processed. No need copy original one.
+ * \retval 0 record is not processed.
+ */
+static int process_command(const struct lu_env *env, struct lustre_cfg *lcfg,
+                          struct mgs_replace_uuid_lookup *mrul)
+{
+       int nids_added = 0;
+       lnet_nid_t nid;
+       char *ptr;
+       int rc;
+
+       if (lcfg->lcfg_command == LCFG_ADD_UUID) {
+               /* LCFG_ADD_UUID command found. Let's skip original command
+                  and add passed nids */
+               ptr = mrul->target.mti_params;
+               while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                       CDEBUG(D_MGS, "add nid %s with uuid %s, "
+                              "device %s\n", libcfs_nid2str(nid),
+                               mrul->target.mti_params,
+                               mrul->target.mti_svname);
+                       rc = record_add_uuid(env,
+                                            mrul->temp_llh, nid,
+                                            mrul->target.mti_params);
+                       if (!rc)
+                               nids_added++;
+               }
+
+               if (nids_added == 0) {
+                       CERROR("No new nids were added, nid %s with uuid %s, "
+                              "device %s\n", libcfs_nid2str(nid),
+                              mrul->target.mti_params,
+                              mrul->target.mti_svname);
+                       RETURN(-ENXIO);
+               } else {
+                       mrul->device_nids_added = 1;
+               }
+
+               return nids_added;
+       }
+
+       if (mrul->device_nids_added && lcfg->lcfg_command == LCFG_SETUP) {
+               /* LCFG_SETUP command found. UUID should be changed */
+               rc = record_setup(env,
+                                 mrul->temp_llh,
+                                 /* devname the same */
+                                 lustre_cfg_string(lcfg, 0),
+                                 /* s1 is not changed */
+                                 lustre_cfg_string(lcfg, 1),
+                                 /* new uuid should be
+                                 the full nidlist */
+                                 mrul->target.mti_params,
+                                 /* s3 is not changed */
+                                 lustre_cfg_string(lcfg, 3),
+                                 /* s4 is not changed */
+                                 lustre_cfg_string(lcfg, 4));
+               return rc ? rc : 1;
+       }
+
+       /* Another commands in target device block */
+       return 0;
+}
+
+/**
+ * Handler that called for every record in llog.
+ * Records are processed in order they placed in llog.
+ *
+ * \param[in] llh       log to be processed
+ * \param[in] rec       current record
+ * \param[in] data      mgs_replace_uuid_lookup structure
+ *
+ * \retval 0    success
+ */
+static int mgs_replace_handler(const struct lu_env *env,
+                              struct llog_handle *llh,
+                              struct llog_rec_hdr *rec,
+                              void *data)
+{
+       struct mgs_replace_uuid_lookup *mrul;
+       struct lustre_cfg *lcfg = REC_DATA(rec);
+       int cfg_len = REC_DATA_LEN(rec);
+       int rc;
+       ENTRY;
+
+       mrul = (struct mgs_replace_uuid_lookup *)data;
+
+       if (rec->lrh_type != OBD_CFG_REC) {
+               CERROR("unhandled lrh_type: %#x, cmd %x %s %s\n",
+                      rec->lrh_type, lcfg->lcfg_command,
+                      lustre_cfg_string(lcfg, 0),
+                      lustre_cfg_string(lcfg, 1));
+               RETURN(-EINVAL);
+       }
+
+       rc = lustre_cfg_sanity_check(lcfg, cfg_len);
+       if (rc) {
+               /* Do not copy any invalidated records */
+               GOTO(skip_out, rc = 0);
+       }
+
+       rc = check_markers(lcfg, mrul);
+       if (rc || mrul->skip_it)
+               GOTO(skip_out, rc = 0);
+
+       /* Write to new log all commands outside target device block */
+       if (!mrul->in_target_device)
+               GOTO(copy_out, rc = 0);
+
+       /* Skip all other LCFG_ADD_UUID and LCFG_ADD_CONN records
+          (failover nids) for this target, assuming that if then
+          primary is changing then so is the failover */
+       if (mrul->device_nids_added &&
+           (lcfg->lcfg_command == LCFG_ADD_UUID ||
+            lcfg->lcfg_command == LCFG_ADD_CONN))
+               GOTO(skip_out, rc = 0);
+
+       rc = process_command(env, lcfg, mrul);
+       if (rc < 0)
+               RETURN(rc);
+
+       if (rc)
+               RETURN(0);
+copy_out:
+       /* Record is placed in temporary llog as is */
+       rc = llog_write(env, mrul->temp_llh, rec, LLOG_NEXT_IDX);
+
+       CDEBUG(D_MGS, "Copied idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
+              rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
+              lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
+       RETURN(rc);
+
+skip_out:
+       CDEBUG(D_MGS, "Skipped idx=%d, rc=%d, len=%d, cmd %x %s %s\n",
+              rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command,
+              lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1));
+       RETURN(rc);
+}
+
+static int mgs_log_is_empty(const struct lu_env *env,
+                           struct mgs_device *mgs, char *name)
+{
+       struct llog_ctxt        *ctxt;
+       int                      rc;
+
+       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+       LASSERT(ctxt != NULL);
+
+       rc = llog_is_empty(env, ctxt, name);
+       llog_ctxt_put(ctxt);
+       return rc;
+}
+
+static int mgs_replace_nids_log(const struct lu_env *env,
+                               struct obd_device *mgs, struct fs_db *fsdb,
+                               char *logname, char *devname, char *nids)
+{
+       struct llog_handle *orig_llh, *backup_llh;
+       struct llog_ctxt *ctxt;
+       struct mgs_replace_uuid_lookup *mrul;
+       struct mgs_device *mgs_dev = lu2mgs_dev(mgs->obd_lu_dev);
+       static struct obd_uuid   cfg_uuid = { .uuid = "config_uuid" };
+       char *backup;
+       int rc, rc2;
+       ENTRY;
+
+       CDEBUG(D_MGS, "Replace nids for %s in %s\n", devname, logname);
+
+       ctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
+       LASSERT(ctxt != NULL);
+
+       if (mgs_log_is_empty(env, mgs_dev, logname)) {
+               /* Log is empty. Nothing to replace */
+               GOTO(out_put, rc = 0);
+       }
+
+       OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
+       if (backup == NULL)
+               GOTO(out_put, rc = -ENOMEM);
+
+       sprintf(backup, "%s.bak", logname);
+
+       rc = llog_backup(env, mgs, ctxt, ctxt, logname, backup);
+       if (rc == 0) {
+               /* Now erase original log file. Connections are not allowed.
+                  Backup is already saved */
+               rc = llog_erase(env, ctxt, NULL, logname);
+               if (rc < 0)
+                       GOTO(out_free, rc);
+       } else if (rc != -ENOENT) {
+               CERROR("%s: can't make backup for %s: rc = %d\n",
+                      mgs->obd_name, logname, rc);
+               GOTO(out_free,rc);
+       }
+
+       /* open local log */
+       rc = llog_open_create(env, ctxt, &orig_llh, NULL, logname);
+       if (rc)
+               GOTO(out_restore, rc);
+
+       rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
+       if (rc)
+               GOTO(out_closel, rc);
+
+       /* open backup llog */
+       rc = llog_open(env, ctxt, &backup_llh, NULL, backup,
+                      LLOG_OPEN_EXISTS);
+       if (rc)
+               GOTO(out_closel, rc);
+
+       rc = llog_init_handle(env, backup_llh, LLOG_F_IS_PLAIN, NULL);
+       if (rc)
+               GOTO(out_close, rc);
+
+       if (llog_get_size(backup_llh) <= 1)
+               GOTO(out_close, rc = 0);
+
+       OBD_ALLOC_PTR(mrul);
+       if (!mrul)
+               GOTO(out_close, rc = -ENOMEM);
+       /* devname is only needed information to replace UUID records */
+       strlcpy(mrul->target.mti_svname, devname,
+               sizeof(mrul->target.mti_svname));
+       /* parse nids later */
+       strlcpy(mrul->target.mti_params, nids, sizeof(mrul->target.mti_params));
+       /* Copy records to this temporary llog */
+       mrul->temp_llh = orig_llh;
+
+       rc = llog_process(env, backup_llh, mgs_replace_handler,
+                         (void *)mrul, NULL);
+       OBD_FREE_PTR(mrul);
+out_close:
+       rc2 = llog_close(NULL, backup_llh);
+       if (!rc)
+               rc = rc2;
+out_closel:
+       rc2 = llog_close(NULL, orig_llh);
+       if (!rc)
+               rc = rc2;
+
+out_restore:
+       if (rc) {
+               CERROR("%s: llog should be restored: rc = %d\n",
+                      mgs->obd_name, rc);
+               rc2 = llog_backup(env, mgs, ctxt, ctxt, backup,
+                                 logname);
+               if (rc2 < 0)
+                       CERROR("%s: can't restore backup %s: rc = %d\n",
+                              mgs->obd_name, logname, rc2);
+       }
+
+out_free:
+       OBD_FREE(backup, strlen(backup) + 1);
+
+out_put:
+       llog_ctxt_put(ctxt);
+
+       if (rc)
+               CERROR("%s: failed to replace nids in log %s: rc = %d\n",
+                      mgs->obd_name, logname, rc);
+
+       RETURN(rc);
+}
+
+/**
+ * Parse device name and get file system name and/or device index
+ *
+ * \param[in]   devname device name (ex. lustre-MDT0000)
+ * \param[out]  fsname  file system name(optional)
+ * \param[out]  index   device index(optional)
+ *
+ * \retval 0    success
+ */
+static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
+{
+       int rc;
+       ENTRY;
+
+       /* Extract fsname */
+       if (fsname) {
+               rc = server_name2fsname(devname, fsname, NULL);
+               if (rc < 0) {
+                       CDEBUG(D_MGS, "Device name %s without fsname\n",
+                              devname);
+                       RETURN(-EINVAL);
+               }
+       }
+
+       if (index) {
+               rc = server_name2index(devname, index, NULL);
+               if (rc < 0) {
+                       CDEBUG(D_MGS, "Device name %s with wrong index\n",
+                              devname);
+                       RETURN(-EINVAL);
+               }
+       }
+
+       RETURN(0);
+}
+
+/* This is only called during replace_nids */
+static int only_mgs_is_running(struct obd_device *mgs_obd)
+{
+       /* TDB: Is global variable with devices count exists? */
+       int num_devices = get_devices_count();
+       int num_exports = 0;
+       struct obd_export *exp;
+
+       spin_lock(&mgs_obd->obd_dev_lock);
+       list_for_each_entry(exp, &mgs_obd->obd_exports, exp_obd_chain) {
+               /* skip self export */
+               if (exp == mgs_obd->obd_self_export)
+                       continue;
+               if (exp_connect_flags(exp) & OBD_CONNECT_MDS_MDS)
+                       continue;
+
+               ++num_exports;
+
+               CERROR("%s: node %s still connected during replace_nids "
+                      "connect_flags:%llx\n",
+                      mgs_obd->obd_name,
+                      libcfs_nid2str(exp->exp_nid_stats->nid),
+                      exp_connect_flags(exp));
+
+       }
+       spin_unlock(&mgs_obd->obd_dev_lock);
+
+       /* osd, MGS and MGC + self_export
+          (wc -l /proc/fs/lustre/devices <= 2) && (non self exports == 0) */
+       return (num_devices <= 3) && (num_exports == 0);
+}
+
+static int name_create_mdt(char **logname, char *fsname, int i)
+{
+       char mdt_index[9];
+
+       sprintf(mdt_index, "-MDT%04x", i);
+       return name_create(logname, fsname, mdt_index);
+}
+
+/**
+ * Replace nids for \a device to \a nids values
+ *
+ * \param obd           MGS obd device
+ * \param devname       nids need to be replaced for this device
+ * (ex. lustre-OST0000)
+ * \param nids          nids list (ex. nid1,nid2,nid3)
+ *
+ * \retval 0    success
+ */
+int mgs_replace_nids(const struct lu_env *env,
+                    struct mgs_device *mgs,
+                    char *devname, char *nids)
+{
+       /* Assume fsname is part of device name */
+       char fsname[MTI_NAME_MAXLEN];
+       int rc;
+       __u32 index;
+       char *logname;
+       struct fs_db *fsdb;
+       unsigned int i;
+       int conn_state;
+       struct obd_device *mgs_obd = mgs->mgs_obd;
+       ENTRY;
+
+       /* We can only change NIDs if no other nodes are connected */
+       spin_lock(&mgs_obd->obd_dev_lock);
+       conn_state = mgs_obd->obd_no_conn;
+       mgs_obd->obd_no_conn = 1;
+       spin_unlock(&mgs_obd->obd_dev_lock);
+
+       /* We can not change nids if not only MGS is started */
+       if (!only_mgs_is_running(mgs_obd)) {
+               CERROR("Only MGS is allowed to be started\n");
+               GOTO(out, rc = -EINPROGRESS);
+       }
+
+       /* Get fsname and index*/
+       rc = mgs_parse_devname(devname, fsname, &index);
+       if (rc)
+               GOTO(out, rc);
+
+       rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
+       if (rc) {
+               CERROR("%s: can't find fsdb: rc = %d\n", fsname, rc);
+               GOTO(out, rc);
+       }
+
+       /* Process client llogs */
+       name_create(&logname, fsname, "-client");
+       rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
+       name_destroy(&logname);
+       if (rc) {
+               CERROR("%s: error while replacing NIDs for %s: rc = %d\n",
+                      fsname, devname, rc);
+               GOTO(out, rc);
+       }
+
+       /* Process MDT llogs */
+       for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+               if (!test_bit(i, fsdb->fsdb_mdt_index_map))
+                       continue;
+               name_create_mdt(&logname, fsname, i);
+               rc = mgs_replace_nids_log(env, mgs_obd, fsdb, logname, devname, nids);
+               name_destroy(&logname);
+               if (rc)
+                       GOTO(out, rc);
+       }
+
+out:
+       spin_lock(&mgs_obd->obd_dev_lock);
+       mgs_obd->obd_no_conn = conn_state;
+       spin_unlock(&mgs_obd->obd_dev_lock);
+
+       RETURN(rc);
+}
+
 static int record_lov_setup(const struct lu_env *env, struct llog_handle *llh,
                            char *devname, struct lov_desc *desc)
 {
-       struct mgs_thread_info *mgi = mgs_env_info(env);
-       struct lustre_cfg *lcfg;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct llog_cfg_rec     *lcr;
        int rc;
 
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
        lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
-       lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
-       if (!lcfg)
+       lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
+       if (lcr == NULL)
                return -ENOMEM;
-       rc = record_lcfg(env, llh, lcfg);
 
-       lustre_cfg_free(lcfg);
+       rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+       lustre_cfg_rec_free(lcr);
        return rc;
 }
 
 static int record_lmv_setup(const struct lu_env *env, struct llog_handle *llh,
                             char *devname, struct lmv_desc *desc)
 {
-       struct mgs_thread_info *mgi = mgs_env_info(env);
-       struct lustre_cfg *lcfg;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct llog_cfg_rec     *lcr;
        int rc;
 
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, devname);
        lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, desc, sizeof(*desc));
-       lcfg = lustre_cfg_new(LCFG_SETUP, &mgi->mgi_bufs);
-
-       rc = record_lcfg(env, llh, lcfg);
+       lcr = lustre_cfg_rec_new(LCFG_SETUP, &mgi->mgi_bufs);
+       if (lcr == NULL)
+               return -ENOMEM;
 
-       lustre_cfg_free(lcfg);
+       rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+       lustre_cfg_rec_free(lcr);
        return rc;
 }
 
@@ -866,7 +1317,7 @@ static inline int record_lov_add(const struct lu_env *env,
                                  char *index, char *gen)
 {
        return record_base(env,llh,lov_name,0,LCFG_LOV_ADD_OBD,
-                           ost_uuid,index,gen,0);
+                          ost_uuid, index, gen, 0);
 }
 
 static inline int record_mount_opt(const struct lu_env *env,
@@ -884,112 +1335,78 @@ static int record_marker(const struct lu_env *env,
                          char *tgtname, char *comment)
 {
        struct mgs_thread_info *mgi = mgs_env_info(env);
-       struct lustre_cfg *lcfg;
+       struct llog_cfg_rec *lcr;
        int rc;
+       int cplen = 0;
 
        if (flags & CM_START)
                fsdb->fsdb_gen++;
        mgi->mgi_marker.cm_step = fsdb->fsdb_gen;
        mgi->mgi_marker.cm_flags = flags;
        mgi->mgi_marker.cm_vers = LUSTRE_VERSION_CODE;
-       strncpy(mgi->mgi_marker.cm_tgtname, tgtname,
-               sizeof(mgi->mgi_marker.cm_tgtname));
-       strncpy(mgi->mgi_marker.cm_comment, comment,
-               sizeof(mgi->mgi_marker.cm_comment));
+       cplen = strlcpy(mgi->mgi_marker.cm_tgtname, tgtname,
+                       sizeof(mgi->mgi_marker.cm_tgtname));
+       if (cplen >= sizeof(mgi->mgi_marker.cm_tgtname))
+               return -E2BIG;
+       cplen = strlcpy(mgi->mgi_marker.cm_comment, comment,
+                       sizeof(mgi->mgi_marker.cm_comment));
+       if (cplen >= sizeof(mgi->mgi_marker.cm_comment))
+               return -E2BIG;
        mgi->mgi_marker.cm_createtime = cfs_time_current_sec();
        mgi->mgi_marker.cm_canceltime = 0;
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
        lustre_cfg_bufs_set(&mgi->mgi_bufs, 1, &mgi->mgi_marker,
                            sizeof(mgi->mgi_marker));
-       lcfg = lustre_cfg_new(LCFG_MARKER, &mgi->mgi_bufs);
-       if (!lcfg)
+       lcr = lustre_cfg_rec_new(LCFG_MARKER, &mgi->mgi_bufs);
+       if (lcr == NULL)
                return -ENOMEM;
-       rc = record_lcfg(env, llh, lcfg);
 
-       lustre_cfg_free(lcfg);
+       rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
+       lustre_cfg_rec_free(lcr);
        return rc;
 }
 
-static int record_start_log(const struct lu_env *env,
-                           struct mgs_device *mgs,
-                            struct llog_handle **llh, char *name)
+static int record_start_log(const struct lu_env *env, struct mgs_device *mgs,
+                           struct llog_handle **llh, char *name)
 {
-        static struct obd_uuid cfg_uuid = { .uuid = "config_uuid" };
-        struct lvfs_run_ctxt saved;
-        struct llog_ctxt *ctxt;
-        int rc = 0;
+       static struct obd_uuid   cfg_uuid = { .uuid = "config_uuid" };
+       struct llog_ctxt        *ctxt;
+       int                      rc = 0;
+       ENTRY;
 
-        if (*llh)
-                GOTO(out, rc = -EBUSY);
+       if (*llh)
+               GOTO(out, rc = -EBUSY);
 
        ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
         if (!ctxt)
                 GOTO(out, rc = -ENODEV);
        LASSERT(ctxt->loc_obd == mgs->mgs_obd);
 
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       rc = llog_open_create(NULL, ctxt, llh, NULL, name);
+       rc = llog_open_create(env, ctxt, llh, NULL, name);
        if (rc)
                GOTO(out_ctxt, rc);
-       rc = llog_init_handle(NULL, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
-       if (rc) {
-               llog_close(NULL, *llh);
-               *llh = NULL;
-       }
+       rc = llog_init_handle(env, *llh, LLOG_F_IS_PLAIN, &cfg_uuid);
+       if (rc)
+               llog_close(env, *llh);
 out_ctxt:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
 out:
-       if (rc)
-               CERROR("Can't start log %s: %d\n", name, rc);
+       if (rc) {
+               CERROR("%s: can't start log %s: rc = %d\n",
+                      mgs->mgs_obd->obd_name, name, rc);
+               *llh = NULL;
+       }
        RETURN(rc);
 }
 
 static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
 {
-        struct lvfs_run_ctxt saved;
-       struct obd_device *obd = (*llh)->lgh_ctxt->loc_obd;
-        int rc = 0;
-
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_close(NULL, *llh);
-        *llh = NULL;
-
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        RETURN(rc);
-}
-
-static int mgs_log_is_empty(const struct lu_env *env,
-                           struct mgs_device *mgs, char *name)
-{
-        struct lvfs_run_ctxt saved;
-        struct llog_handle *llh;
-        struct llog_ctxt *ctxt;
-        int rc = 0;
-
-       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
-        LASSERT(ctxt != NULL);
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       rc = llog_open(NULL, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_ctxt, rc);
-       }
+       int rc;
 
-       llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_close, rc);
-       rc = llog_get_size(llh);
+       rc = llog_close(env, *llh);
+       *llh = NULL;
 
-out_close:
-       llog_close(NULL, llh);
-out_ctxt:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-       llog_ctxt_put(ctxt);
-       /* header is record 1 */
-       return (rc <= 1);
+       return rc;
 }
 
 /******************** config "macros" *********************/
@@ -997,25 +1414,23 @@ out_ctxt:
 /* write an lcfg directly into a log (with markers) */
 static int mgs_write_log_direct(const struct lu_env *env,
                                struct mgs_device *mgs, struct fs_db *fsdb,
-                                char *logname, struct lustre_cfg *lcfg,
-                                char *devname, char *comment)
+                               char *logname, struct llog_cfg_rec *lcr,
+                               char *devname, char *comment)
 {
-        struct llog_handle *llh = NULL;
-        int rc;
-        ENTRY;
+       struct llog_handle *llh = NULL;
+       int rc;
 
-        if (!lcfg)
-                RETURN(-ENOMEM);
+       ENTRY;
 
        rc = record_start_log(env, mgs, &llh, logname);
-        if (rc)
-                RETURN(rc);
+       if (rc)
+               RETURN(rc);
 
         /* FIXME These should be a single journal transaction */
        rc = record_marker(env, llh, fsdb, CM_START, devname, comment);
        if (rc)
                GOTO(out_end, rc);
-       rc = record_lcfg(env, llh, lcfg);
+       rc = llog_write(env, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
        if (rc)
                GOTO(out_end, rc);
        rc = record_marker(env, llh, fsdb, CM_END, devname, comment);
@@ -1027,99 +1442,104 @@ out_end:
 }
 
 /* write the lcfg in all logs for the given fs */
-int mgs_write_log_direct_all(const struct lu_env *env,
-                            struct mgs_device *mgs,
-                            struct fs_db *fsdb,
-                            struct mgs_target_info *mti,
-                            struct lustre_cfg *lcfg,
-                            char *devname, char *comment,
-                            int server_only)
+static int mgs_write_log_direct_all(const struct lu_env *env,
+                                   struct mgs_device *mgs,
+                                   struct fs_db *fsdb,
+                                   struct mgs_target_info *mti,
+                                   struct llog_cfg_rec *lcr, char *devname,
+                                   char *comment, int server_only)
 {
-       cfs_list_t list;
-       struct mgs_direntry *dirent, *n;
-        char *fsname = mti->mti_fsname;
-        char *logname;
-        int rc = 0, len = strlen(fsname);
-        ENTRY;
+       struct list_head         log_list;
+       struct mgs_direntry     *dirent, *n;
+       char                    *fsname = mti->mti_fsname;
+       int                      rc = 0, len = strlen(fsname);
 
-        /* We need to set params for any future logs
-           as well. FIXME Append this file to every new log.
-           Actually, we should store as params (text), not llogs.  Or
-           in a database. */
-       rc = name_create(&logname, fsname, "-params");
+       ENTRY;
+       /* Find all the logs in the CONFIGS directory */
+       rc = class_dentry_readdir(env, mgs, &log_list);
        if (rc)
                RETURN(rc);
-       if (mgs_log_is_empty(env, mgs, logname)) {
-               struct llog_handle *llh = NULL;
-               rc = record_start_log(env, mgs, &llh, logname);
-               record_end_log(env, &llh);
-        }
-        name_destroy(&logname);
-        if (rc)
-                RETURN(rc);
-
-        /* Find all the logs in the CONFIGS directory */
-       rc = class_dentry_readdir(env, mgs, &list);
-       if (rc)
-                RETURN(rc);
 
-        /* Could use fsdb index maps instead of directory listing */
-       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
-               cfs_list_del(&dirent->list);
-                /* don't write to sptlrpc rule log */
-               if (strstr(dirent->name, "-sptlrpc") != NULL)
+       /* Could use fsdb index maps instead of directory listing */
+       list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+               list_del_init(&dirent->mde_list);
+               /* don't write to sptlrpc rule log */
+               if (strstr(dirent->mde_name, "-sptlrpc") != NULL)
                        goto next;
 
                /* caller wants write server logs only */
-               if (server_only && strstr(dirent->name, "-client") != NULL)
+               if (server_only && strstr(dirent->mde_name, "-client") != NULL)
                        goto next;
 
-               if (strncmp(fsname, dirent->name, len) == 0) {
-                       CDEBUG(D_MGS, "Changing log %s\n", dirent->name);
-                        /* Erase any old settings of this same parameter */
-                       rc = mgs_modify(env, mgs, fsdb, mti, dirent->name,
-                                       devname, comment, CM_SKIP);
-                       if (rc < 0)
-                               CERROR("%s: Can't modify llog %s: rc = %d\n",
-                                      mgs->mgs_obd->obd_name, dirent->name,rc);
-                        /* Write the new one */
-                        if (lcfg) {
-                               rc = mgs_write_log_direct(env, mgs, fsdb,
-                                                         dirent->name,
-                                                         lcfg, devname,
-                                                         comment);
-                                if (rc)
-                                       CERROR("%s: writing log %s: rc = %d\n",
-                                              mgs->mgs_obd->obd_name,
-                                              dirent->name, rc);
-                        }
-                }
+               if (strlen(dirent->mde_name) <= len ||
+                   strncmp(fsname, dirent->mde_name, len) != 0 ||
+                   dirent->mde_name[len] != '-')
+                       goto next;
+
+               CDEBUG(D_MGS, "Changing log %s\n", dirent->mde_name);
+               /* Erase any old settings of this same parameter */
+               rc = mgs_modify(env, mgs, fsdb, mti, dirent->mde_name,
+                               devname, comment, CM_SKIP);
+               if (rc < 0)
+                       CERROR("%s: Can't modify llog %s: rc = %d\n",
+                              mgs->mgs_obd->obd_name, dirent->mde_name, rc);
+               if (lcr == NULL)
+                       goto next;
+               /* Write the new one */
+               rc = mgs_write_log_direct(env, mgs, fsdb, dirent->mde_name,
+                                         lcr, devname, comment);
+               if (rc != 0)
+                       CERROR("%s: writing log %s: rc = %d\n",
+                              mgs->mgs_obd->obd_name, dirent->mde_name, rc);
 next:
                mgs_direntry_free(dirent);
-        }
+       }
 
-        RETURN(rc);
+       RETURN(rc);
 }
 
-static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
+static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
                                    struct mgs_device *mgs,
                                    struct fs_db *fsdb,
                                    struct mgs_target_info *mti,
-                                   char *logname);
+                                   int index, char *logname);
 static int mgs_write_log_osc_to_lov(const struct lu_env *env,
                                    struct mgs_device *mgs,
                                    struct fs_db *fsdb,
                                     struct mgs_target_info *mti,
-                                    char *logname, char *suffix, char *lovname,
+                                   char *logname, char *suffix, char *lovname,
                                     enum lustre_sec_part sec_part, int flags);
 static int name_create_mdt_and_lov(char **logname, char **lovname,
                                   struct fs_db *fsdb, int i);
 
-static int mgs_steal_llog_handler(const struct lu_env *env,
-                                 struct llog_handle *llh,
-                                 struct llog_rec_hdr *rec, void *data)
+static int add_param(char *params, char *key, char *val)
+{
+       char *start = params + strlen(params);
+       char *end = params + sizeof(((struct mgs_target_info *)0)->mti_params);
+       int keylen = 0;
+
+       if (key != NULL)
+               keylen = strlen(key);
+       if (start + 1 + keylen + strlen(val) >= end) {
+               CERROR("params are too long: %s %s%s\n",
+                      params, key != NULL ? key : "", val);
+               return -EINVAL;
+       }
+
+       sprintf(start, " %s%s", key != NULL ? key : "", val);
+       return 0;
+}
+
+/**
+ * Walk through client config log record and convert the related records
+ * into the target.
+ **/
+static int mgs_steal_client_llog_handler(const struct lu_env *env,
+                                        struct llog_handle *llh,
+                                        struct llog_rec_hdr *rec, void *data)
 {
        struct mgs_device *mgs;
+       struct obd_device *obd;
         struct mgs_target_info *mti, *tmti;
         struct fs_db *fsdb;
         int cfg_len = rec->lrh_len;
@@ -1133,13 +1553,16 @@ static int mgs_steal_llog_handler(const struct lu_env *env,
            2: found mdc;
         */
         static int last_step = -1;
+       int cplen = 0;
 
         ENTRY;
 
         mti = ((struct temp_comp*)data)->comp_mti;
         tmti = ((struct temp_comp*)data)->comp_tmti;
         fsdb = ((struct temp_comp*)data)->comp_fsdb;
-       mgs = ((struct temp_comp*)data)->comp_mgs;
+       obd = ((struct temp_comp *)data)->comp_obd;
+       mgs = lu2mgs_dev(obd->obd_lu_dev);
+       LASSERT(mgs);
 
         if (rec->lrh_type != OBD_CFG_REC) {
                 CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
@@ -1154,68 +1577,84 @@ static int mgs_steal_llog_handler(const struct lu_env *env,
 
         lcfg = (struct lustre_cfg *)cfg_buf;
 
-        if (lcfg->lcfg_command == LCFG_MARKER) {
-                struct cfg_marker *marker;
-                marker = lustre_cfg_buf(lcfg, 1);
-                if (!strncmp(marker->cm_comment,"add osc",7) &&
-                    (marker->cm_flags & CM_START)){
-                        got_an_osc_or_mdc = 1;
-                        strncpy(tmti->mti_svname, marker->cm_tgtname,
-                                sizeof(tmti->mti_svname));
+       if (lcfg->lcfg_command == LCFG_MARKER) {
+               struct cfg_marker *marker;
+               marker = lustre_cfg_buf(lcfg, 1);
+               if (!strncmp(marker->cm_comment, "add osc", 7) &&
+                   (marker->cm_flags & CM_START) &&
+                    !(marker->cm_flags & CM_SKIP)) {
+                       got_an_osc_or_mdc = 1;
+                       cplen = strlcpy(tmti->mti_svname, marker->cm_tgtname,
+                                       sizeof(tmti->mti_svname));
+                       if (cplen >= sizeof(tmti->mti_svname))
+                               RETURN(-E2BIG);
                        rc = record_start_log(env, mgs, &mdt_llh,
                                              mti->mti_svname);
                        if (rc)
                                RETURN(rc);
                        rc = record_marker(env, mdt_llh, fsdb, CM_START,
-                                           mti->mti_svname,"add osc(copied)");
+                                          mti->mti_svname, "add osc(copied)");
                        record_end_log(env, &mdt_llh);
-                        last_step = marker->cm_step;
-                        RETURN(rc);
-                }
-                if (!strncmp(marker->cm_comment,"add osc",7) &&
-                    (marker->cm_flags & CM_END)){
-                        LASSERT(last_step == marker->cm_step);
-                        last_step = -1;
-                        got_an_osc_or_mdc = 0;
+                       last_step = marker->cm_step;
+                       RETURN(rc);
+               }
+               if (!strncmp(marker->cm_comment, "add osc", 7) &&
+                   (marker->cm_flags & CM_END) &&
+                    !(marker->cm_flags & CM_SKIP)) {
+                       LASSERT(last_step == marker->cm_step);
+                       last_step = -1;
+                       got_an_osc_or_mdc = 0;
+                       memset(tmti, 0, sizeof(*tmti));
                        rc = record_start_log(env, mgs, &mdt_llh,
                                              mti->mti_svname);
                        if (rc)
                                RETURN(rc);
                        rc = record_marker(env, mdt_llh, fsdb, CM_END,
-                                           mti->mti_svname,"add osc(copied)");
+                                          mti->mti_svname, "add osc(copied)");
                        record_end_log(env, &mdt_llh);
-                        RETURN(rc);
-                }
-                if (!strncmp(marker->cm_comment,"add mdc",7) &&
-                    (marker->cm_flags & CM_START)){
-                        got_an_osc_or_mdc = 2;
-                        last_step = marker->cm_step;
-                        memcpy(tmti->mti_svname, marker->cm_tgtname,
-                               strlen(marker->cm_tgtname));
-
-                        RETURN(rc);
-                }
-                if (!strncmp(marker->cm_comment,"add mdc",7) &&
-                    (marker->cm_flags & CM_END)){
-                        LASSERT(last_step == marker->cm_step);
-                        last_step = -1;
-                        got_an_osc_or_mdc = 0;
-                        RETURN(rc);
-                }
-        }
+                       RETURN(rc);
+               }
+               if (!strncmp(marker->cm_comment, "add mdc", 7) &&
+                   (marker->cm_flags & CM_START) &&
+                    !(marker->cm_flags & CM_SKIP)) {
+                       got_an_osc_or_mdc = 2;
+                       last_step = marker->cm_step;
+                       memcpy(tmti->mti_svname, marker->cm_tgtname,
+                              strlen(marker->cm_tgtname));
+
+                       RETURN(rc);
+               }
+               if (!strncmp(marker->cm_comment, "add mdc", 7) &&
+                   (marker->cm_flags & CM_END) &&
+                    !(marker->cm_flags & CM_SKIP)) {
+                       LASSERT(last_step == marker->cm_step);
+                       last_step = -1;
+                       got_an_osc_or_mdc = 0;
+                       memset(tmti, 0, sizeof(*tmti));
+                       RETURN(rc);
+               }
+       }
 
         if (got_an_osc_or_mdc == 0 || last_step < 0)
                 RETURN(rc);
 
-        if (lcfg->lcfg_command == LCFG_ADD_UUID) {
-                uint64_t nodenid;
-                nodenid = lcfg->lcfg_nid;
+       if (lcfg->lcfg_command == LCFG_ADD_UUID) {
+               uint64_t nodenid = lcfg->lcfg_nid;
 
-                tmti->mti_nids[tmti->mti_nid_count] = nodenid;
-                tmti->mti_nid_count++;
+               if (strlen(tmti->mti_uuid) == 0) {
+                       /* target uuid not set, this config record is before
+                        * LCFG_SETUP, this nid is one of target node nid.
+                        */
+                       tmti->mti_nids[tmti->mti_nid_count] = nodenid;
+                       tmti->mti_nid_count++;
+               } else {
+                       /* failover node nid */
+                       rc = add_param(tmti->mti_params, PARAM_FAILNODE,
+                                      libcfs_nid2str(nodenid));
+               }
 
-                RETURN(rc);
-        }
+               RETURN(rc);
+       }
 
         if (lcfg->lcfg_command == LCFG_SETUP) {
                 char *target;
@@ -1239,7 +1678,8 @@ static int mgs_steal_llog_handler(const struct lu_env *env,
                        strlen(mti->mti_fsname));
                 tmti->mti_stripe_index = index;
 
-               rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, tmti,
+               rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, tmti,
+                                             mti->mti_stripe_index,
                                              mti->mti_svname);
                 memset(tmti, 0, sizeof(*tmti));
                 RETURN(rc);
@@ -1281,7 +1721,6 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
                                               struct temp_comp* comp)
 {
         struct llog_handle *loghandle;
-        struct lvfs_run_ctxt saved;
         struct mgs_target_info *tmti;
         struct llog_ctxt *ctxt;
        int rc;
@@ -1296,11 +1735,9 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
                GOTO(out_ctxt, rc = -ENOMEM);
 
        comp->comp_tmti = tmti;
-       comp->comp_mgs = mgs;
-
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
+       comp->comp_obd = mgs->mgs_obd;
 
-       rc = llog_open(NULL, ctxt, &loghandle, NULL, client_name,
+       rc = llog_open(env, ctxt, &loghandle, NULL, client_name,
                       LLOG_OPEN_EXISTS);
        if (rc < 0) {
                if (rc == -ENOENT)
@@ -1308,17 +1745,16 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
                GOTO(out_pop, rc);
        }
 
-       rc = llog_init_handle(NULL, loghandle, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(env, loghandle, LLOG_F_IS_PLAIN, NULL);
        if (rc)
                GOTO(out_close, rc);
 
-       rc = llog_process_or_fork(env, loghandle, mgs_steal_llog_handler,
+       rc = llog_process_or_fork(env, loghandle, mgs_steal_client_llog_handler,
                                  (void *)comp, NULL, false);
        CDEBUG(D_MGS, "steal llog re = %d\n", rc);
 out_close:
-       llog_close(NULL, loghandle);
+       llog_close(env, loghandle);
 out_pop:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
        OBD_FREE_PTR(tmti);
 out_ctxt:
        llog_ctxt_put(ctxt);
@@ -1399,9 +1835,9 @@ static int mgs_write_log_lov(const struct lu_env *env, struct mgs_device *mgs,
         /* Defaults.  Can be changed later by lcfg config_param */
         lovdesc->ld_default_stripe_count = 1;
         lovdesc->ld_pattern = LOV_PATTERN_RAID0;
-        lovdesc->ld_default_stripe_size = 1024 * 1024;
+       lovdesc->ld_default_stripe_size = LOV_DESC_STRIPE_SIZE_DEFAULT;
         lovdesc->ld_default_stripe_offset = -1;
-        lovdesc->ld_qos_maxage = QOS_DEFAULT_MAXAGE;
+       lovdesc->ld_qos_maxage = LOV_DESC_QOS_MAXAGE_DEFAULT;
         sprintf((char*)lovdesc->ld_uuid.uuid, "%s_UUID", lovname);
         /* can these be the same? */
         uuid = (char *)lovdesc->ld_uuid.uuid;
@@ -1452,7 +1888,12 @@ static int mgs_write_log_failnids(const struct lu_env *env,
         #07 L add_conn 0:OSC_uml1_ost1_mdsA  1:uml2_UUID
         */
 
-        /* Pull failnid info out of params string */
+       /*
+        * Pull failnid info out of params string, which may contain something
+        * like "<nid1>,<nid2>:<nid3>,<nid4>".  class_parse_nid() does not
+        * complain about abnormal inputs like ",:<nid1>", "<nid1>:,<nid2>",
+        * etc.  However, convert_hostnames() should have caught those.
+        */
         while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
                 while (class_parse_nid(ptr, &nid, &ptr) == 0) {
                         if (failnodeuuid == NULL) {
@@ -1467,13 +1908,25 @@ static int mgs_write_log_failnids(const struct lu_env *env,
                                "client %s\n", libcfs_nid2str(nid),
                                failnodeuuid, cliname);
                        rc = record_add_uuid(env, llh, nid, failnodeuuid);
-                }
-               if (failnodeuuid)
+                       /*
+                        * If *ptr is ':', we have added all NIDs for
+                        * failnodeuuid.
+                        */
+                       if (*ptr == ':') {
+                               rc = record_add_conn(env, llh, cliname,
+                                                    failnodeuuid);
+                               name_destroy(&failnodeuuid);
+                               failnodeuuid = NULL;
+                       }
+               }
+               if (failnodeuuid) {
                        rc = record_add_conn(env, llh, cliname, failnodeuuid);
-        }
+                       name_destroy(&failnodeuuid);
+                       failnodeuuid = NULL;
+               }
+       }
 
-       name_destroy(&failnodeuuid);
-        return rc;
+       return rc;
 }
 
 static int mgs_write_log_mdc_to_lmv(const struct lu_env *env,
@@ -1556,83 +2009,158 @@ out_free:
         RETURN(rc);
 }
 
+static inline int name_create_lov(char **lovname, char *mdtname,
+                                 struct fs_db *fsdb, int index)
+{
+       /* COMPAT_180 */
+       if (index == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+               return name_create(lovname, fsdb->fsdb_name, "-mdtlov");
+       else
+               return name_create(lovname, mdtname, "-mdtlov");
+}
+
+static int name_create_mdt_and_lov(char **logname, char **lovname,
+                                  struct fs_db *fsdb, int i)
+{
+       int rc;
+
+       rc = name_create_mdt(logname, fsdb->fsdb_name, i);
+       if (rc)
+               return rc;
+       /* COMPAT_180 */
+       if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+               rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
+       else
+               rc = name_create(lovname, *logname, "-mdtlov");
+       if (rc) {
+               name_destroy(logname);
+               *logname = NULL;
+       }
+       return rc;
+}
+
+static inline int name_create_mdt_osc(char **oscname, char *ostname,
+                                     struct fs_db *fsdb, int i)
+{
+       char suffix[16];
+
+       if (i == 0 && test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+               sprintf(suffix, "-osc");
+       else
+               sprintf(suffix, "-osc-MDT%04x", i);
+       return name_create(oscname, ostname, suffix);
+}
+
 /* add new mdc to already existent MDS */
-static int mgs_write_log_mdc_to_mdt(const struct lu_env *env,
+static int mgs_write_log_osp_to_mdt(const struct lu_env *env,
                                    struct mgs_device *mgs,
                                    struct fs_db *fsdb,
                                    struct mgs_target_info *mti,
-                                   char *logname)
+                                   int mdt_index, char *logname)
 {
-        struct llog_handle *llh = NULL;
-       char *nodeuuid = NULL;
-       char *mdcname = NULL;
-       char *mdcuuid = NULL;
-       char *mdtuuid = NULL;
-        int idx = mti->mti_stripe_index;
-        char index[9];
-        int i, rc;
+       struct llog_handle      *llh = NULL;
+       char    *nodeuuid = NULL;
+       char    *ospname = NULL;
+       char    *lovuuid = NULL;
+       char    *mdtuuid = NULL;
+       char    *svname = NULL;
+       char    *mdtname = NULL;
+       char    *lovname = NULL;
+       char    index_str[16];
+       int     i, rc;
 
-        ENTRY;
-       if (mgs_log_is_empty(env, mgs, logname)) {
+       ENTRY;
+       if (mgs_log_is_empty(env, mgs, mti->mti_svname)) {
                 CERROR("log is empty! Logical error\n");
                 RETURN (-EINVAL);
         }
 
-        CDEBUG(D_MGS, "adding mdc index %d to %s\n", idx, logname);
+       CDEBUG(D_MGS, "adding osp index %d to %s\n", mti->mti_stripe_index,
+              logname);
 
-       rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
+       rc = name_create_mdt(&mdtname, fsdb->fsdb_name, mti->mti_stripe_index);
        if (rc)
                RETURN(rc);
-       snprintf(index, sizeof(index), "-mdc%04x", idx);
-       rc = name_create(&mdcname, logname, index);
+
+       rc = name_create(&nodeuuid, libcfs_nid2str(mti->mti_nids[0]), "");
        if (rc)
-               GOTO(out_free, rc);
-       rc = name_create(&mdcuuid, mdcname, "_UUID");
+               GOTO(out_destory, rc);
+
+       rc = name_create(&svname, mdtname, "-osp");
        if (rc)
-               GOTO(out_free, rc);
-       rc = name_create(&mdtuuid, logname, "_UUID");
+               GOTO(out_destory, rc);
+
+       sprintf(index_str, "-MDT%04x", mdt_index);
+       rc = name_create(&ospname, svname, index_str);
        if (rc)
-               GOTO(out_free, rc);
+               GOTO(out_destory, rc);
+
+       rc = name_create_lov(&lovname, logname, fsdb, mdt_index);
+       if (rc)
+               GOTO(out_destory, rc);
+
+       rc = name_create(&lovuuid, lovname, "_UUID");
+       if (rc)
+               GOTO(out_destory, rc);
+
+       rc = name_create(&mdtuuid, mdtname, "_UUID");
+       if (rc)
+               GOTO(out_destory, rc);
 
        rc = record_start_log(env, mgs, &llh, logname);
        if (rc)
-               GOTO(out_free, rc);
-       rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname, "add mdc");
+               GOTO(out_destory, rc);
+
+       rc = record_marker(env, llh, fsdb, CM_START, mti->mti_svname,
+                          "add osp");
        if (rc)
-               GOTO(out_end, rc);
-        for (i = 0; i < mti->mti_nid_count; i++) {
-                CDEBUG(D_MGS, "add nid %s for mdt\n",
-                       libcfs_nid2str(mti->mti_nids[i]));
+               GOTO(out_destory, rc);
+
+       for (i = 0; i < mti->mti_nid_count; i++) {
+               CDEBUG(D_MGS, "add nid %s for mdt\n",
+                      libcfs_nid2str(mti->mti_nids[i]));
                rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
                if (rc)
                        GOTO(out_end, rc);
         }
-       rc = record_attach(env, llh, mdcname, LUSTRE_MDC_NAME, mdcuuid);
+
+       rc = record_attach(env, llh, ospname, LUSTRE_OSP_NAME, lovuuid);
        if (rc)
                GOTO(out_end, rc);
-       rc = record_setup(env, llh, mdcname, mti->mti_uuid, nodeuuid, 0, 0);
+
+       rc = record_setup(env, llh, ospname, mti->mti_uuid, nodeuuid,
+                         NULL, NULL);
        if (rc)
                GOTO(out_end, rc);
-       rc = mgs_write_log_failnids(env, mti, llh, mdcname);
+
+       rc = mgs_write_log_failnids(env, mti, llh, ospname);
        if (rc)
                GOTO(out_end, rc);
-        snprintf(index, sizeof(index), "%d", idx);
 
-       rc = record_mdc_add(env, llh, logname, mdcuuid, mti->mti_uuid,
-                            index, "1");
+       /* Add mdc(osp) to lod */
+       snprintf(index_str, sizeof(mti->mti_stripe_index), "%d",
+                mti->mti_stripe_index);
+       rc = record_base(env, llh, lovname, 0, LCFG_ADD_MDC, mti->mti_uuid,
+                        index_str, "1", NULL);
        if (rc)
                GOTO(out_end, rc);
-       rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add mdc");
+
+       rc = record_marker(env, llh, fsdb, CM_END, mti->mti_svname, "add osp");
        if (rc)
                GOTO(out_end, rc);
+
 out_end:
        record_end_log(env, &llh);
-out_free:
+
+out_destory:
        name_destroy(&mdtuuid);
-        name_destroy(&mdcuuid);
-        name_destroy(&mdcname);
+       name_destroy(&lovuuid);
+       name_destroy(&lovname);
+       name_destroy(&ospname);
+       name_destroy(&svname);
         name_destroy(&nodeuuid);
-        RETURN(rc);
+       name_destroy(&mdtname);
+       RETURN(rc);
 }
 
 static int mgs_write_log_mdt0(const struct lu_env *env,
@@ -1699,46 +2227,6 @@ out_free:
         RETURN(rc);
 }
 
-static inline int name_create_mdt(char **logname, char *fsname, int i)
-{
-        char mdt_index[9];
-
-        sprintf(mdt_index, "-MDT%04x", i);
-       return name_create(logname, fsname, mdt_index);
-}
-
-static int name_create_mdt_and_lov(char **logname, char **lovname,
-                                    struct fs_db *fsdb, int i)
-{
-       int rc;
-
-       rc = name_create_mdt(logname, fsdb->fsdb_name, i);
-       if (rc)
-               return rc;
-        /* COMPAT_180 */
-        if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
-               rc = name_create(lovname, fsdb->fsdb_name, "-mdtlov");
-        else
-               rc = name_create(lovname, *logname, "-mdtlov");
-       if (rc) {
-               name_destroy(logname);
-               *logname = NULL;
-       }
-       return rc;
-}
-
-static inline int name_create_mdt_osc(char **oscname, char *ostname,
-                                       struct fs_db *fsdb, int i)
-{
-        char suffix[16];
-
-        if (i == 0 && cfs_test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
-                sprintf(suffix, "-osc");
-        else
-                sprintf(suffix, "-osc-MDT%04x", i);
-       return name_create(oscname, ostname, suffix);
-}
-
 /* envelope method for all layers log */
 static int mgs_write_log_mdt(const struct lu_env *env,
                             struct mgs_device *mgs,
@@ -1820,20 +2308,24 @@ static int mgs_write_log_mdt(const struct lu_env *env,
 
        if (rc)
                GOTO(out_end, rc);
+
        /* for_all_existing_mdt except current one */
-        for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
-                char *mdtname;
-                if (i !=  mti->mti_stripe_index &&
-                    cfs_test_bit(i,  fsdb->fsdb_mdt_index_map)) {
-                       rc = name_create_mdt(&mdtname, mti->mti_fsname, i);
+       for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
+               if (i !=  mti->mti_stripe_index &&
+                   test_bit(i, fsdb->fsdb_mdt_index_map)) {
+                       char *logname;
+
+                       rc = name_create_mdt(&logname, fsdb->fsdb_name, i);
                        if (rc)
                                GOTO(out_end, rc);
-                       rc = mgs_write_log_mdc_to_mdt(env, mgs, fsdb, mti, mdtname);
-                        name_destroy(&mdtname);
+
+                       rc = mgs_write_log_osp_to_mdt(env, mgs, fsdb, mti,
+                                                     i, logname);
+                       name_destroy(&logname);
                        if (rc)
                                GOTO(out_end, rc);
-                }
-        }
+               }
+       }
 out_end:
        record_end_log(env, &llh);
 out_free:
@@ -1872,9 +2364,16 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env,
        rc = name_create(&svname, mti->mti_svname, "-osc");
        if (rc)
                GOTO(out_free, rc);
-       rc = name_create(&oscname, svname, suffix);
+
+       /* for the system upgraded from old 1.8, keep using the old osc naming
+        * style for mdt, see name_create_mdt_osc(). LU-1257 */
+       if (test_bit(FSDB_OSCNAME18, &fsdb->fsdb_flags))
+               rc = name_create(&oscname, svname, "");
+       else
+               rc = name_create(&oscname, svname, suffix);
        if (rc)
                GOTO(out_free, rc);
+
        rc = name_create(&oscuuid, oscname, "_UUID");
        if (rc)
                GOTO(out_free, rc);
@@ -1882,6 +2381,7 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env,
        if (rc)
                GOTO(out_free, rc);
 
+
         /*
         #03 L add_uuid nid=uml1@tcp(0x20000c0a80201) 0:  1:uml1_UUID
         multihomed (#4)
@@ -1897,11 +2397,18 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env,
        rc = record_start_log(env, mgs, &llh, logname);
         if (rc)
                GOTO(out_free, rc);
+
         /* FIXME these should be a single journal transaction */
        rc = record_marker(env, llh, fsdb, CM_START | flags, mti->mti_svname,
                            "add osc");
        if (rc)
                GOTO(out_end, rc);
+
+       /* NB: don't change record order, because upon MDT steal OSC config
+        * from client, it treats all nids before LCFG_SETUP as target nids
+        * (multiple interfaces), while nids after as failover node nids.
+        * See mgs_steal_client_llog_handler() LCFG_ADD_UUID.
+        */
         for (i = 0; i < mti->mti_nid_count; i++) {
                 CDEBUG(D_MGS, "add nid %s\n", libcfs_nid2str(mti->mti_nids[i]));
                rc = record_add_uuid(env, llh, mti->mti_nids[i], nodeuuid);
@@ -1917,7 +2424,9 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env,
        rc = mgs_write_log_failnids(env, mti, llh, oscname);
        if (rc)
                GOTO(out_end, rc);
-        snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
+
+       snprintf(index, sizeof(index), "%d", mti->mti_stripe_index);
+
        rc = record_lov_add(env, llh, lovname, mti->mti_uuid, index, "1");
        if (rc)
                GOTO(out_end, rc);
@@ -1996,7 +2505,7 @@ out_end:
         /* We also have to update the other logs where this osc is part of
            the lov */
 
-        if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
+       if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
                 /* If we're upgrading, the old mdt log already has our
                    entry. Let's do a fake one for fun. */
                 /* Note that we can't add any new failnids, since we don't
@@ -2014,7 +2523,7 @@ out_end:
 
         /* Add ost to all MDT lov defs */
         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
-                if (cfs_test_bit(i, fsdb->fsdb_mdt_index_map)) {
+               if (test_bit(i, fsdb->fsdb_mdt_index_map)) {
                         char mdt_index[9];
 
                        rc = name_create_mdt_and_lov(&logname, &lovname, fsdb,
@@ -2152,7 +2661,7 @@ static int mgs_write_log_add_failnid(const struct lu_env *env,
                 int i;
 
                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
-                        if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
+                       if (!test_bit(i, fsdb->fsdb_mdt_index_map))
                                 continue;
                        rc = name_create_mdt(&logname, mti->mti_fsname, i);
                        if (rc)
@@ -2178,40 +2687,67 @@ static int mgs_write_log_add_failnid(const struct lu_env *env,
 
 static int mgs_wlp_lcfg(const struct lu_env *env,
                        struct mgs_device *mgs, struct fs_db *fsdb,
-                        struct mgs_target_info *mti,
-                        char *logname, struct lustre_cfg_bufs *bufs,
-                        char *tgtname, char *ptr)
+                       struct mgs_target_info *mti,
+                       char *logname, struct lustre_cfg_bufs *bufs,
+                       char *tgtname, char *ptr)
 {
-        char comment[MTI_NAME_MAXLEN];
-        char *tmp;
-        struct lustre_cfg *lcfg;
-        int rc, del;
-
-        /* Erase any old settings of this same parameter */
-        memcpy(comment, ptr, MTI_NAME_MAXLEN);
-        comment[MTI_NAME_MAXLEN - 1] = 0;
-        /* But don't try to match the value. */
-        if ((tmp = strchr(comment, '=')))
-            *tmp = 0;
-        /* FIXME we should skip settings that are the same as old values */
+       char comment[MTI_NAME_MAXLEN];
+       char *tmp;
+       struct llog_cfg_rec *lcr;
+       int rc, del;
+
+       /* Erase any old settings of this same parameter */
+       memcpy(comment, ptr, MTI_NAME_MAXLEN);
+       comment[MTI_NAME_MAXLEN - 1] = 0;
+       /* But don't try to match the value. */
+       tmp = strchr(comment, '=');
+       if (tmp != NULL)
+               *tmp = 0;
+       /* FIXME we should skip settings that are the same as old values */
        rc = mgs_modify(env, mgs, fsdb, mti, logname, tgtname, comment,CM_SKIP);
        if (rc < 0)
                return rc;
-        del = mgs_param_empty(ptr);
+       del = mgs_param_empty(ptr);
+
+       LCONSOLE_INFO("%s parameter %s.%s in log %s\n", del ? "Disabling" : rc ?
+                     "Setting" : "Modifying", tgtname, comment, logname);
+       if (del) {
+               /* mgs_modify() will return 1 if nothing had to be done */
+               if (rc == 1)
+                       rc = 0;
+               return rc;
+       }
 
-        LCONSOLE_INFO("%sing parameter %s.%s in log %s\n", del ? "Disabl" : rc ?
-                      "Sett" : "Modify", tgtname, comment, logname);
-        if (del)
-                return rc;
+       lustre_cfg_bufs_reset(bufs, tgtname);
+       lustre_cfg_bufs_set_string(bufs, 1, ptr);
+       if (mti->mti_flags & LDD_F_PARAM2)
+               lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
 
-        lustre_cfg_bufs_reset(bufs, tgtname);
-        lustre_cfg_bufs_set_string(bufs, 1, ptr);
-        lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
-        if (!lcfg)
-                return -ENOMEM;
-       rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
-        lustre_cfg_free(lcfg);
-        return rc;
+       lcr = lustre_cfg_rec_new((mti->mti_flags & LDD_F_PARAM2) ?
+                                LCFG_SET_PARAM : LCFG_PARAM, bufs);
+       if (lcr == NULL)
+               return -ENOMEM;
+
+       rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr, tgtname,
+                                 comment);
+       lustre_cfg_rec_free(lcr);
+       return rc;
+}
+
+static int mgs_write_log_param2(const struct lu_env *env,
+                               struct mgs_device *mgs,
+                               struct fs_db *fsdb,
+                               struct mgs_target_info *mti, char *ptr)
+{
+       struct lustre_cfg_bufs  bufs;
+       int                     rc = 0;
+       ENTRY;
+
+       CDEBUG(D_MGS, "next param '%s'\n", ptr);
+       rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, PARAMS_FILENAME, &bufs,
+                         mti->mti_svname, ptr);
+
+       RETURN(rc);
 }
 
 /* write global variable settings into log */
@@ -2219,8 +2755,9 @@ static int mgs_write_log_sys(const struct lu_env *env,
                             struct mgs_device *mgs, struct fs_db *fsdb,
                             struct mgs_target_info *mti, char *sys, char *ptr)
 {
-       struct mgs_thread_info *mgi = mgs_env_info(env);
-       struct lustre_cfg *lcfg;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct lustre_cfg       *lcfg;
+       struct llog_cfg_rec     *lcr;
        char *tmp, sep;
        int rc, cmd, convert = 1;
 
@@ -2251,7 +2788,11 @@ static int mgs_write_log_sys(const struct lu_env *env,
        lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, sys);
        if (!convert && *tmp != '\0')
                lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 2, tmp);
-       lcfg = lustre_cfg_new(cmd, &mgi->mgi_bufs);
+       lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+       if (lcr == NULL)
+               return -ENOMEM;
+
+       lcfg = &lcr->lcr_cfg;
        lcfg->lcfg_num = convert ? simple_strtoul(tmp, NULL, 0) : 0;
        /* truncate the comment to the parameter name */
        ptr = tmp - 1;
@@ -2259,7 +2800,7 @@ static int mgs_write_log_sys(const struct lu_env *env,
        *ptr = '\0';
        /* modify all servers and clients */
        rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
-                                     *tmp == '\0' ? NULL : lcfg,
+                                     *tmp == '\0' ? NULL : lcr,
                                      mti->mti_fsname, sys, 0);
        if (rc == 0 && *tmp != '\0') {
                switch (cmd) {
@@ -2276,7 +2817,7 @@ static int mgs_write_log_sys(const struct lu_env *env,
                }
        }
        *ptr = sep;
-       lustre_cfg_free(lcfg);
+       lustre_cfg_rec_free(lcr);
        return rc;
 }
 
@@ -2285,12 +2826,11 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
                               struct fs_db *fsdb, struct mgs_target_info *mti,
                               char *quota, char *ptr)
 {
-       struct lustre_cfg_bufs bufs;
-       struct lustre_cfg *lcfg;
-       char *tmp;
-       char sep;
-       int cmd = LCFG_PARAM;
-       int rc;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct llog_cfg_rec     *lcr;
+       char                    *tmp;
+       char                     sep;
+       int                      rc, cmd = LCFG_PARAM;
 
        /* support only 'meta' and 'data' pools so far */
        if (class_match_param(ptr, QUOTA_METAPOOL_NAME, &tmp) != 0 &&
@@ -2312,9 +2852,12 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
                }
        }
 
-       lustre_cfg_bufs_reset(&bufs, NULL);
-       lustre_cfg_bufs_set_string(&bufs, 1, quota);
-       lcfg = lustre_cfg_new(cmd, &bufs);
+       lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_fsname);
+       lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, quota);
+       lcr = lustre_cfg_rec_new(cmd, &mgi->mgi_bufs);
+       if (lcr == NULL)
+               return -ENOMEM;
+
        /* truncate the comment to the parameter name */
        ptr = tmp - 1;
        sep = *ptr;
@@ -2325,11 +2868,11 @@ static int mgs_write_log_quota(const struct lu_env *env, struct mgs_device *mgs,
         *     log once we cleanup the config log for global param. */
        /* modify all servers */
        rc = mgs_write_log_direct_all(env, mgs, fsdb, mti,
-                                     *tmp == '\0' ? NULL : lcfg,
+                                     *tmp == '\0' ? NULL : lcr,
                                      mti->mti_fsname, quota, 1);
        *ptr = sep;
-       lustre_cfg_free(lcfg);
-       return rc;
+       lustre_cfg_rec_free(lcr);
+       return rc < 0 ? rc : 0;
 }
 
 static int mgs_srpc_set_param_disk(const struct lu_env *env,
@@ -2338,61 +2881,63 @@ static int mgs_srpc_set_param_disk(const struct lu_env *env,
                                    struct mgs_target_info *mti,
                                    char *param)
 {
-       struct mgs_thread_info *mgi = mgs_env_info(env);
-        struct llog_handle     *llh = NULL;
-        char                   *logname;
-        char                   *comment, *ptr;
-        struct lustre_cfg      *lcfg;
-        int                     rc, len;
-        ENTRY;
+       struct mgs_thread_info  *mgi = mgs_env_info(env);
+       struct llog_cfg_rec     *lcr;
+       struct llog_handle      *llh = NULL;
+       char                    *logname;
+       char                    *comment, *ptr;
+       int                      rc, len;
 
-        /* get comment */
-        ptr = strchr(param, '=');
-        LASSERT(ptr);
-        len = ptr - param;
+       ENTRY;
 
-        OBD_ALLOC(comment, len + 1);
-        if (comment == NULL)
-                RETURN(-ENOMEM);
-        strncpy(comment, param, len);
-        comment[len] = '\0';
+       /* get comment */
+       ptr = strchr(param, '=');
+       LASSERT(ptr != NULL);
+       len = ptr - param;
+
+       OBD_ALLOC(comment, len + 1);
+       if (comment == NULL)
+               RETURN(-ENOMEM);
+       strncpy(comment, param, len);
+       comment[len] = '\0';
 
-        /* prepare lcfg */
+       /* prepare lcfg */
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, mti->mti_svname);
        lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, param);
-       lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
-        if (lcfg == NULL)
-                GOTO(out_comment, rc = -ENOMEM);
+       lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &mgi->mgi_bufs);
+       if (lcr == NULL)
+               GOTO(out_comment, rc = -ENOMEM);
 
-        /* construct log name */
-        rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
-        if (rc)
-                GOTO(out_lcfg, rc);
+       /* construct log name */
+       rc = name_create(&logname, mti->mti_fsname, "-sptlrpc");
+       if (rc < 0)
+               GOTO(out_lcfg, rc);
 
        if (mgs_log_is_empty(env, mgs, logname)) {
                rc = record_start_log(env, mgs, &llh, logname);
-                if (rc)
-                        GOTO(out, rc);
+               if (rc < 0)
+                       GOTO(out, rc);
                record_end_log(env, &llh);
-        }
+       }
 
-        /* obsolete old one */
+       /* obsolete old one */
        rc = mgs_modify(env, mgs, fsdb, mti, logname, mti->mti_svname,
                        comment, CM_SKIP);
        if (rc < 0)
                GOTO(out, rc);
-        /* write the new one */
-       rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcfg,
-                                  mti->mti_svname, comment);
+       /* write the new one */
+       rc = mgs_write_log_direct(env, mgs, fsdb, logname, lcr,
+                                 mti->mti_svname, comment);
        if (rc)
-               CERROR("err %d writing log %s\n", rc, logname);
+               CERROR("%s: error writing log %s: rc = %d\n",
+                      mgs->mgs_obd->obd_name, logname, rc);
 out:
-        name_destroy(&logname);
+       name_destroy(&logname);
 out_lcfg:
-        lustre_cfg_free(lcfg);
+       lustre_cfg_rec_free(lcr);
 out_comment:
-        OBD_FREE(comment, len + 1);
-        RETURN(rc);
+       OBD_FREE(comment, len + 1);
+       RETURN(rc);
 }
 
 static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
@@ -2414,10 +2959,10 @@ static int mgs_srpc_set_param_udesc_mem(struct fs_db *fsdb,
                 goto error_out;
 
         if (strcmp(ptr, "yes") == 0) {
-                cfs_set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
+               set_bit(FSDB_UDESC, &fsdb->fsdb_flags);
                 CWARN("Enable user descriptor shipping from client to MDT\n");
         } else if (strcmp(ptr, "no") == 0) {
-                cfs_clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
+               clear_bit(FSDB_UDESC, &fsdb->fsdb_flags);
                 CWARN("Disable user descriptor shipping from client to MDT\n");
         } else {
                 *(ptr - 1) = '=';
@@ -2461,7 +3006,7 @@ static int mgs_srpc_set_param_mem(struct fs_db *fsdb,
                 RETURN(rc);
 
         /* mgs rules implies must be mgc->mgs */
-        if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
+       if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
                 if ((rule.sr_from != LUSTRE_SP_MGC &&
                      rule.sr_from != LUSTRE_SP_ANY) ||
                     (rule.sr_to != LUSTRE_SP_MGS &&
@@ -2545,7 +3090,7 @@ static int mgs_srpc_set_param(const struct lu_env *env,
         if (rc)
                 goto out_free;
 
-        if (cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
+       if (test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags)) {
                 /*
                  * for mgs rules, make them effective immediately.
                  */
@@ -2570,7 +3115,7 @@ static int mgs_srpc_read_handler(const struct lu_env *env,
 {
        struct mgs_srpc_read_data *msrd = data;
         struct cfg_marker         *marker;
-        struct lustre_cfg         *lcfg = (struct lustre_cfg *)(rec + 1);
+       struct lustre_cfg         *lcfg = REC_DATA(rec);
         char                      *svname, *param;
         int                        cfg_len, rc;
         ENTRY;
@@ -2580,8 +3125,7 @@ static int mgs_srpc_read_handler(const struct lu_env *env,
                 RETURN(-EINVAL);
         }
 
-        cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
-                  sizeof(struct llog_rec_tail);
+       cfg_len = REC_DATA_LEN(rec);
 
         rc = lustre_cfg_sanity_check(lcfg, cfg_len);
         if (rc) {
@@ -2633,7 +3177,6 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
                                 struct fs_db *fsdb)
 {
         struct llog_handle        *llh = NULL;
-        struct lvfs_run_ctxt       saved;
         struct llog_ctxt          *ctxt;
         char                      *logname;
         struct mgs_srpc_read_data  msrd;
@@ -2651,17 +3194,15 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
        if (mgs_log_is_empty(env, mgs, logname))
                 GOTO(out, rc = 0);
 
-       push_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
-
-       rc = llog_open(NULL, ctxt, &llh, NULL, logname,
+       rc = llog_open(env, ctxt, &llh, NULL, logname,
                       LLOG_OPEN_EXISTS);
        if (rc < 0) {
                if (rc == -ENOENT)
                        rc = 0;
-               GOTO(out_pop, rc);
+               GOTO(out, rc);
        }
 
-       rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
+       rc = llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
         if (rc)
                 GOTO(out_close, rc);
 
@@ -2671,13 +3212,11 @@ int mgs_get_fsdb_srpc_from_llog(const struct lu_env *env,
         msrd.msrd_fsdb = fsdb;
         msrd.msrd_skip = 0;
 
-       rc = llog_process_or_fork(env, llh, mgs_srpc_read_handler,
-                                 (void *)&msrd, NULL, false);
+       rc = llog_process(env, llh, mgs_srpc_read_handler, (void *)&msrd,
+                         NULL);
 
 out_close:
-       llog_close(NULL, llh);
-out_pop:
-       pop_ctxt(&saved, &mgs->mgs_obd->obd_lvfs_ctxt, NULL);
+       llog_close(env, llh);
 out:
         llog_ctxt_put(ctxt);
         name_destroy(&logname);
@@ -2780,7 +3319,7 @@ static int mgs_write_log_param(const struct lu_env *env,
                 /* Modify mdtlov */
                 /* Add to all MDT logs for CMD */
                 for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
-                        if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
+                       if (!test_bit(i, fsdb->fsdb_mdt_index_map))
                                 continue;
                        rc = name_create_mdt(&logname, mti->mti_fsname, i);
                        if (rc)
@@ -2798,7 +3337,7 @@ static int mgs_write_log_param(const struct lu_env *env,
                                            "changes were made to the "
                                            "config log.\n",
                                            mti->mti_svname, rc);
-                        if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
+                       if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags))
                                 LCONSOLE_ERROR_MSG(0x146, "This may be"
                                                    " because the log"
                                                    "is in the old 1.4"
@@ -2856,7 +3395,7 @@ static int mgs_write_log_param(const struct lu_env *env,
             (class_match_param(ptr, PARAM_LLITE, NULL) == 0)) {
                 char *cname;
 
-               if (cfs_test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
+               if (test_bit(FSDB_OLDLOG14, &fsdb->fsdb_flags)) {
                        LCONSOLE_ERROR_MSG(0x148, "Upgraded client logs for %s"
                                           " cannot be modified. Consider"
                                           " updating the configuration with"
@@ -2878,9 +3417,22 @@ static int mgs_write_log_param(const struct lu_env *env,
                if (rc)
                        GOTO(end, rc);
 
-                CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+               /* Forbid direct update of llite root squash parameters.
+                * These parameters are indirectly set via the MDT settings.
+                * See (LU-1778) */
+               if ((class_match_param(ptr, PARAM_LLITE, &tmp) == 0) &&
+                   ((memcmp(tmp, "root_squash=", 12) == 0) ||
+                    (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
+                       LCONSOLE_ERROR("%s: root squash parameters can only "
+                               "be updated through MDT component\n",
+                               mti->mti_fsname);
+                       name_destroy(&cname);
+                       GOTO(end, rc = -EINVAL);
+               }
+
+               CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
 
-                /* Modify client */
+               /* Modify client */
                rc = name_create(&logname, mti->mti_fsname, "-client");
                if (rc) {
                        name_destroy(&cname);
@@ -2894,7 +3446,7 @@ static int mgs_write_log_param(const struct lu_env *env,
                         int i;
 
                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++){
-                                if (!cfs_test_bit(i, fsdb->fsdb_mdt_index_map))
+                               if (!test_bit(i, fsdb->fsdb_mdt_index_map))
                                         continue;
                                 name_destroy(&cname);
                                rc = name_create_mdt_osc(&cname, mti->mti_svname,
@@ -2916,13 +3468,13 @@ static int mgs_write_log_param(const struct lu_env *env,
                                }
                        }
                }
-                name_destroy(&logname);
-                name_destroy(&cname);
-                GOTO(end, rc);
-        }
+               name_destroy(&logname);
+               name_destroy(&cname);
+               GOTO(end, rc);
+       }
 
-        /* All mdt. params in proc */
-        if (class_match_param(ptr, PARAM_MDT, NULL) == 0) {
+       /* All mdt. params in proc */
+       if (class_match_param(ptr, PARAM_MDT, &tmp) == 0) {
                 int i;
                 __u32 idx;
 
@@ -2939,7 +3491,7 @@ static int mgs_write_log_param(const struct lu_env *env,
                         goto active_err;
                 if (rc & LDD_F_SV_ALL) {
                         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
-                                if (!cfs_test_bit(i,
+                               if (!test_bit(i,
                                                   fsdb->fsdb_mdt_index_map))
                                         continue;
                                rc = name_create_mdt(&logname,
@@ -2948,32 +3500,69 @@ static int mgs_write_log_param(const struct lu_env *env,
                                        goto active_err;
                                rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
                                                  logname, &mgi->mgi_bufs,
-                                                  logname, ptr);
-                                name_destroy(&logname);
-                                if (rc)
-                                        goto active_err;
-                        }
-                } else {
+                                                 logname, ptr);
+                               name_destroy(&logname);
+                               if (rc)
+                                       goto active_err;
+                       }
+               } else {
+                       if ((memcmp(tmp, "root_squash=", 12) == 0) ||
+                           (memcmp(tmp, "nosquash_nids=", 14) == 0)) {
+                               LCONSOLE_ERROR("%s: root squash parameters "
+                                       "cannot be applied to a single MDT\n",
+                                       mti->mti_fsname);
+                               GOTO(end, rc = -EINVAL);
+                       }
                        rc = mgs_wlp_lcfg(env, mgs, fsdb, mti,
                                          mti->mti_svname, &mgi->mgi_bufs,
-                                          mti->mti_svname, ptr);
-                        if (rc)
-                                goto active_err;
-                }
-                GOTO(end, rc);
-        }
+                                         mti->mti_svname, ptr);
+                       if (rc)
+                               goto active_err;
+               }
 
-        /* All mdd., ost. params in proc */
-        if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
-            (class_match_param(ptr, PARAM_OST, NULL) == 0)) {
-                CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
+               /* root squash settings are also applied to llite
+                * config log (see LU-1778) */
+               if (rc == 0 &&
+                   ((memcmp(tmp, "root_squash=", 12) == 0) ||
+                    (memcmp(tmp, "nosquash_nids=", 14) == 0))) {
+                       char *cname;
+                       char *ptr2;
+
+                       rc = name_create(&cname, mti->mti_fsname, "-client");
+                       if (rc)
+                               GOTO(end, rc);
+                       rc = name_create(&logname, mti->mti_fsname, "-client");
+                       if (rc) {
+                               name_destroy(&cname);
+                               GOTO(end, rc);
+                       }
+                       rc = name_create(&ptr2, PARAM_LLITE, tmp);
+                       if (rc) {
+                               name_destroy(&cname);
+                               name_destroy(&logname);
+                               GOTO(end, rc);
+                       }
+                       rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, logname,
+                                         &mgi->mgi_bufs, cname, ptr2);
+                       name_destroy(&ptr2);
+                       name_destroy(&logname);
+                       name_destroy(&cname);
+               }
+               GOTO(end, rc);
+       }
+
+       /* All mdd., ost. and osd. params in proc */
+       if ((class_match_param(ptr, PARAM_MDD, NULL) == 0) ||
+           (class_match_param(ptr, PARAM_OST, NULL) == 0) ||
+           (class_match_param(ptr, PARAM_OSD, NULL) == 0)) {
+               CDEBUG(D_MGS, "%.3s param %s\n", ptr, ptr + 4);
                if (mgs_log_is_empty(env, mgs, mti->mti_svname))
-                        GOTO(end, rc = -ENODEV);
+                       GOTO(end, rc = -ENODEV);
 
                rc = mgs_wlp_lcfg(env, mgs, fsdb, mti, mti->mti_svname,
                                  &mgi->mgi_bufs, mti->mti_svname, ptr);
-                GOTO(end, rc);
-        }
+               GOTO(end, rc);
+       }
 
         LCONSOLE_WARN("Ignoring unrecognized param '%s'\n", ptr);
         rc2 = -ENOSYS;
@@ -3008,30 +3597,29 @@ int mgs_check_failnid(const struct lu_env *env, struct mgs_device *mgs,
            the failover list.  Modify mti->params for rewriting back at
            server_register_target(). */
 
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
+       mutex_lock(&fsdb->fsdb_mutex);
         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
+       mutex_unlock(&fsdb->fsdb_mutex);
+       char    *buf, *params;
+       int      rc = -EINVAL;
 
         RETURN(rc);
 #endif
         return 0;
 }
 
-int mgs_write_log_target(const struct lu_env *env,
-                        struct mgs_device *mgs,
-                         struct mgs_target_info *mti,
-                         struct fs_db *fsdb)
+int mgs_write_log_target(const struct lu_env *env, struct mgs_device *mgs,
+                        struct mgs_target_info *mti, struct fs_db *fsdb)
 {
-        int rc = -EINVAL;
-        char *buf, *params;
-        ENTRY;
+       char    *buf, *params;
+       int      rc = -EINVAL;
+
+       ENTRY;
 
-        /* set/check the new target index */
+       /* set/check the new target index */
        rc = mgs_set_index(env, mgs, mti);
-        if (rc < 0) {
-                CERROR("Can't get index (%d)\n", rc);
-                RETURN(rc);
-        }
+       if (rc < 0)
+               RETURN(rc);
 
        if (rc == EALREADY) {
                LCONSOLE_WARN("Found index %d for %s, updating log\n",
@@ -3042,9 +3630,10 @@ int mgs_write_log_target(const struct lu_env *env,
                   get repeat setup instructions for already running
                   osc's. So don't update the client/mdt logs. */
                mti->mti_flags &= ~LDD_F_UPDATE;
+               rc = 0;
        }
 
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
+       mutex_lock(&fsdb->fsdb_mutex);
 
         if (mti->mti_flags &
             (LDD_F_VIRGIN | LDD_F_UPGRADE14 | LDD_F_WRITECONF)) {
@@ -3093,35 +3682,31 @@ int mgs_write_log_target(const struct lu_env *env,
         OBD_FREE(buf, strlen(mti->mti_params) + 1);
 
 out_up:
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
+       mutex_unlock(&fsdb->fsdb_mutex);
         RETURN(rc);
 }
 
 int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
 {
-       struct lvfs_run_ctxt     saved;
        struct llog_ctxt        *ctxt;
        int                      rc = 0;
-       struct obd_device *obd = mgs->mgs_obd;
 
-       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
+       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
        if (ctxt == NULL) {
                CERROR("%s: MGS config context doesn't exist\n",
-                      obd->obd_name);
+                      mgs->mgs_obd->obd_name);
                rc = -ENODEV;
        } else {
-               push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-               rc = llog_erase(NULL, ctxt, NULL, name);
+               rc = llog_erase(env, ctxt, NULL, name);
                /* llog may not exist */
                if (rc == -ENOENT)
                        rc = 0;
-               pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
                llog_ctxt_put(ctxt);
        }
 
        if (rc)
-               CERROR("%s: failed to clear log %s: %d\n", obd->obd_name,
-                      name, rc);
+               CERROR("%s: failed to clear log %s: %d\n",
+                      mgs->mgs_obd->obd_name, name, rc);
 
        return rc;
 }
@@ -3130,35 +3715,35 @@ int mgs_erase_log(const struct lu_env *env, struct mgs_device *mgs, char *name)
 int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsname)
 {
        struct fs_db *fsdb;
-       cfs_list_t list;
+       struct list_head log_list;
        struct mgs_direntry *dirent, *n;
        int rc, len = strlen(fsname);
        char *suffix;
        ENTRY;
 
        /* Find all the logs in the CONFIGS directory */
-       rc = class_dentry_readdir(env, mgs, &list);
+       rc = class_dentry_readdir(env, mgs, &log_list);
        if (rc)
                RETURN(rc);
 
-        cfs_mutex_lock(&mgs->mgs_mutex);
+       mutex_lock(&mgs->mgs_mutex);
 
         /* Delete the fs db */
        fsdb = mgs_find_fsdb(mgs, fsname);
         if (fsdb)
                mgs_free_fsdb(mgs, fsdb);
 
-        cfs_mutex_unlock(&mgs->mgs_mutex);
+       mutex_unlock(&mgs->mgs_mutex);
 
-       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
-               cfs_list_del(&dirent->list);
-               suffix = strrchr(dirent->name, '-');
+       list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+               list_del_init(&dirent->mde_list);
+               suffix = strrchr(dirent->mde_name, '-');
                if (suffix != NULL) {
-                       if ((len == suffix - dirent->name) &&
-                           (strncmp(fsname, dirent->name, len) == 0)) {
+                       if ((len == suffix - dirent->mde_name) &&
+                           (strncmp(fsname, dirent->mde_name, len) == 0)) {
                                CDEBUG(D_MGS, "Removing log %s\n",
-                                      dirent->name);
-                               mgs_erase_log(env, mgs, dirent->name);
+                                      dirent->mde_name);
+                               mgs_erase_log(env, mgs, dirent->mde_name);
                        }
                }
                mgs_direntry_free(dirent);
@@ -3167,6 +3752,40 @@ int mgs_erase_logs(const struct lu_env *env, struct mgs_device *mgs, char *fsnam
         RETURN(rc);
 }
 
+/* list all logs for the given fs */
+int mgs_list_logs(const struct lu_env *env, struct mgs_device *mgs,
+                 struct obd_ioctl_data *data)
+{
+       struct list_head         log_list;
+       struct mgs_direntry     *dirent, *n;
+       char                    *out, *suffix;
+       int                      l, remains, rc;
+
+       ENTRY;
+
+       /* Find all the logs in the CONFIGS directory */
+       rc = class_dentry_readdir(env, mgs, &log_list);
+       if (rc)
+               RETURN(rc);
+
+       out = data->ioc_bulk;
+       remains = data->ioc_inllen1;
+       list_for_each_entry_safe(dirent, n, &log_list, mde_list) {
+               list_del_init(&dirent->mde_list);
+               suffix = strrchr(dirent->mde_name, '-');
+               if (suffix != NULL) {
+                       l = snprintf(out, remains, "config log: $%s\n",
+                                    dirent->mde_name);
+                       out += l;
+                       remains -= l;
+               }
+               mgs_direntry_free(dirent);
+               if (remains <= 0)
+                       break;
+       }
+       RETURN(rc);
+}
+
 /* from llog_swab */
 static void print_lustre_cfg(struct lustre_cfg *lcfg)
 {
@@ -3191,6 +3810,34 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg)
         EXIT;
 }
 
+/* Setup params fsdb and log
+ */
+int mgs_params_fsdb_setup(const struct lu_env *env, struct mgs_device *mgs,
+                         struct fs_db *fsdb)
+{
+       struct llog_handle      *params_llh = NULL;
+       int                     rc;
+       ENTRY;
+
+       rc = mgs_find_or_make_fsdb(env, mgs, PARAMS_FILENAME, &fsdb);
+       if (fsdb != NULL) {
+               mutex_lock(&fsdb->fsdb_mutex);
+               rc = record_start_log(env, mgs, &params_llh, PARAMS_FILENAME);
+               if (rc == 0)
+                       rc = record_end_log(env, &params_llh);
+               mutex_unlock(&fsdb->fsdb_mutex);
+       }
+
+       RETURN(rc);
+}
+
+/* Cleanup params fsdb and log
+ */
+int mgs_params_fsdb_cleanup(const struct lu_env *env, struct mgs_device *mgs)
+{
+       return mgs_erase_logs(env, mgs, PARAMS_FILENAME);
+}
+
 /* Set a permanent (config log) param for a target or fs
  * \param lcfg buf0 may contain the device (testfs-MDT0000) name
  *             buf1 contains the single parameter
@@ -3198,13 +3845,14 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg)
 int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
                 struct lustre_cfg *lcfg, char *fsname)
 {
-        struct fs_db *fsdb;
-        struct mgs_target_info *mti;
+       struct fs_db *fsdb;
+       struct mgs_target_info *mti;
         char *devname, *param;
-        char *ptr, *tmp;
-        __u32 index;
-        int rc = 0;
-        ENTRY;
+       char *ptr;
+       const char *tmp;
+       __u32 index;
+       int rc = 0;
+       ENTRY;
 
         print_lustre_cfg(lcfg);
 
@@ -3226,27 +3874,27 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
                 RETURN(-ENOSYS);
         }
 
-        /* Extract fsname */
-        ptr = strrchr(devname, '-');
-        memset(fsname, 0, MTI_NAME_MAXLEN);
-        if (ptr && (server_name2index(ptr, &index, NULL) >= 0)) {
+       rc = mgs_parse_devname(devname, fsname, NULL);
+       if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
                 /* param related to llite isn't allowed to set by OST or MDT */
-                if (strncmp(param, PARAM_LLITE, sizeof(PARAM_LLITE)) == 0)
+               if (rc == 0 && strncmp(param, PARAM_LLITE,
+                                      sizeof(PARAM_LLITE) - 1) == 0)
                         RETURN(-EINVAL);
-
-                strncpy(fsname, devname, ptr - devname);
         } else {
                 /* assume devname is the fsname */
-                strncpy(fsname, devname, MTI_NAME_MAXLEN);
+               strlcpy(fsname, devname, MTI_NAME_MAXLEN);
         }
-        fsname[MTI_NAME_MAXLEN - 1] = 0;
         CDEBUG(D_MGS, "setparam fs='%s' device='%s'\n", fsname, devname);
 
-       rc = mgs_find_or_make_fsdb(env, mgs, fsname, &fsdb);
-        if (rc)
-                RETURN(rc);
-        if (!cfs_test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
-            cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
+       rc = mgs_find_or_make_fsdb(env, mgs,
+                                  lcfg->lcfg_command == LCFG_SET_PARAM ?
+                                  PARAMS_FILENAME : fsname, &fsdb);
+       if (rc)
+               RETURN(rc);
+
+       if (lcfg->lcfg_command != LCFG_SET_PARAM &&
+           !test_bit(FSDB_MGS_SELF, &fsdb->fsdb_flags) &&
+           test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
                 CERROR("No filesystem targets for %s.  cfg_device from lctl "
                        "is '%s'\n", fsname, devname);
                mgs_free_fsdb(mgs, fsdb);
@@ -3257,9 +3905,15 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
         OBD_ALLOC_PTR(mti);
         if (!mti)
                 GOTO(out, rc = -ENOMEM);
-        strncpy(mti->mti_fsname, fsname, MTI_NAME_MAXLEN);
-        strncpy(mti->mti_svname, devname, MTI_NAME_MAXLEN);
-        strncpy(mti->mti_params, param, sizeof(mti->mti_params));
+       if (strlcpy(mti->mti_fsname, fsname, sizeof(mti->mti_fsname))
+           >= sizeof(mti->mti_fsname))
+               GOTO(out, rc = -E2BIG);
+       if (strlcpy(mti->mti_svname, devname, sizeof(mti->mti_svname))
+           >= sizeof(mti->mti_svname))
+               GOTO(out, rc = -E2BIG);
+       if (strlcpy(mti->mti_params, param, sizeof(mti->mti_params))
+           >= sizeof(mti->mti_params))
+               GOTO(out, rc = -E2BIG);
         rc = server_name2index(mti->mti_svname, &mti->mti_stripe_index, &tmp);
         if (rc < 0)
                 /* Not a valid server; may be only fsname */
@@ -3269,20 +3923,26 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
                 if (server_make_name(rc, mti->mti_stripe_index, mti->mti_fsname,
                                      mti->mti_svname))
                         GOTO(out, rc = -EINVAL);
+       /*
+        * Revoke lock so everyone updates.  Should be alright if
+        * someone was already reading while we were updating the logs,
+        * so we don't really need to hold the lock while we're
+        * writing (above).
+        */
+       if (lcfg->lcfg_command == LCFG_SET_PARAM) {
+               mti->mti_flags = rc | LDD_F_PARAM2;
+               mutex_lock(&fsdb->fsdb_mutex);
+               rc = mgs_write_log_param2(env, mgs, fsdb, mti, mti->mti_params);
+               mutex_unlock(&fsdb->fsdb_mutex);
+               mgs_revoke_lock(mgs, fsdb, CONFIG_T_PARAMS);
+       } else {
+               mti->mti_flags = rc | LDD_F_PARAM;
+               mutex_lock(&fsdb->fsdb_mutex);
+               rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
+               mutex_unlock(&fsdb->fsdb_mutex);
+               mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
+       }
 
-        mti->mti_flags = rc | LDD_F_PARAM;
-
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
-       rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
-
-        /*
-         * Revoke lock so everyone updates.  Should be alright if
-         * someone was already reading while we were updating the logs,
-         * so we don't really need to hold the lock while we're
-         * writing (above).
-         */
-       mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
 out:
         OBD_FREE_PTR(mti);
         RETURN(rc);
@@ -3290,9 +3950,9 @@ out:
 
 static int mgs_write_log_pool(const struct lu_env *env,
                              struct mgs_device *mgs, char *logname,
-                              struct fs_db *fsdb, char *lovname,
+                             struct fs_db *fsdb, char *tgtname,
                               enum lcfg_command_type cmd,
-                              char *poolname, char *fsname,
+                             char *fsname, char *poolname,
                               char *ostname, char *comment)
 {
         struct llog_handle *llh = NULL;
@@ -3301,18 +3961,96 @@ static int mgs_write_log_pool(const struct lu_env *env,
        rc = record_start_log(env, mgs, &llh, logname);
        if (rc)
                return rc;
-       rc = record_marker(env, llh, fsdb, CM_START, lovname, comment);
+       rc = record_marker(env, llh, fsdb, CM_START, tgtname, comment);
        if (rc)
                goto out;
-       rc = record_base(env, llh, lovname, 0, cmd, poolname, fsname, ostname, 0);
+       rc = record_base(env, llh, tgtname, 0, cmd,
+                        fsname, poolname, ostname, 0);
        if (rc)
                goto out;
-       rc = record_marker(env, llh, fsdb, CM_END, lovname, comment);
+       rc = record_marker(env, llh, fsdb, CM_END, tgtname, comment);
 out:
        record_end_log(env, &llh);
         return rc;
 }
 
+int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
+                   enum lcfg_command_type cmd, const char *nodemap_name,
+                   char *param)
+{
+       lnet_nid_t      nid[2];
+       __u32           idmap[2];
+       bool            bool_switch;
+       __u32           int_id;
+       int             rc = 0;
+       ENTRY;
+
+       switch (cmd) {
+       case LCFG_NODEMAP_ADD:
+               rc = nodemap_add(nodemap_name);
+               break;
+       case LCFG_NODEMAP_DEL:
+               rc = nodemap_del(nodemap_name);
+               break;
+       case LCFG_NODEMAP_ADD_RANGE:
+               rc = nodemap_parse_range(param, nid);
+               if (rc != 0)
+                       break;
+               rc = nodemap_add_range(nodemap_name, nid);
+               break;
+       case LCFG_NODEMAP_DEL_RANGE:
+               rc = nodemap_parse_range(param, nid);
+               if (rc != 0)
+                       break;
+               rc = nodemap_del_range(nodemap_name, nid);
+               break;
+       case LCFG_NODEMAP_ADMIN:
+               bool_switch = simple_strtoul(param, NULL, 10);
+               rc = nodemap_set_allow_root(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_TRUSTED:
+               bool_switch = simple_strtoul(param, NULL, 10);
+               rc = nodemap_set_trust_client_ids(nodemap_name, bool_switch);
+               break;
+       case LCFG_NODEMAP_SQUASH_UID:
+               int_id = simple_strtoul(param, NULL, 10);
+               rc = nodemap_set_squash_uid(nodemap_name, int_id);
+               break;
+       case LCFG_NODEMAP_SQUASH_GID:
+               int_id = simple_strtoul(param, NULL, 10);
+               rc = nodemap_set_squash_gid(nodemap_name, int_id);
+               break;
+       case LCFG_NODEMAP_ADD_UIDMAP:
+       case LCFG_NODEMAP_ADD_GIDMAP:
+               rc = nodemap_parse_idmap(param, idmap);
+               if (rc != 0)
+                       break;
+               if (cmd == LCFG_NODEMAP_ADD_UIDMAP)
+                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_UID,
+                                              idmap);
+               else
+                       rc = nodemap_add_idmap(nodemap_name, NODEMAP_GID,
+                                              idmap);
+               break;
+       case LCFG_NODEMAP_DEL_UIDMAP:
+       case LCFG_NODEMAP_DEL_GIDMAP:
+               rc = nodemap_parse_idmap(param, idmap);
+               if (rc != 0)
+                       break;
+               if (cmd == LCFG_NODEMAP_DEL_UIDMAP)
+                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_UID,
+                                              idmap);
+               else
+                       rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
+                                              idmap);
+               break;
+       default:
+               rc = -EINVAL;
+       }
+
+       RETURN(rc);
+}
+
 int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                 enum lcfg_command_type cmd, char *fsname,
                 char *poolname, char *ostname)
@@ -3331,7 +4069,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                 CERROR("Can't get db for %s\n", fsname);
                 RETURN(rc);
         }
-        if (cfs_test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
+       if (test_bit(FSDB_LOG_EMPTY, &fsdb->fsdb_flags)) {
                 CERROR("%s is not defined\n", fsname);
                mgs_free_fsdb(mgs, fsdb);
                 RETURN(-EINVAL);
@@ -3385,21 +4123,20 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                 break;
         }
 
-        cfs_mutex_lock(&fsdb->fsdb_mutex);
-
         if (canceled_label != NULL) {
                 OBD_ALLOC_PTR(mti);
                 if (mti == NULL)
                        GOTO(out_cancel, rc = -ENOMEM);
         }
 
+       mutex_lock(&fsdb->fsdb_mutex);
         /* write pool def to all MDT logs */
         for (i = 0; i < INDEX_MAP_SIZE * 8; i++) {
-                 if (cfs_test_bit(i,  fsdb->fsdb_mdt_index_map)) {
+               if (test_bit(i,  fsdb->fsdb_mdt_index_map)) {
                        rc = name_create_mdt_and_lov(&logname, &lovname,
                                                     fsdb, i);
                        if (rc) {
-                               cfs_mutex_unlock(&fsdb->fsdb_mutex);
+                               mutex_unlock(&fsdb->fsdb_mutex);
                                GOTO(out_mti, rc);
                        }
                         if (canceled_label != NULL) {
@@ -3417,7 +4154,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                         name_destroy(&logname);
                         name_destroy(&lovname);
                        if (rc) {
-                               cfs_mutex_unlock(&fsdb->fsdb_mutex);
+                               mutex_unlock(&fsdb->fsdb_mutex);
                                GOTO(out_mti, rc);
                        }
                 }
@@ -3425,14 +4162,14 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
 
        rc = name_create(&logname, fsname, "-client");
        if (rc) {
-               cfs_mutex_unlock(&fsdb->fsdb_mutex);
+               mutex_unlock(&fsdb->fsdb_mutex);
                GOTO(out_mti, rc);
        }
        if (canceled_label != NULL) {
                rc = mgs_modify(env, mgs, fsdb, mti, logname,
                                fsdb->fsdb_clilov, canceled_label, CM_SKIP);
                if (rc < 0) {
-                       cfs_mutex_unlock(&fsdb->fsdb_mutex);
+                       mutex_unlock(&fsdb->fsdb_mutex);
                        name_destroy(&logname);
                        GOTO(out_mti, rc);
                }
@@ -3440,7 +4177,7 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
 
        rc = mgs_write_log_pool(env, mgs, logname, fsdb, fsdb->fsdb_clilov,
                                cmd, fsname, poolname, ostname, label);
-        cfs_mutex_unlock(&fsdb->fsdb_mutex);
+       mutex_unlock(&fsdb->fsdb_mutex);
        name_destroy(&logname);
         /* request for update */
        mgs_revoke_lock(mgs, fsdb, CONFIG_T_CONFIG);
@@ -3456,64 +4193,3 @@ out_label:
        OBD_FREE(label, label_sz);
         return rc;
 }
-
-#if 0
-/******************** unused *********************/
-static int mgs_backup_llog(struct obd_device *obd, char* fsname)
-{
-        struct file *filp, *bak_filp;
-        struct lvfs_run_ctxt saved;
-        char *logname, *buf;
-        loff_t soff = 0 , doff = 0;
-        int count = 4096, len;
-        int rc = 0;
-
-        OBD_ALLOC(logname, PATH_MAX);
-        if (logname == NULL)
-                return -ENOMEM;
-
-        OBD_ALLOC(buf, count);
-        if (!buf)
-                GOTO(out , rc = -ENOMEM);
-
-        len = snprintf(logname, PATH_MAX, "%s/%s.bak",
-                       MOUNT_CONFIGS_DIR, fsname);
-
-        if (len >= PATH_MAX - 1) {
-                GOTO(out, -ENAMETOOLONG);
-        }
-
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
-        bak_filp = l_filp_open(logname, O_RDWR|O_CREAT|O_TRUNC, 0660);
-        if (IS_ERR(bak_filp)) {
-                rc = PTR_ERR(bak_filp);
-                CERROR("backup logfile open %s: %d\n", logname, rc);
-                GOTO(pop, rc);
-        }
-        sprintf(logname, "%s/%s", MOUNT_CONFIGS_DIR, fsname);
-        filp = l_filp_open(logname, O_RDONLY, 0);
-        if (IS_ERR(filp)) {
-                rc = PTR_ERR(filp);
-                CERROR("logfile open %s: %d\n", logname, rc);
-                GOTO(close1f, rc);
-        }
-
-        while ((rc = lustre_fread(filp, buf, count, &soff)) > 0) {
-                rc = lustre_fwrite(bak_filp, buf, count, &doff);
-                break;
-        }
-
-        filp_close(filp, 0);
-close1f:
-        filp_close(bak_filp, 0);
-pop:
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-out:
-        if (buf)
-                OBD_FREE(buf, count);
-        OBD_FREE(logname, PATH_MAX);
-        return rc;
-}
-
-#endif