Whamcloud - gitweb
LU-4200 mgs: fix counting of mgs exports
[fs/lustre-release.git] / lustre / mgs / mgs_llog.c
index cf43a4b..820acba 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, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2013, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -46,7 +46,6 @@
 #define D_MGS D_CONFIG
 
 #include <obd.h>
-#include <obd_lov.h>
 #include <lustre_param.h>
 #include <lustre_sec.h>
 #include <lustre_quota.h>
@@ -67,9 +66,6 @@ int class_dentry_readdir(const struct lu_env *env,
 
        CFS_INIT_LIST_HEAD(list);
 
-       if (!dt_try_as_dir(env, dir))
-               GOTO(out, rc = -ENOTDIR);
-
        LASSERT(dir);
        LASSERT(dir->do_index_ops);
 
@@ -122,7 +118,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);
@@ -697,8 +692,14 @@ 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;
@@ -707,6 +708,8 @@ static int mgs_modify(const struct lu_env *env, struct mgs_device *mgs,
                          NULL);
        if (!rc && !mml->mml_modified)
                rc = 1;
+
+out_free:
         OBD_FREE_PTR(mml);
 
 out_close:
@@ -947,7 +950,6 @@ static int mgs_replace_handler(const struct lu_env *env,
                               struct llog_rec_hdr *rec,
                               void *data)
 {
-       struct llog_rec_hdr local_rec = *rec;
        struct mgs_replace_uuid_lookup *mrul;
        struct lustre_cfg *lcfg = REC_DATA(rec);
        int cfg_len = REC_DATA_LEN(rec);
@@ -994,9 +996,7 @@ static int mgs_replace_handler(const struct lu_env *env,
                RETURN(0);
 copy_out:
        /* Record is placed in temporary llog as is */
-       local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail);
-       rc = llog_write(env, mrul->temp_llh, &local_rec, NULL, 0,
-                        (void *)lcfg, -1);
+       rc = llog_write(env, mrul->temp_llh, rec, NULL, 0, NULL, -1);
 
        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,
@@ -1010,83 +1010,20 @@ skip_out:
        RETURN(rc);
 }
 
-static int mgs_backup_llog(const struct lu_env *env,
-                          struct obd_device *mgs,
-                          char *fsname, char *backup)
+static int mgs_log_is_empty(const struct lu_env *env,
+                           struct mgs_device *mgs, char *name)
 {
-       struct obd_uuid *uuid;
-       struct llog_handle *orig_llh, *bak_llh;
-       struct llog_ctxt *lctxt;
-       int rc, rc2;
-       ENTRY;
-
-       lctxt = llog_get_context(mgs, LLOG_CONFIG_ORIG_CTXT);
-       if (!lctxt) {
-               CERROR("%s: missing llog context\n", mgs->obd_name);
-               GOTO(out, rc = -EINVAL);
-       }
-
-       /* Make sure there's no old backup log */
-       rc = llog_erase(env, lctxt, NULL, backup);
-       if (rc < 0 && rc != -ENOENT)
-               GOTO(out_put, rc);
-
-       /* open backup log */
-       rc = llog_open_create(env, lctxt, &bak_llh, NULL, backup);
-       if (rc) {
-               CERROR("%s: backup logfile open %s: rc = %d\n",
-                      mgs->obd_name, backup, rc);
-               GOTO(out_put, rc);
-       }
-
-       /* set the log header uuid */
-       OBD_ALLOC_PTR(uuid);
-       if (uuid == NULL)
-                GOTO(out_put, rc = -ENOMEM);
-       obd_str2uuid(uuid, backup);
-       rc = llog_init_handle(env, bak_llh, LLOG_F_IS_PLAIN, uuid);
-       OBD_FREE_PTR(uuid);
-       if (rc)
-               GOTO(out_close1, rc);
-
-       /* open original log */
-       rc = llog_open(env, lctxt, &orig_llh, NULL, fsname,
-                      LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_close1, rc);
-       }
-
-       rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_close2, rc);
+       struct llog_ctxt        *ctxt;
+       int                      rc;
 
-       /* Copy remote log */
-       rc = llog_process(env, orig_llh, llog_copy_handler,
-                         (void *)bak_llh, NULL);
+       ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
+       LASSERT(ctxt != NULL);
 
-out_close2:
-       rc2 = llog_close(env, orig_llh);
-       if (!rc)
-               rc = rc2;
-out_close1:
-       rc2 = llog_close(env, bak_llh);
-        if (!rc)
-                rc = rc2;
-out_put:
-       if (lctxt)
-               llog_ctxt_put(lctxt);
-out:
-       if (rc)
-               CERROR("%s: Failed to backup log %s: rc = %d\n",
-                      mgs->obd_name, fsname, rc);
-       RETURN(rc);
+       rc = llog_is_empty(env, ctxt, name);
+       llog_ctxt_put(ctxt);
+       return rc;
 }
 
-static int mgs_log_is_empty(const struct lu_env *env, struct mgs_device *mgs,
-                           char *name);
-
 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)
@@ -1095,6 +1032,7 @@ static int mgs_replace_nids_log(const struct lu_env *env,
        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;
@@ -1109,31 +1047,31 @@ static int mgs_replace_nids_log(const struct lu_env *env,
                GOTO(out_put, rc = 0);
        }
 
-       OBD_ALLOC(backup, strlen(logname) + 5);
+       OBD_ALLOC(backup, strlen(logname) + strlen(".bak") + 1);
        if (backup == NULL)
                GOTO(out_put, rc = -ENOMEM);
 
        sprintf(backup, "%s.bak", logname);
 
-       rc = mgs_backup_llog(env, mgs, logname, backup);
-       if (rc < 0) {
+       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);
        }
 
-       /* Now erase original log file. Connections are not allowed.
-          Backup is already saved */
-       rc = llog_erase(env, ctxt, NULL, logname);
-       if (rc < 0 && rc != -ENOENT)
-               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, NULL);
+       rc = llog_init_handle(env, orig_llh, LLOG_F_IS_PLAIN, &cfg_uuid);
        if (rc)
                GOTO(out_closel, rc);
 
@@ -1176,14 +1114,15 @@ out_restore:
        if (rc) {
                CERROR("%s: llog should be restored: rc = %d\n",
                       mgs->obd_name, rc);
-               rc2 = mgs_backup_llog(env, mgs, backup, logname);
+               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) + 5);
+       OBD_FREE(backup, strlen(backup) + 1);
 
 out_put:
        llog_ctxt_put(ctxt);
@@ -1206,26 +1145,24 @@ out_put:
  */
 static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
 {
-       char *ptr;
+       int rc;
        ENTRY;
 
        /* Extract fsname */
-       ptr = strrchr(devname, '-');
-
        if (fsname) {
-               if (!ptr) {
+               rc = server_name2fsname(devname, fsname, NULL);
+               if (rc < 0) {
                        CDEBUG(D_MGS, "Device name %s without fsname\n",
                               devname);
                        RETURN(-EINVAL);
                }
-               memset(fsname, 0, MTI_NAME_MAXLEN);
-               strncpy(fsname, devname, ptr - devname);
-               fsname[MTI_NAME_MAXLEN - 1] = 0;
        }
 
        if (index) {
-               if (server_name2index(ptr, index, NULL) < 0) {
-                       CDEBUG(D_MGS, "Device name with wrong index\n");
+               rc = server_name2index(devname, index, NULL);
+               if (rc < 0) {
+                       CDEBUG(D_MGS, "Device name %s with wrong index\n",
+                              devname);
                        RETURN(-EINVAL);
                }
        }
@@ -1233,13 +1170,36 @@ static int mgs_parse_devname(char *devname, char *fsname, __u32 *index)
        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) && (num_exports <= 2) */
-       return (num_devices <= 3) && (mgs_obd->obd_num_exports <= 2);
+          (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)
@@ -1398,16 +1358,21 @@ static int record_marker(const struct lu_env *env,
        struct mgs_thread_info *mgi = mgs_env_info(env);
        struct lustre_cfg *lcfg;
        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);
@@ -1464,35 +1429,6 @@ static int record_end_log(const struct lu_env *env, struct llog_handle **llh)
        return rc;
 }
 
-static int mgs_log_is_empty(const struct lu_env *env,
-                           struct mgs_device *mgs, char *name)
-{
-        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);
-       rc = llog_open(env, ctxt, &llh, NULL, name, LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_ctxt, rc);
-       }
-
-       llog_init_handle(env, llh, LLOG_F_IS_PLAIN, NULL);
-       if (rc)
-               GOTO(out_close, rc);
-       rc = llog_get_size(llh);
-
-out_close:
-       llog_close(env, llh);
-out_ctxt:
-       llog_ctxt_put(ctxt);
-       /* header is record 1 */
-       return (rc <= 1);
-}
-
 /******************** config "macros" *********************/
 
 /* write an lcfg directly into a log (with markers) */
@@ -1553,7 +1489,8 @@ int mgs_write_log_direct_all(const struct lu_env *env,
        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);
+               if (rc == 0)
+                       record_end_log(env, &llh);
         }
         name_destroy(&logname);
         if (rc)
@@ -1634,9 +1571,13 @@ static int add_param(char *params, char *key, char *val)
        return 0;
 }
 
-static int mgs_steal_llog_handler(const struct lu_env *env,
-                                 struct llog_handle *llh,
-                                 struct llog_rec_hdr *rec, void *data)
+/**
+ * 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;
@@ -1653,6 +1594,7 @@ static int mgs_steal_llog_handler(const struct lu_env *env,
            2: found mdc;
         */
         static int last_step = -1;
+       int cplen = 0;
 
         ENTRY;
 
@@ -1676,59 +1618,63 @@ 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) &&
+       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;
-                        strncpy(tmti->mti_svname, marker->cm_tgtname,
-                                sizeof(tmti->mti_svname));
+                       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) &&
+                       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;
+                       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) &&
+                       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));
+                       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) &&
+                       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;
-                        RETURN(rc);
-                }
-        }
+                       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);
@@ -1844,7 +1790,7 @@ static int mgs_steal_llog_for_mdt_from_client(const struct lu_env *env,
        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:
@@ -1930,9 +1876,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;
@@ -1999,11 +1945,13 @@ static int mgs_write_log_failnids(const struct lu_env *env,
                                failnodeuuid, cliname);
                        rc = record_add_uuid(env, llh, nid, failnodeuuid);
                 }
-               if (failnodeuuid)
+               if (failnodeuuid) {
                        rc = record_add_conn(env, llh, cliname, failnodeuuid);
+                       name_destroy(&failnodeuuid);
+                       failnodeuuid = NULL;
+               }
         }
 
-       name_destroy(&failnodeuuid);
         return rc;
 }
 
@@ -2485,7 +2433,7 @@ static int mgs_write_log_osc_to_lov(const struct lu_env *env,
        /* 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_llog_handler() LCFG_ADD_UUID.
+        * 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]));
@@ -2792,8 +2740,13 @@ static int mgs_wlp_lcfg(const struct lu_env *env,
                 return rc;
 
         lustre_cfg_bufs_reset(bufs, tgtname);
-        lustre_cfg_bufs_set_string(bufs, 1, ptr);
-        lcfg = lustre_cfg_new(LCFG_PARAM, bufs);
+       lustre_cfg_bufs_set_string(bufs, 1, ptr);
+       if (mti->mti_flags & LDD_F_PARAM2)
+               lustre_cfg_bufs_set_string(bufs, 2, LCTL_UPCALL);
+
+       lcfg = lustre_cfg_new((mti->mti_flags & LDD_F_PARAM2) ?
+                             LCFG_SET_PARAM : LCFG_PARAM, bufs);
+
         if (!lcfg)
                 return -ENOMEM;
        rc = mgs_write_log_direct(env, mgs, fsdb, logname,lcfg,tgtname,comment);
@@ -2801,6 +2754,22 @@ static int mgs_wlp_lcfg(const struct lu_env *env,
         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 */
 static int mgs_write_log_sys(const struct lu_env *env,
                             struct mgs_device *mgs, struct fs_db *fsdb,
@@ -3544,17 +3513,18 @@ static int mgs_write_log_param(const struct lu_env *env,
                 GOTO(end, rc);
         }
 
-        /* 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);
+       /* 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;
@@ -3623,6 +3593,7 @@ 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;
        }
 
        mutex_lock(&fsdb->fsdb_mutex);
@@ -3744,6 +3715,43 @@ 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)
+{
+       cfs_list_t               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, &list);
+       if (rc) {
+               CERROR("%s: can't read %s dir = %d\n",
+                      mgs->mgs_obd->obd_name, MOUNT_CONFIGS_DIR, rc);
+               RETURN(rc);
+       }
+
+       out = data->ioc_bulk;
+       remains = data->ioc_inllen1;
+       cfs_list_for_each_entry_safe(dirent, n, &list, list) {
+               cfs_list_del(&dirent->list);
+               suffix = strrchr(dirent->name, '-');
+               if (suffix != NULL) {
+                       l = snprintf(out, remains, "config log: $%s\n",
+                                    dirent->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)
 {
@@ -3775,13 +3783,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);
 
@@ -3807,7 +3816,7 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
        if (rc == 0 && !mgs_parse_devname(devname, NULL, &index)) {
                 /* param related to llite isn't allowed to set by OST or MDT */
                if (rc == 0 && strncmp(param, PARAM_LLITE,
-                                  sizeof(PARAM_LLITE)) == 0)
+                                      sizeof(PARAM_LLITE) - 1) == 0)
                         RETURN(-EINVAL);
         } else {
                 /* assume devname is the fsname */
@@ -3817,10 +3826,14 @@ int mgs_setparam(const struct lu_env *env, struct mgs_device *mgs,
         }
         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 (!test_bit(FSDB_MGS_SELF, &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);
@@ -3832,9 +3845,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 */
@@ -3844,20 +3863,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;
-
-       mutex_lock(&fsdb->fsdb_mutex);
-       rc = mgs_write_log_param(env, mgs, fsdb, mti, mti->mti_params);
-       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);
@@ -3865,9 +3890,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;
@@ -3876,18 +3901,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,
+                   const 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)
@@ -3960,14 +4063,13 @@ int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
                 break;
         }
 
-       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 (test_bit(i,  fsdb->fsdb_mdt_index_map)) {
@@ -4031,5 +4133,3 @@ out_label:
        OBD_FREE(label, label_sz);
         return rc;
 }
-
-