Whamcloud - gitweb
Branch b1_4_mountconf
authornathan <nathan>
Tue, 14 Mar 2006 21:48:43 +0000 (21:48 +0000)
committernathan <nathan>
Tue, 14 Mar 2006 21:48:43 +0000 (21:48 +0000)
b=9861
make mgsnids and failover nids part of string parameters
(e.g. mgsnode=<nid_list>), to simplify mkfs/mount, and to provide a
distinction between multiple nids per node, and multiple nodes.  String
parsing moves into kernel.  Arbitrary params can be added to mkfs.lustre
with --param key=value, hopefully preventing any need to ever change the
lustre_disk_data.

13 files changed:
lustre/include/linux/lustre_disk.h
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_param.h [new file with mode: 0644]
lustre/lov/lov_obd.c
lustre/mds/mds_open.c
lustre/mgc/mgc_request.c
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/obdclass/lustre_peer.c
lustre/obdclass/obd_mount.c
lustre/ptlrpc/pack_generic.c
lustre/utils/mkfs_lustre.c
lustre/utils/mount_lustre.c

index 647341a..467217a 100644 (file)
@@ -89,20 +89,14 @@ struct lustre_disk_data {
         __u32      ldd_flags;           /* LDD_SV_TYPE */
         __u32      ldd_svindex;         /* server index (0001), must match 
                                            svname */
-/*28*/  char       ldd_fsname[64];      /* filesystem this server is part of */
+        __u32      ldd_mount_type;      /* target fs type LDD_MT_* */
+        char       ldd_fsname[64];      /* filesystem this server is part of */
         char       ldd_svname[64];      /* this server's name (lustre-mdt0001)*/
-        enum ldd_mount_type ldd_mount_type;  /* target fs type LDD_MT_* */
-        __u16      ldd_mgsnid_count;
-        __u16      ldd_failnid_count;   /* server failover nid count */
-/*164*/ lnet_nid_t ldd_mgsnid[MTI_NIDS_MAX];  /* mgs nids; lmd can override */
-        lnet_nid_t ldd_failnid[MTI_NIDS_MAX]; /* server failover nids */
-        __u16      ldd_mgsnode[8];      /* nid count of each node in... */
-        __u16      ldd_failnode[8];     /* ...the nid arrays */
-
-/*1220*/__u8       ldd_uuid[40];        /* server UUID (COMPAT_146) */
+        __u8       ldd_uuid[40];        /* server UUID (COMPAT_146) */
    
-/*1260*/__u8       ldd_padding[4096 - 1260];
-/*4096*/char       ldd_mount_opts[4094]; /* target fs mount opts */
+/*200*/ __u8       ldd_padding[4096 - 200];
+/*4096*/char       ldd_mount_opts[4096]; /* target fs mount opts */
+/*8192*/char       ldd_params[4096];     /* key=value pairs */
 };
 
 #define IS_MDT(data)   ((data)->ldd_flags & LDD_F_SV_TYPE_MDT)
@@ -142,14 +136,13 @@ int server_name2index(char *svname, __u32 *idx, char **endptr);
 struct lustre_mount_data {
         __u32      lmd_magic;
         __u32      lmd_flags;         /* lustre mount flags */
-        int        lmd_mgsnid_count;  /* how many failover nids we have for 
-                                         the MGS */
+        int        lmd_mgs_failnodes; /* mgs failover node count */
         int        lmd_exclude_count;
-        char      *lmd_dev;           /* device or file system name */
+        char      *lmd_dev;           /* device name */
+        char      *lmd_fs;            /* file system name (client only) */
         char      *lmd_opts;          /* lustre mount options (as opposed to 
                                          _device_ mount options) */
         __u32     *lmd_exclude;       /* array of OSTs to ignore */
-        lnet_nid_t lmd_mgsnid[MTI_NIDS_MAX];/* who to contact at startup */
 };
 
 #define LMD_FLG_CLIENT       0x0002  /* Mounting a client only */
@@ -174,6 +167,7 @@ struct mkfs_opts {
         __u64 mo_device_sz;             /* in KB */
         int   mo_stripe_count;
         int   mo_flags; 
+        int   mo_mgs_failnodes;
 };
 
 /****************** last_rcvd file *********************/
@@ -268,7 +262,7 @@ struct lustre_sb_info {
 # define    s2lsi_nocast(sb) ((sb)->u.generic_sbp)
 #endif
 
-#define     get_profile_name(sb)   (s2lsi(sb)->lsi_lmd->lmd_dev)
+#define     get_profile_name(sb)   (s2lsi(sb)->lsi_lmd->lmd_fs)
 
 #endif /* __KERNEL__ */
 
@@ -303,5 +297,4 @@ int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id);
 
 #endif
 
-
 #endif // _LUSTRE_DISK_H
index efd593d..c634c79 100644 (file)
@@ -1006,6 +1006,7 @@ struct mgs_target_info {
         __u32            mti_failnid_count;
         __u32            mti_config_ver;
         __u32            mti_flags;
+        char             mti_params[2048];
 };
 
 extern void lustre_swab_mgs_target_info(struct mgs_target_info *oinfo);
diff --git a/lustre/include/linux/lustre_param.h b/lustre/include/linux/lustre_param.h
new file mode 100644 (file)
index 0000000..ba2bcfb
--- /dev/null
@@ -0,0 +1,45 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2006 Cluster File Systems, Inc.
+ *   Author: Nathan Rutman <nathan@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ * User-settable parameter keys
+ */
+
+#ifndef _LUSTRE_PARAM_H
+#define _LUSTRE_PARAM_H
+
+/* obd_mount.c */
+int class_find_param(char *buf, char *key, char **valp);
+int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh);
+
+
+/****************** User-settable parameter keys *********************/
+
+#define PARAM_MGSNODE          "mgsnode="
+#define PARAM_FAILNODE         "failnode="
+#define PARAM_OBD_TIMEOUT      "obd_timeout="
+#define PARAM_DEFAULT_STRIPE   "default_stripe_"
+#define PARAM_D_STRIPE_SIZE    PARAM_DEFAULT_STRIPE"size"
+#define PARAM_D_STRIPE_COUNT   PARAM_DEFAULT_STRIPE"count"
+#define PARAM_D_STRIPE_OFFSET  PARAM_DEFAULT_STRIPE"offset"
+#define PARAM_D_STRIPE_PATTERN PARAM_DEFAULT_STRIPE"pattern"
+
+#endif // _LUSTRE_PARAM_H
index f3a683c..90f2857 100644 (file)
@@ -52,6 +52,7 @@
 #include <linux/obd_lov.h>
 #include <linux/obd_ost.h>
 #include <linux/lprocfs_status.h>
+#include <linux/lustre_param.h>
 
 #include "lov_internal.h"
 
@@ -804,13 +805,13 @@ static int lov_process_config(struct obd_device *obd, obd_count len, void *buf)
                         }
                         *sval = 0;
                         val = simple_strtol(sval + 1, NULL, 0);
-                        if (strcmp(key, "default_stripe_size") == 0)
+                        if (strcmp(key, PARAM_D_STRIPE_SIZE) == 0)
                                 desc->ld_default_stripe_size = val;
-                        else if (strcmp(key, "default_stripe_count") == 0)
+                        else if (strcmp(key, PARAM_D_STRIPE_COUNT) == 0)
                                 desc->ld_default_stripe_count = val;
-                        else if (strcmp(key, "default_stripe_offset") == 0)
+                        else if (strcmp(key, PARAM_D_STRIPE_OFFSET) == 0)
                                 desc->ld_default_stripe_offset = val;
-                        else if (strcmp(key, "default_stripe_pattern") == 0)
+                        else if (strcmp(key, PARAM_D_STRIPE_PATTERN) == 0)
                                 desc->ld_pattern = val;
                         else {
                                 CERROR("Unknown param %s\n", key);
index 67d0fbe..c75a94b 100644 (file)
@@ -478,12 +478,13 @@ static int mds_create_objects(struct ptlrpc_request *req, int offset,
         }
 
         rc = fsfilt_set_md(obd, inode, *handle, lmm, lmm_size);
-        lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, 0);
-        lmm_bufsize = req->rq_repmsg->buflens[offset];
-        LASSERT(lmm_buf);
-        LASSERT(lmm_bufsize >= lmm_size);
-
-        memcpy(lmm_buf, lmm, lmm_size);
+        lmm_buf = lustre_msg_buf(req->rq_repmsg, offset, lmm_size);
+        if (!lmm_buf) {
+                CERROR("Can't allocate reply buffer size=%d\n", lmm_size);
+                rc = -ENOMEM;
+        } else {
+                memcpy(lmm_buf, lmm, lmm_size);
+        }
         obd_free_diskmd(mds->mds_osc_exp, &lmm);
  out_oa:
         oti_free_cookies(&oti);
index 772d4b8..de49e60 100644 (file)
@@ -58,12 +58,15 @@ int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id)
         
         /* fsname is at most 8 chars long at the beginning of the logname
            e.g. "lustre-MDT0001" or "lustre" */
-        name_end = strchr(logname, '-');
+        name_end = strrchr(logname, '-');
         if (name_end)
                 len = name_end - logname;
         else
                 len = strlen(logname);
-        LASSERT(len <= 8);
+        if (len > 8) {
+                CERROR("fsname too long: %s\n", logname);
+                return -EINVAL;
+        }
         memcpy(&resname, logname, len);
 
         memset(res_id, 0, sizeof(*res_id));
@@ -177,7 +180,11 @@ static int config_log_add(char *logname, struct config_llog_instance *cfg,
                           strlen(cfg->cfg_instance) + 1);
                 strcpy(cld->cld_cfg.cfg_instance, cfg->cfg_instance);
         }
-        mgc_logname2resid(logname, &cld->cld_resid);
+        rc = mgc_logname2resid(logname, &cld->cld_resid);
+        if (rc) {
+                config_log_put(cld);
+                RETURN(rc);
+        }
         spin_lock(&config_list_lock);
         list_add(&cld->cld_list_chain, &config_llog_list);
         spin_unlock(&config_list_lock);
@@ -612,9 +619,11 @@ static int mgc_target_register(struct obd_export *exp,
         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MGS_VERSION,
                               MGS_TARGET_REG, 1, &size, NULL);
         if (!req)
-                RETURN(rc = -ENOMEM);
+                RETURN(-ENOMEM);
 
         req_mti = lustre_msg_buf(req->rq_reqmsg, 0, sizeof(*req_mti));
+        if (!req_mti) 
+                RETURN(-ENOMEM);
         memcpy(req_mti, mti, sizeof(*req_mti));
 
         req->rq_replen = lustre_msg_size(1, &rep_size);
@@ -1009,20 +1018,23 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf)
                        cfg->cfg_last_idx);
 
                 /* We're only called through here on the initial mount */
-                config_log_add(logname, cfg, sb);
-
+                rc = config_log_add(logname, cfg, sb);
+                if (rc) 
+                        break;
                 cld = config_log_find(logname, cfg);
                 if (IS_ERR(cld)) {
                         rc = PTR_ERR(cld);
-                } else {
-                        /* COMPAT_146 */
-                        /* For old logs, there was no start marker. */
-                        /* FIXME only set this for old logs! */
-                        cld->cld_cfg.cfg_flags |= CFG_F_MARKER;
-
-                        rc = mgc_process_log(obd, cld);
-                        config_log_put(cld);
+                        break;
                 }
+                
+                /* COMPAT_146 */
+                /* For old logs, there was no start marker. */
+                /* FIXME only set this for old logs! */
+                cld->cld_cfg.cfg_flags |= CFG_F_MARKER;
+                
+                rc = mgc_process_log(obd, cld);
+                config_log_put(cld);
+                
                 break;       
         }
         case LCFG_LOG_END: {
index ddcb2f4..7570553 100644 (file)
@@ -277,14 +277,13 @@ static int mgs_get_cfg_lock(struct obd_device *obd, char *fsname,
         ENTRY;
 
         rc = mgc_logname2resid(fsname, &res_id);
-
-        rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, res_id,
-                              LDLM_PLAIN, NULL, LCK_EX, &flags,
-                              ldlm_blocking_ast, ldlm_completion_ast, 
-                              NULL, fsname, NULL, 0, NULL, lockh);
-        if (rc) {
-                CERROR("can't take cfg lock %d\n", rc);
-        }
+        if (!rc) 
+                rc = ldlm_cli_enqueue(NULL, NULL, obd->obd_namespace, res_id,
+                                      LDLM_PLAIN, NULL, LCK_EX, &flags,
+                                      ldlm_blocking_ast, ldlm_completion_ast, 
+                                      NULL, fsname, NULL, 0, NULL, lockh);
+        if (rc) 
+                CERROR("can't take cfg lock for %s (%d)\n", fsname, rc);
         
         RETURN(rc);
 }
index 69cab1d..66c0216 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/lvfs.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/lustre_disk.h>
+#include <linux/lustre_param.h>
 #include "mgs_internal.h"
 
 
@@ -268,10 +269,10 @@ static inline int name_create(char *prefix, char *suffix, char **newname)
         return 0;
 }
 
-static inline void name_destroy(char *newname)
+static inline void name_destroy(char *name)
 {        
-        if (newname)
-                OBD_FREE(newname, strlen(newname) + 1);
+        if (name)
+                OBD_FREE(name, strlen(name) + 1);
 }
 
 
@@ -717,12 +718,10 @@ static int mgs_write_log_failnids(struct obd_device *obd,
                                   struct llog_handle *llh,
                                   char *cliname)
 {
-        char *failnodeuuid;
+        char *failnodeuuid = NULL;
+        char *ptr = mti->mti_params;
         lnet_nid_t nid;
-        int i, j = 0, rc = 0;
-
-        if (!mti->mti_failnid_count) 
-                return 0;
+        int rc = 0;
 
         /*
         #03 L add_uuid  nid=uml1@tcp(0x20000c0a80201) nal=90 0:  1:uml1_UUID
@@ -732,27 +731,29 @@ static int mgs_write_log_failnids(struct obd_device *obd,
         #0x L add_uuid  nid=2@elan(0x1000000000002)   nal=90 0:  1:uml2_UUID
         #07 L add_conn 0:OSC_uml1_ost1_mdsA  1:uml2_UUID
         */
-        
-        /* We don't know the failover node name, so just use the first nid
-           as the uuid */
-        name_create(libcfs_nid2str(mti->mti_failnids[0]), "", &failnodeuuid);
-        for (i = 0; i < mti->mti_failnid_count; i++) {
-                nid = mti->mti_failnids[i];
-                if (mti->mti_failnodes[j] && (i >= mti->mti_failnodes[j])) {
-                        /* This is the first nid of a new failover node.  
-                           add_conn the old uuid, and start a new one. */
+
+        /* Pull failnid info out of params string */
+        while (class_find_param(ptr, PARAM_FAILNODE, &ptr) == 0) {
+                while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                        if (failnodeuuid == NULL) {
+                                /* We don't know the failover node name, 
+                                   so just use the first nid as the uuid */
+                                rc = name_create(libcfs_nid2str(nid), "",
+                                                 &failnodeuuid);
+                                if (rc) 
+                                        return rc;
+                        }
+                        CDEBUG(D_MGS, "add nid %s for failover uuid %s, "
+                               "client %s\n", libcfs_nid2str(nid),
+                               failnodeuuid, cliname);
+                        rc = record_add_uuid(obd, llh, nid, failnodeuuid);
+                }
+                if (failnodeuuid) {
                         rc = record_add_conn(obd, llh, cliname, failnodeuuid);
                         name_destroy(failnodeuuid);
-                        name_create(libcfs_nid2str(mti->mti_failnids[i]),
-                                    "", &failnodeuuid);
-                        j++;
+                        failnodeuuid = NULL;
                 }
-                CDEBUG(D_MGS, "add nid %s for failover uuid %s, client %s\n", 
-                       libcfs_nid2str(nid), failnodeuuid, cliname);
-                rc = record_add_uuid(obd, llh, nid, failnodeuuid);
         }
-        rc = record_add_conn(obd, llh, cliname, failnodeuuid);
-        name_destroy(failnodeuuid);
 
         return rc;
 }
@@ -1019,7 +1020,6 @@ static int mgs_write_log_add_failnid(struct obd_device *obd, struct fs_db *fsdb,
                 RETURN(-EINVAL);
         }
         
-        
         /* Add failover nids to client log */
         name_create(mti->mti_fsname, "-client", &logname);
         rc = record_start_log(obd, &llh, logname);
@@ -1075,7 +1075,9 @@ int mgs_check_failnid(struct obd_device *obd, struct mgs_target_info *mti)
            if just one nid is missing, add uuid for nodeuuid[nid0]).
         */
 
-
+        /* Hey, we can just check mti->params to see if we're already in
+           the failover list */
+        
         down(&fsdb->fsdb_sem);
         rc = mgs_write_log_add_failnid(obd, fsdb, mti);
         up(&fsdb->fsdb_sem);
@@ -1280,9 +1282,9 @@ static int mgs_clear_log(struct obd_device *obd, char *name)
         return(rc);
 }
 
-static int dentry_readdir(struct obd_device *obd, struct dentry *dir,
-                          struct vfsmount *inmnt, 
-                          struct list_head *dentry_list){
+static int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
+                                struct vfsmount *inmnt, 
+                                struct list_head *dentry_list){
         /* see mds_cleanup_pending */
         struct lvfs_run_ctxt saved;
         struct file *file;
@@ -1327,8 +1329,8 @@ int mgs_erase_logs(struct obd_device *obd, char *fsname)
         ENTRY;
         
         /* Find all the logs in the CONFIGS directory */
-        rc = dentry_readdir(obd, mgs->mgs_configs_dir,
-                             mgs->mgs_vfsmnt, &dentry_list);
+        rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
+                                  mgs->mgs_vfsmnt, &dentry_list);
         if (rc) {
                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
                 RETURN(rc);
@@ -1371,8 +1373,8 @@ int mgs_setparam_all_logs(struct obd_device *obd, struct fs_db *fsdb,
         name_destroy(logname);
 
         /* Find all the logs in the CONFIGS directory */
-        rc = dentry_readdir(obd, mgs->mgs_configs_dir,
-                             mgs->mgs_vfsmnt, &dentry_list);
+        rc = class_dentry_readdir(obd, mgs->mgs_configs_dir,
+                                  mgs->mgs_vfsmnt, &dentry_list);
         if (rc) {
                 CERROR("Can't read %s dir\n", MOUNT_CONFIGS_DIR);
                 RETURN(rc);
@@ -1416,29 +1418,6 @@ static void print_lustre_cfg(struct lustre_cfg *lcfg)
         EXIT;
 }
 
-/* returns 1 if key matches, else 0 */
-static int class_match_key(char *key, char *buf, char **valh)
-{
-        char *val;
-        *valh = NULL;
-
-        if (strncmp(key, buf, strlen(key)) != 0) 
-                return 0;
-
-        val = strchr(buf, '=');
-        if (!val || (*(++val) == 0)) {
-                CERROR("Key has no value %s\n", buf);
-                return 0;
-        }
-        if (val - buf > strlen(key) + 1) {
-                /* We didn't match the entire key */
-                return 0;
-        }
-
-        *valh = val;
-        return 1;
-}
-
 /* Set a permanent (config log) param for a target or fs */
 int mgs_setparam(struct obd_device *obd, char *fsname, struct lustre_cfg *lcfg)
 {
@@ -1481,10 +1460,13 @@ int mgs_setparam(struct obd_device *obd, char *fsname, struct lustre_cfg *lcfg)
 
         /* add failover nidlist */
         if ((lcfg->lcfg_command == LCFG_PARAM) && 
-            class_match_key("failnid", lustre_cfg_string(lcfg, 1), &val)) {
+            class_find_param(lustre_cfg_string(lcfg, 1), 
+                           PARAM_FAILNODE, &val)) {
                 struct mgs_target_info *mti;
-                CDEBUG(D_MGS, "failnid, mod MDT, client\n");
+                CDEBUG(D_MGS, "failnode, mod MDT, client\n");
                 OBD_ALLOC_PTR(mti);
+                if (!mti) 
+                        GOTO(out, rc = -ENOMEM);
                 strcpy(mti->mti_fsname, fsname);
                 strcpy(mti->mti_svname, devname);
                 rc = server_name2index(devname, &mti->mti_stripe_index, NULL);
@@ -1493,20 +1475,19 @@ int mgs_setparam(struct obd_device *obd, char *fsname, struct lustre_cfg *lcfg)
                         GOTO(out, rc);
                 }
                 mti->mti_flags = rc;
-                /* FIXME add to lctl.  nids must be in lnet_nid_t
-                   form, not ascii - we can't resolve hostnames from the 
-                   kernel. */
-                mti->mti_failnid_count = simple_strtoul(val, NULL, 10);
-                memcpy(mti->mti_failnids, lustre_cfg_string(lcfg, 2), 
-                       mti->mti_failnid_count * sizeof(mti->mti_failnids[0]));
-                /* assume these are nids for a single node. */
+                strncpy(mti->mti_params, lustre_cfg_string(lcfg, 1), 
+                        sizeof(mti->mti_params));
+                /* FIXME add to lctl.  nids must be in dotted-quad ascii -
+                   we can't resolve hostnames from the kernel. */
                 rc = mgs_write_log_add_failnid(obd, fsdb, mti); 
                 OBD_FREE_PTR(mti);
                 GOTO(out, rc);
         }
         
         /* lov default stripe params */
-        if ((lcfg->lcfg_command == LCFG_PARAM) && strstr(devname, "-mdtlov")) {
+        if ((lcfg->lcfg_command == LCFG_PARAM) && 
+            class_find_param(lustre_cfg_string(lcfg, 1),
+                           PARAM_DEFAULT_STRIPE, &val)) {
                 char *lovname, *logname;
                 CDEBUG(D_MGS, "lov param, mod MDT, client\n");
                 name_create(fsname, "-MDT0000", &logname);
index 499e313..716368f 100644 (file)
@@ -85,6 +85,8 @@ int lustre_uuid_to_peer(char *uuid, lnet_nid_t *peer_nid, int index)
         return -ENOENT;
 }
 
+/* Add a nid to a niduuid.  Multiple nids can be added to a single uuid; 
+   LNET will choose the best one. */
 int class_add_uuid(char *uuid, __u64 nid)
 {
         struct uuid_nid_data *data;
@@ -120,7 +122,7 @@ int class_add_uuid(char *uuid, __u64 nid)
         return 0;
 }
 
-/* delete only one entry if uuid is specified, otherwise delete all */
+/* Delete the nids for one uuid if specified, otherwise delete all */
 int class_del_uuid (char *uuid)
 {
         struct list_head  deathrow;
index 6233d16..ca0342e 100644 (file)
 #include <linux/version.h> 
 #include <linux/lustre_log.h>
 #include <linux/lustre_disk.h>
+#include <linux/lustre_param.h>
 #include <linux/lustre_ver.h>
                       
 static int (*client_fill_super)(struct super_block *sb) = NULL;
 
+/*********** string parsing utils *********/
+
+/* returns 0 if key matches as far as keylen, else 1 */
+int class_find_param(char *buf, char *key, char **valp)
+{
+        char *ptr;
+
+        if (!buf) 
+                return 1;
+
+        if ((ptr = strstr(buf, key)) == NULL) 
+                return 1;
+
+        if (valp) 
+                *valp = ptr + strlen(key);
+        
+        return 0;
+}
+
+/* 0 is good nid, 
+   1 not found
+   < 0 error
+   endh is set to next separator */
+int class_parse_nid(char *buf, lnet_nid_t *nid, char **endh)
+{
+        char tmp, *endp;
+
+        if (!buf) 
+                return 1;
+        while (*buf == ',' || *buf == ':') 
+                buf++;
+        if (*buf == ' ' || *buf == '/' || *buf == '\0') 
+                return 1;
+
+        /* nid separators or end of nids */
+        endp = strpbrk(buf, ",: /");
+        if (endp == NULL) 
+                endp = buf + strlen(buf);
+
+        tmp = *endp;
+        *endp = '\0';
+        *nid = libcfs_str2nid(buf);
+        if (*nid == LNET_NID_ANY) {
+                LCONSOLE_ERROR("Can't parse NID '%s'\n", buf);
+                *endp = tmp;
+                return -EINVAL;
+        }
+        *endp = tmp;
+
+        if (endh) 
+                *endh = endp;
+        CDEBUG(D_WARNING, "Nid %s\n", libcfs_nid2str(*nid));
+        return 0;
+}
 
 /*********** mount lookup *********/
 
@@ -240,8 +295,6 @@ int server_put_mount(char *name, struct vfsmount *mnt)
 
 static void ldd_print(struct lustre_disk_data *ldd)
 {
-        int i;
-
         PRINT_CMD(PRINT_MASK, "  disk data:\n"); 
         PRINT_CMD(PRINT_MASK, "config:  %d\n", ldd->ldd_config_ver);
         PRINT_CMD(PRINT_MASK, "fs:      %s\n", ldd->ldd_fsname);
@@ -250,18 +303,7 @@ static void ldd_print(struct lustre_disk_data *ldd)
         PRINT_CMD(PRINT_MASK, "flags:   %#x\n", ldd->ldd_flags);
         PRINT_CMD(PRINT_MASK, "diskfs:  %s\n", MT_STR(ldd));
         PRINT_CMD(PRINT_MASK, "options: %s\n", ldd->ldd_mount_opts);
-        if (!ldd->ldd_mgsnid_count) 
-                PRINT_CMD(PRINT_MASK, "no MGS nids\n");
-        else for (i = 0; i < ldd->ldd_mgsnid_count; i++) {
-                PRINT_CMD(PRINT_MASK, "mgs nid %d:  %s\n", i, 
-                       libcfs_nid2str(ldd->ldd_mgsnid[i]));
-        }
-        if (!ldd->ldd_failnid_count)
-                PRINT_CMD(PRINT_MASK, "no failover nids\n");
-        else for (i = 0; i < ldd->ldd_failnid_count; i++) {
-                PRINT_CMD(PRINT_MASK, "failover nid %d:  %s\n", i,
-                          libcfs_nid2str(ldd->ldd_failnid[i]));
-        }
+        PRINT_CMD(PRINT_MASK, "params: %s\n", ldd->ldd_params);
 }
 
 static int ldd_parse(struct lvfs_run_ctxt *mount_ctxt, 
@@ -419,7 +461,8 @@ int lustre_end_log(struct super_block *sb, char *logname,
         int rc;
         ENTRY;
 
-        LASSERT(mgc);
+        if (!mgc)
+                RETURN(-ENOENT);
 
         /* mgc_process_config */
         lustre_cfg_bufs_reset(&bufs, mgc->obd_name);
@@ -441,7 +484,9 @@ static int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd,
         struct lustre_cfg    * lcfg = NULL;
         int rc;
                
-        CDEBUG(D_TRACE, "lcfg %s %#x %s %s %s %s\n", cfgname,
+
+        CDEBUG((cmd==LCFG_ADD_UUID)?D_WARNING:D_TRACE,
+               "lcfg %s %#x %s %s %s %s\n", cfgname,
                cmd, s1, s2, s3, s4); 
 
         lustre_cfg_bufs_reset(&bufs, cfgname);
@@ -548,8 +593,10 @@ static int lustre_start_mgc(struct super_block *sb)
         struct obd_uuid *uuid;
         class_uuid_t uuidc;
         lnet_nid_t nid;
+        char niduuid[10];
+        char *ptr;
         int recov_bk;
-        int rc = 0, i;
+        int rc = 0, i = 0, j;
         ENTRY;
 
         LASSERT(lsi->lsi_lmd);
@@ -576,63 +623,84 @@ static int lustre_start_mgc(struct super_block *sb)
                 GOTO(out, rc = 0);
         }
 
-        if (lsi->lsi_lmd->lmd_mgsnid_count == 0) {
-                LCONSOLE_ERROR("No NIDs for the MGS were given.\n");
-                RETURN(-EINVAL);
-        }
-
         CDEBUG(D_MOUNT, "Start MGC '%s'\n", LUSTRE_MGC_OBDNAME);
 
-        /* Add the first uuid for the MGS */
-        nid = lsi->lsi_lmd->lmd_mgsnid[0];
-        rc = do_lcfg(LUSTRE_MGC_OBDNAME, nid, LCFG_ADD_UUID, 
-                     libcfs_nid2str(nid), 0,0,0);
-        if (rc < 0)
-                RETURN(rc);
+        /* Add the primary nids for the MGS */
+        if (lsi->lsi_flags & LSI_SERVER) {
+                ptr = lsi->lsi_ldd->ldd_params;
+                if (IS_MGS(lsi->lsi_ldd)) {
+                        /* Use local nids (including LO) */
+                        lnet_process_id_t id;
+                        while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
+                                rc = do_lcfg(LUSTRE_MGC_OBDNAME, id.nid,
+                                             LCFG_ADD_UUID, "mgsnid0", 0,0,0);
+                        }
+                } else {
+                        /* Use mgsnode= nids */
+                        if (class_find_param(ptr, PARAM_MGSNODE, &ptr) != 0) {
+                                CERROR("No MGS nids given.\n");
+                                RETURN(-EINVAL);
+                        }
+                        while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                                rc = do_lcfg(LUSTRE_MGC_OBDNAME, nid,
+                                             LCFG_ADD_UUID, "mgsnid0", 0,0,0);
+                                i++;
+                        }
+                }
+        } else { /* client */
+                /* use nids from mount line: uml1,1@elan:uml2,2@elan:/lustre */
+                ptr = lsi->lsi_lmd->lmd_dev;
+                while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                        rc = do_lcfg(LUSTRE_MGC_OBDNAME, nid,
+                                     LCFG_ADD_UUID, "mgsnid0", 0,0,0);
+                        i++;
+                        if (*ptr == ':') 
+                                break;
+                }
+        }
+        if (i == 0) {
+                CERROR("No valid MGS nids found.\n");
+                RETURN(-EINVAL);
+        }
+        lsi->lsi_lmd->lmd_mgs_failnodes = 1;
 
-        /* Generate a unique uuid for each MGC */
+        /* Random uuid for MGC allows easier reconnects */
         OBD_ALLOC_PTR(uuid);
-#if 0
-        /* use the 1st non-loopback nid */
-        lnet_process_id_t id;
-        i = 0;
-        while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
-                if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND) 
-                        continue;
-                break;
-        }
-        sprintf(uuid->uuid, "mgc_"LPX64, id.nid);
-#else
-        /* random makes reconnect easier */
         class_generate_random_uuid(uuidc);
         class_uuid_unparse(uuidc, uuid);
-#endif        
-        CDEBUG(D_MOUNT, "generated uuid: %s\n", uuid->uuid);
 
         /* Start the MGC */
         rc = lustre_start_simple(LUSTRE_MGC_OBDNAME, LUSTRE_MGC_NAME, 
                                  (char *)uuid->uuid, LUSTRE_MGS_OBDNAME,
-                                 libcfs_nid2str(nid));
+                                 "mgsnid0");
         OBD_FREE_PTR(uuid);
         if (rc) 
                 RETURN(rc);
         
-        /* Add the redundant MGS nids */
-        for (i = 1; i < lsi->lsi_lmd->lmd_mgsnid_count; i++) {
-                nid = lsi->lsi_lmd->lmd_mgsnid[i];
-                rc = do_lcfg(LUSTRE_MGC_OBDNAME, nid, LCFG_ADD_UUID, 
-                             libcfs_nid2str(nid), 0, 0, 0);
-                if (rc) {
-                        CERROR("Add uuid for %s failed %d\n", 
-                               libcfs_nid2str(nid), rc);
-                        continue;
+        /* Add any failover MGS nids */
+        i = 1;
+        while ((*ptr == ':' || 
+                class_find_param(ptr, PARAM_MGSNODE, &ptr) == 0)) {
+                /* New failover node */
+                sprintf(niduuid, "mgsnid%d", i);
+                j = 0;
+                while (class_parse_nid(ptr, &nid, &ptr) == 0) {
+                        j++;
+                        rc = do_lcfg(LUSTRE_MGC_OBDNAME, nid,
+                                     LCFG_ADD_UUID, niduuid, 0,0,0);
+                        if (*ptr == ':') 
+                                break;
+                }
+                if (j > 0) {
+                        rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_ADD_CONN,
+                                     niduuid, 0, 0, 0);
+                        i++;
+                } else {
+                        /* at ":/fsname" */
+                        break;
                 }
-                rc = do_lcfg(LUSTRE_MGC_OBDNAME, 0, LCFG_ADD_CONN,
-                             libcfs_nid2str(nid), 0, 0, 0);
-                if (rc) 
-                        CERROR("Add conn for %s failed %d\n", 
-                               libcfs_nid2str(nid), rc);
         }
+        lsi->lsi_lmd->lmd_mgs_failnodes = i;
         
         obd = class_name2obd(LUSTRE_MGC_OBDNAME);
         if (!obd) {
@@ -677,7 +745,7 @@ static int lustre_stop_mgc(struct super_block *sb)
 {
         struct lustre_sb_info *lsi = s2lsi(sb);
         struct obd_device *obd;
-        lnet_nid_t nid;
+        char niduuid[10];
         int i, rc;
         ENTRY;
 
@@ -710,15 +778,13 @@ static int lustre_stop_mgc(struct super_block *sb)
         if (rc)
                 RETURN(rc);
         
-        /* class_add_uuid adds a nid even if the same uuid exists; we might
-           delete any copy here.  So they all better match. */
-        for (i = 0; i < lsi->lsi_lmd->lmd_mgsnid_count; i++) {
-                nid = lsi->lsi_lmd->lmd_mgsnid[i];
-                rc = do_lcfg(obd->obd_name, nid, LCFG_DEL_UUID, 
-                              libcfs_nid2str(nid), 0, 0, 0);
+        for (i = 0; i < lsi->lsi_lmd->lmd_mgs_failnodes; i++) {
+                sprintf(niduuid, "mgsnid%d", i);
+                rc = do_lcfg(obd->obd_name, 0, LCFG_DEL_UUID, 
+                             niduuid, 0, 0, 0);
                 if (rc)
                         CERROR("del MDC UUID %s failed: rc = %d\n", 
-                               libcfs_nid2str(nid), rc);
+                               niduuid, rc);
         }
         /* class_import_put will get rid of the additional connections */
 
@@ -809,8 +875,6 @@ static int server_sb2mti(struct super_block *sb, struct mgs_target_info *mti)
         int i = 0;
         ENTRY;
 
-        if (!mti) 
-                RETURN(-ENOMEM);
         if (!(lsi->lsi_flags & LSI_SERVER))
                 RETURN(-EINVAL);
 
@@ -832,14 +896,16 @@ static int server_sb2mti(struct super_block *sb, struct mgs_target_info *mti)
                 }
         }    
 
-        mti->mti_failnid_count = ldd->ldd_failnid_count;
-        memcpy(mti->mti_failnids, ldd->ldd_failnid, sizeof(mti->mti_failnids));
-        memcpy(mti->mti_failnodes, ldd->ldd_failnode, 
-               sizeof(mti->mti_failnodes));
-        memcpy(mti->mti_uuid, ldd->ldd_uuid, sizeof(mti->mti_uuid));
         mti->mti_config_ver = 0;
         mti->mti_flags = ldd->ldd_flags;
         mti->mti_stripe_index = ldd->ldd_svindex;
+        memcpy(mti->mti_uuid, ldd->ldd_uuid, sizeof(mti->mti_uuid));
+        if (strlen(ldd->ldd_params) > sizeof(mti->mti_params)) {
+                CERROR("params too big for mti\n");
+                RETURN(-ENOMEM);
+                /* FIXME we can't send a msg much bigger than 4k - use bulk? */
+        }
+        memcpy(mti->mti_params, ldd->ldd_params, sizeof(mti->mti_params));
         RETURN(0);
 }
 
@@ -860,6 +926,8 @@ int server_register_target(struct super_block *sb)
                 RETURN(-EINVAL);
 
         OBD_ALLOC_PTR(mti);
+        if (!mti) 
+                RETURN(-ENOMEM);
         rc = server_sb2mti(sb, mti);
         if (rc) 
                 GOTO(out, rc);
@@ -1343,7 +1411,7 @@ static int server_fill_super(struct super_block *sb)
 {
         struct lustre_sb_info *lsi = s2lsi(sb);
         struct vfsmount *mnt;
-        int mgs_service = 0, i = 0, rc;
+        int rc;
         ENTRY;
 
         /* the One True Mount */
@@ -1370,32 +1438,12 @@ static int server_fill_super(struct super_block *sb)
                 GOTO(out, rc = -EALREADY);
         }
 
-        /* append on-disk MGS nids to mount-line MGS nids */
-        for (i = 0; (i < lsi->lsi_ldd->ldd_mgsnid_count) && 
-              (lsi->lsi_lmd->lmd_mgsnid_count < MTI_NIDS_MAX); i++) {
-                lsi->lsi_lmd->lmd_mgsnid[lsi->lsi_lmd->lmd_mgsnid_count++] = 
-                        lsi->lsi_ldd->ldd_mgsnid[i];
-        }
-
         /* start MGS before MGC */
         if (IS_MGS(lsi->lsi_ldd)) {
                 rc = server_start_mgs(sb);
                 if (rc) {
                         CERROR("ignoring Failed MGS start!!\n");
                         //GOTO(out_mnt, rc);
-                } else {
-                        /* add local nids (including LO) to MGS nids */
-                        lnet_process_id_t id;
-                        int j = lsi->lsi_lmd->lmd_mgsnid_count;
-                        i = 0;
-                        while ((rc = LNetGetId(i++, &id)) != -ENOENT) {
-                                if (j >= MTI_NIDS_MAX) 
-                                        break;
-                                lsi->lsi_lmd->lmd_mgsnid[j++] = id.nid;
-                        }     
-                        lsi->lsi_lmd->lmd_mgsnid_count = j;
-
-                        mgs_service++;
                 }
         }
 
@@ -1489,16 +1537,9 @@ static void lmd_print(struct lustre_mount_data *lmd)
         int i;
 
         PRINT_CMD(PRINT_MASK, "  mount data:\n"); 
-        if (!lmd->lmd_mgsnid_count) 
-                PRINT_CMD(PRINT_MASK, "no MGS nids\n");
-        else for (i = 0; i < lmd->lmd_mgsnid_count; i++) {
-                PRINT_CMD(PRINT_MASK, "nid %d:  %s\n", i, 
-                       libcfs_nid2str(lmd->lmd_mgsnid[i]));
-        }
         if (lmd_is_client(lmd)) 
-                PRINT_CMD(PRINT_MASK, "fsname:  %s\n", lmd->lmd_dev);
-        else
-                PRINT_CMD(PRINT_MASK, "device:  %s\n", lmd->lmd_dev);
+                PRINT_CMD(PRINT_MASK, "fsname:  %s\n", lmd->lmd_fs);
+        PRINT_CMD(PRINT_MASK, "device:  %s\n", lmd->lmd_dev);
         PRINT_CMD(PRINT_MASK, "flags:   %x\n", lmd->lmd_flags);
         if (lmd->lmd_opts)
                 PRINT_CMD(PRINT_MASK, "options: %s\n", lmd->lmd_opts);
@@ -1522,7 +1563,7 @@ int lustre_check_exclusion(struct super_block *sb, char *svname)
                 RETURN(0);
 
         CDEBUG(D_MOUNT, "Check exclusion %s (%d) in %d of %s\n", svname, 
-               index, lmd->lmd_exclude_count, lmd->lmd_dev);
+               index, lmd->lmd_exclude_count, lmd->lmd_fs);
         
         for(i = 0; i < lmd->lmd_exclude_count; i++) {
                 if (index == lmd->lmd_exclude[i]) {
@@ -1642,6 +1683,7 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                         /* terminate options right before device.  device
                            must be the last one. */
                         *s1 = 0;
+                        break;
                 }
 
                 /* Find next opt */
@@ -1657,46 +1699,21 @@ static int lmd_parse(char *options, struct lustre_mount_data *lmd)
                 goto invalid;
         }
 
-        if (strchr(devname, ',')) {
-                LCONSOLE_ERROR("Device name must be the final option\n");
-                goto invalid;
-        }
-
-        s1 = devname;
-        /* Get MGS nids if client mount:  uml1@tcp:uml2@tcp:/fsname-client */
-        while ((s2 = strchr(s1, ':'))) {
-                lnet_nid_t nid;
-                *s2 = 0;
+        s1 = strrchr(devname, ':');
+        if (s1) {
                 lmd->lmd_flags = LMD_FLG_CLIENT;
-                nid = libcfs_str2nid(s1);
-                if (nid == LNET_NID_ANY) {
-                        LCONSOLE_ERROR("Can't parse NID '%s'\n", s1);
-                        goto invalid;
-                }
-                if (lmd->lmd_mgsnid_count >= MTI_NIDS_MAX) {
-                        LCONSOLE_ERROR("Too many NIDs: '%s'\n", s1);
-                        goto invalid;
-                }
-                lmd->lmd_mgsnid[lmd->lmd_mgsnid_count++] = nid;
-                s1 = s2 + 1;
-        }
-
-        if (lmd_is_client(lmd)) {
                 /* Remove leading /s from fsname */
-                while (*++s1 == '/')
-                        ;
-        }
-
-        if (*s1 == 0) {
-                LCONSOLE_ERROR("No filesytem specified\n");
-                goto invalid;
-        }
+                while (*++s1 == '/') ;
+        } else
+                s1 = devname;
 
         /* freed in lustre_free_lsi */
-        OBD_ALLOC(lmd->lmd_dev, strlen(s1) + 1);
+        OBD_ALLOC(lmd->lmd_dev, strlen(devname) + 1);
         if (!lmd->lmd_dev) 
                 RETURN(-ENOMEM);
-        strcpy(lmd->lmd_dev, s1);
+        strcpy(lmd->lmd_dev, devname);
+        /* fsname is last part of devname for clients (mgsnid:/fsname) */
+        lmd->lmd_fs = lmd->lmd_dev + (s1 - devname);
         
         /* save mount options */
         s1 = options + strlen(options) - 1;
@@ -1743,11 +1760,11 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
         }
 
         if (lmd_is_client(lmd)) {
-                CDEBUG(D_MOUNT, "Mounting client for fs %s\n", lmd->lmd_dev);
+                CDEBUG(D_MOUNT, "Mounting client for fs %s\n", lmd->lmd_fs);
                 if (!client_fill_super) {
                         LCONSOLE_ERROR("Nothing registered for client mount!"
                                " Is llite module loaded?\n");
-                        rc = -ENOSYS;
+                        rc = -ENODEV;
                 } else {
                         rc = lustre_start_mgc(sb);
                         if (rc) 
@@ -1773,7 +1790,7 @@ out:
                 CERROR("Unable to mount %s\n", 
                        s2lsi(sb) ? lmd->lmd_dev : "");
         } else {
-                CDEBUG(D_MOUNT, "Successfully mounted %s\n", lmd->lmd_dev);
+                CDEBUG(D_MOUNT, "Successfully mounted %s\n", lmd->lmd_fs);
         }
         RETURN(rc);
 } 
@@ -1848,6 +1865,7 @@ EXPORT_SYMBOL(server_put_mount);
 EXPORT_SYMBOL(server_register_target);
 EXPORT_SYMBOL(server_name2index);
 EXPORT_SYMBOL(server_mti_print);
-
+EXPORT_SYMBOL(class_find_param);
+EXPORT_SYMBOL(class_parse_nid);
 
 
index d2cfce5..896e928 100644 (file)
@@ -408,7 +408,7 @@ void *lustre_msg_buf(struct lustre_msg *m, int n, int min_size)
 
         bufcount = m->bufcount;
         if (n >= bufcount) {
-                CDEBUG(D_INFO, "msg %p buffer[%d] not present (count %d)\n",
+                CERROR("msg %p buffer[%d] not present (count %d)\n",
                        m, n, bufcount);
                 return NULL;
         }
index 9fe657d..1c77b0a 100644 (file)
@@ -40,6 +40,7 @@
 #define NO_SYS_VFS 1
 #include <linux/fs.h> // for BLKGETSIZE64
 #include <linux/lustre_disk.h>
+#include <linux/lustre_param.h>
 #include <lnet/lnetctl.h>
 #include <linux/lustre_ver.h>
 #include "obdctl.h"
@@ -512,7 +513,6 @@ out:
 
 void print_ldd(char *str, struct lustre_disk_data *ldd)
 {
-        int i = 0, j= 0;
         printf("\n   %s:\n", str);
         printf("Target:     %s\n", ldd->ldd_svname);
         if (ldd->ldd_svindex == INDEX_UNASSIGNED) 
@@ -533,27 +533,7 @@ void print_ldd(char *str, struct lustre_disk_data *ldd)
                ldd->ldd_flags & LDD_F_WRITECONF  ? "writeconf ":"",
                ldd->ldd_flags & LDD_F_UPGRADE14  ? "upgrade1.4 ":"");
         printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts);
-        printf("MGS");
-        j = 0;
-        for (i = 0; i < ldd->ldd_mgsnid_count; i++) {
-                if (i == 0 || i == ldd->ldd_mgsnode[j]) {
-                        if (i) 
-                                j++;
-                        printf("\n    node %d:", j + 1);
-                }
-                printf(" %s", libcfs_nid2str(ldd->ldd_mgsnid[i]));
-        }
-        printf("\nFailover");
-        j = 0;
-        for (i = 0; i < ldd->ldd_failnid_count; i++) {
-                if (i == 0 || i == ldd->ldd_failnode[j]) {
-                        if (i) 
-                                j++;
-                        printf("\n    node %d:", j + 1);
-                }
-                printf(" %s", libcfs_nid2str(ldd->ldd_failnid[i]));
-        }
-
+        printf("Parameters:%s\n", ldd->ldd_params);
         printf("\n");
 }
 
@@ -581,6 +561,10 @@ int write_local_files(struct mkfs_opts *mop)
         if (ret) {
                 fprintf(stderr, "%s: Unable to mount %s: %s\n", 
                         progname, dev, strerror(errno));
+                if (errno == ENODEV) {
+                        fprintf(stderr, "Is the %s module available?\n", 
+                                MT_STR(&mop->mo_ldd));
+                }
                 goto out_rmdir;
         }
 
@@ -792,7 +776,7 @@ void set_defaults(struct mkfs_opts *mop)
         mop->mo_ldd.ldd_magic = LDD_MAGIC;
         mop->mo_ldd.ldd_config_ver = 1;
         mop->mo_ldd.ldd_flags = LDD_F_NEED_INDEX | LDD_F_UPDATE | LDD_F_VIRGIN;
-        mop->mo_ldd.ldd_mgsnid_count = 0;
+        mop->mo_mgs_failnodes = 0;
         strcpy(mop->mo_ldd.ldd_fsname, "lustre");
         if (get_os_version() == 24) 
                 mop->mo_ldd.ldd_mount_type = LDD_MT_EXT3;
@@ -810,50 +794,60 @@ static inline void badopt(const char *opt, char *type)
         usage(stderr);
 }
 
-
-static int parse_nids(int first_spec, char *buf, __u16 *count,
-                      lnet_nid_t *nids, __u16 *nodes)
-{                                                 
-        int j, i = *count;
-        char *s1 = buf, *s2;
-
-        if (first_spec == 1) {
-                /* for the first nid spec in a tunefs, we erase all old nid
-                   info */
-                *count = 0; i = 0;
-                for (j = 0; j < 8; j++) 
-                        nodes[j] = 0;
+static int add_param(char *buf, char *key, char *val)
+{
+        int end = sizeof(((struct lustre_disk_data *)0)->ldd_params);
+        int start = strlen(buf);
+        int keylen = 0;
+
+        if (key) 
+                keylen = strlen(key);
+        if (start + 1 + keylen + strlen(val) >= end) {
+                fprintf(stderr, "%s: params are too long-\n%s %s%s\n",
+                        progname, buf, key ? key : "", val);
+                return 1;
         }
 
-        while ((s2 = strsep(&s1, ","))) {
-                nids[i] = libcfs_str2nid(s2);
-                if (nids[i] == LNET_NID_ANY) {
-                        fprintf(stderr, "%s: malformed nid %s\n", 
+        sprintf(buf + start, " %s%s", key ? key : "", val);
+        return 0;
+}
+
+/* from mount_lustre */
+/* Get rid of symbolic hostnames for tcp, since kernel can't do lookups */
+#define MAXNIDSTR 1024
+static char *convert_hostnames(char *s1)
+{
+        char *converted, *s2 = 0, *c;
+        int left = MAXNIDSTR;
+        lnet_nid_t nid;
+        
+        converted = malloc(left);
+        c = converted;
+        while ((left > 0) && ((s2 = strsep(&s1, ",: \0")))) {
+                nid = libcfs_str2nid(s2);
+                if (nid == LNET_NID_ANY) {
+                        if (*s2 == '/') 
+                                /* end of nids */
+                                break;
+                        fprintf(stderr, "%s: Can't parse NID '%s'\n", 
                                 progname, s2);
-                        return 1;
+                        free(converted);
+                        return NULL;
                 }
-                i++;
-                if (i >= MTI_NIDS_MAX) {
-                        fprintf(stderr, "%s: too many nids (%s...)\n", 
-                                progname, s1);
-                        return 1;
+                if (LNET_NETTYP(LNET_NIDNET(nid)) == SOCKLND) {
+                        __u32 addr = LNET_NIDADDR(nid);
+                        c += snprintf(c, left, "%u.%u.%u.%u@%s%u,",
+                                      (addr >> 24) & 0xff, (addr >> 16) & 0xff,
+                                      (addr >> 8) & 0xff, addr & 0xff,
+                                      libcfs_lnd2str(SOCKLND), 
+                                      LNET_NETNUM(LNET_NIDNET(nid)));
+                } else {
+                        c += snprintf(c, left, "%s,", s2);
                 }
+                left = converted + MAXNIDSTR - c;
         }
-        if (i == *count) 
-                return 0;
-
-        /* mark the last nid index in the node array */
-        j = 0;
-        while (nodes[j] && (j < 8)) 
-                j++;
-        if (j >= 8) {
-                fprintf(stderr, "%s: too many nodes (%s...)\n", 
-                        progname, buf);
-                return 1;
-        }
-        *count = i;
-        nodes[j] = i;
-        return 0;
+        *(c - 1) = '\0';
+        return converted;
 }
 
 int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
@@ -864,6 +858,7 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                 {"stripe-count-hint", 1, 0, 'c'},
                 {"configdev", 1, 0, 'C'},
                 {"device-size", 1, 0, 'd'},
+                {"erase-params", 0, 0, 'e'},
                 {"failnode", 1, 0, 'f'},
                 {"failover", 1, 0, 'f'},
                 {"mgs", 0, 0, 'G'},
@@ -877,16 +872,17 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                 {"nomgs", 0, 0, 'N'},
                 {"mountfsoptions", 1, 0, 'o'},
                 {"ost", 0, 0, 'O'},
-                {"print", 0, 0, 'p'},
+                {"param", 1, 0, 'p'},
+                {"print", 0, 0, 'P'},
                 {"quiet", 0, 0, 'q'},
                 {"reformat", 0, 0, 'r'},
                 {"verbose", 0, 0, 'v'},
                 {"writeconf", 0, 0, 'w'},
                 {0, 0, 0, 0}
         };
-        char *optstring = "b:c:C:d:f:Ghi:k:m:Mn:No:Opqrvw";
+        char *optstring = "b:c:C:d:ef:Ghi:k:m:Mn:No:Op:Pqrvw";
         char opt;
-        int longidx;
+        int rc, longidx;
 
         while ((opt = getopt_long(argc, argv, optstring, long_opt, &longidx)) != 
                EOF) {
@@ -923,20 +919,18 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                 case 'd':
                         mop->mo_device_sz = atol(optarg); 
                         break;
+                case 'e':
+                        mop->mo_ldd.ldd_params[0] = '\0';
+                        break;
                 case 'f': {
-                        int rc;
-                        static int first_fail_spec = 1;
-                        rc = parse_nids(first_fail_spec, optarg, 
-                                        &mop->mo_ldd.ldd_failnid_count,
-                                        mop->mo_ldd.ldd_failnid,
-                                        mop->mo_ldd.ldd_failnode);
-                        if (rc) {
-                                fprintf(stderr, "%s: bad failover nids\n",
-                                        progname);
+                        char *nids = convert_hostnames(optarg);
+                        if (!nids) 
                                 return 1;
-                        }
-                        mop->mo_ldd.ldd_flags |= LDD_F_UPDATE;
-                        first_fail_spec++;
+                        rc = add_param(mop->mo_ldd.ldd_params, PARAM_FAILNODE, 
+                                       nids); 
+                        free(nids);
+                        if (rc) 
+                                return rc;
                         break;
                 }
                 case 'G':
@@ -959,23 +953,15 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                                 sizeof(mop->mo_mkfsopts) - 1);
                         break;
                 case 'm': {
-                        int rc;
-                        static int first_mgs_spec = 1;
-                        if (IS_MGS(&mop->mo_ldd)) {
-                                badopt(long_opt[longidx].name, 
-                                       "non-MGS MDT,OST");
+                        char *nids = convert_hostnames(optarg);
+                        if (!nids) 
                                 return 1;
-                        }
-                        rc = parse_nids(first_mgs_spec, optarg, 
-                                        &mop->mo_ldd.ldd_mgsnid_count,
-                                        mop->mo_ldd.ldd_mgsnid,
-                                        mop->mo_ldd.ldd_mgsnode);
-                        if (rc) {
-                                fprintf(stderr, "%s: bad MGS nids\n",
-                                        progname);
-                                return 1;
-                        }
-                        first_mgs_spec++;
+                        rc = add_param(mop->mo_ldd.ldd_params, PARAM_MGSNODE, 
+                                       nids); 
+                        free(nids);
+                        if (rc) 
+                                return rc;
+                        mop->mo_mgs_failnodes++;
                         break;
                 }
                 case 'M':
@@ -1005,6 +991,11 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                         mop->mo_ldd.ldd_flags |= LDD_F_SV_TYPE_OST;
                         break;
                 case 'p':
+                        rc = add_param(mop->mo_ldd.ldd_params, NULL, optarg);
+                        if (rc) 
+                                return rc;
+                        break;
+                case 'P':
                         print_only++;
                         break;
                 case 'q':
@@ -1047,7 +1038,8 @@ int main(int argc, char *const argv[])
         char default_mountopts[512] = "";
         int  ret = 0;
 
-        assert(offsetof(struct lustre_disk_data, ldd_padding) == 1260);
+        //printf("pad %d\n", offsetof(struct lustre_disk_data, ldd_padding));
+        assert(offsetof(struct lustre_disk_data, ldd_padding) == 200);
         
         if ((progname = strrchr(argv[0], '/')) != NULL)
                 progname++;
@@ -1122,15 +1114,15 @@ int main(int argc, char *const argv[])
                 goto out;
         }
 
-        if (IS_MDT(ldd) && !IS_MGS(ldd) && ldd->ldd_mgsnid_count == 0) {
+        if (IS_MDT(ldd) && !IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) {
                 vprint("No management node specified, adding MGS to this "
                        "MDT\n");
                 ldd->ldd_flags |= LDD_F_SV_TYPE_MGS;
         }
 
-        if (!IS_MGS(ldd) && (ldd->ldd_mgsnid_count == 0)) {
+        if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) {
                 fatal();
-                fprintf(stderr, "Must specify either --mgs or --mgsnid\n");
+                fprintf(stderr, "Must specify either --mgs or --mgsnode\n");
                 usage(stderr);
                 goto out;
         }
index 2742a16..ca2a5ab 100644 (file)
@@ -131,36 +131,40 @@ update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
 static char *convert_hostnames(char *s1)
 {
         char *converted, *s2 = 0, *c;
+        char sep;
         int left = MAXNIDSTR;
         lnet_nid_t nid;
         
         converted = malloc(left);
         c = converted;
-        while ((left > 0) && ((s2 = strsep(&s1, ",:")))) {
-                nid = libcfs_str2nid(s2);
-                if (nid == LNET_NID_ANY) {
-                        if (*s2 == '/') 
-                                /* end of nids */
-                                break;
-                        fprintf(stderr, "%s: Can't parse NID '%s'\n", 
-                                progname, s2);
-                        free(converted);
-                        return NULL;
-                }
+        while ((left > 0) && (*s1 != '/')) {
+                s2 = strpbrk(s1, ",:");
+                if (!s2)
+                        goto out_free;
+                sep = *s2;
+                *s2 = '\0';     
+                nid = libcfs_str2nid(s1);
+                if (nid == LNET_NID_ANY)
+                        goto out_free;
                 if (LNET_NETTYP(LNET_NIDNET(nid)) == SOCKLND) {
                         __u32 addr = LNET_NIDADDR(nid);
-                        c += snprintf(c, left, "%u.%u.%u.%u@%s%u:",
+                        c += snprintf(c, left, "%u.%u.%u.%u@%s%u%c",
                                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,
                                       (addr >> 8) & 0xff, addr & 0xff,
                                       libcfs_lnd2str(SOCKLND), 
-                                      LNET_NETNUM(LNET_NIDNET(nid)));
+                                      LNET_NETNUM(LNET_NIDNET(nid)), sep);
                 } else {
-                        c += snprintf(converted, left, "%s:", s2);
+                        c += snprintf(c, left, "%s%c", s1, sep);
                 }
                 left = converted + MAXNIDSTR - c;
+                s1 = s2 + 1;
         }
-        snprintf(c, left, "%s", s2);
+        snprintf(c, left, "%s", s1);
         return converted;
+out_free:
+        fprintf(stderr, "%s: Can't parse NID '%s'\n", progname, s1);
+        free(converted);
+        return NULL;
 }
 
 /*****************************************************************************
@@ -374,7 +378,12 @@ int main(int argc, char *const argv[])
                 if (errno == ENODEV)
                         fprintf(stderr, "Are the lustre modules loaded?\n"
                              "Check /etc/modules.conf and /proc/filesystems\n");
-                rc = 32;
+                if (errno == ENOTBLK)
+                        fprintf(stderr,"Does this filesystem have any OSTs?\n");
+                if (errno == ENOENT)
+                        fprintf(stderr,"Is the mgs specification correct? "
+                                "(%s)\n", source);
+                rc = errno;
         } else if (!nomtab) {
                 rc = update_mtab_entry(source, target, "lustre", options,0,0,0);
         }