Whamcloud - gitweb
b=22078 Bind ost/mdt to specific nids
[fs/lustre-release.git] / lustre / utils / mkfs_lustre.c
index 95f7260..f3e0b55 100644 (file)
@@ -26,7 +26,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright  2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  */
 /*
@@ -62,6 +62,7 @@
 #include <string.h>
 #include <getopt.h>
 #include <limits.h>
+#include <ctype.h>
 
 #ifdef __linux__
 /* libcfs.h is not really needed here, but on SLES10/PPC, fs.h includes idr.h which
@@ -129,6 +130,7 @@ void usage(FILE *out)
                 */
                 "\t\t--comment=<user comment>: arbitrary user string (%d bytes)\n"
                 "\t\t--mountfsoptions=<opts> : permanent mount options\n"
+                "\t\t--network=<net>[,<...>] : network(s) to restrict this ost/mdt to\n"
 #ifndef TUNEFS
                 "\t\t--backfstype=<fstype> : backing fs type (ext3, ldiskfs)\n"
                 "\t\t--device-size=#N(KB) : device size for loop devices\n"
@@ -525,7 +527,13 @@ static void enable_default_backfs_features(struct mkfs_opts *mop)
         int maj_high, maj_low, min;
         int ret;
 
-        strscat(mop->mo_mkfsopts, " -O dir_index,extents", sizeof(mop->mo_mkfsopts));
+        if (IS_MDT(&mop->mo_ldd))
+                strscat(mop->mo_mkfsopts, " -O dir_index,extents,dirdata",
+                                sizeof(mop->mo_mkfsopts));
+        else
+                strscat(mop->mo_mkfsopts, " -O dir_index,extents",
+                                sizeof(mop->mo_mkfsopts));
+
 
         /* Upstream e2fsprogs called our uninit_groups feature uninit_bg,
          * check for both of them when testing e2fsprogs features. */
@@ -563,11 +571,24 @@ static void enable_default_backfs_features(struct mkfs_opts *mop)
 /* Build fs according to type */
 int make_lustre_backfs(struct mkfs_opts *mop)
 {
+        __u64 device_sz = mop->mo_device_sz, block_count = 0;
         char mkfs_cmd[PATH_MAX];
         char buf[64];
         char *dev;
         int ret = 0;
-        int block_count = 0;
+
+        if (!(mop->mo_flags & MO_IS_LOOP)) {
+                mop->mo_device_sz = get_device_size(mop->mo_device);
+
+                if (mop->mo_device_sz == 0)
+                        return ENODEV;
+
+                /* Compare to real size */
+                if (device_sz == 0 || device_sz > mop->mo_device_sz)
+                        device_sz = mop->mo_device_sz;
+                else
+                        mop->mo_device_sz = device_sz;
+        }
 
         if (mop->mo_device_sz != 0) {
                 if (mop->mo_device_sz < 8096){
@@ -582,15 +603,6 @@ int make_lustre_backfs(struct mkfs_opts *mop)
         if ((mop->mo_ldd.ldd_mount_type == LDD_MT_EXT3) ||
             (mop->mo_ldd.ldd_mount_type == LDD_MT_LDISKFS) ||
             (mop->mo_ldd.ldd_mount_type == LDD_MT_LDISKFS2)) {
-                __u64 device_sz = mop->mo_device_sz;
-
-                /* we really need the size */
-                if (device_sz == 0) {
-                        device_sz = get_device_size(mop->mo_device);
-                        if (device_sz == 0)
-                                return ENODEV;
-                }
-
                 /* Journal size in MB */
                 if (strstr(mop->mo_mkfsopts, "-J") == NULL) {
                         /* Choose our own default journal size */
@@ -698,7 +710,7 @@ int make_lustre_backfs(struct mkfs_opts *mop)
         vprint("formatting backing filesystem %s on %s\n",
                MT_STR(&mop->mo_ldd), dev);
         vprint("\ttarget name  %s\n", mop->mo_ldd.ldd_svname);
-        vprint("\t4k blocks     %d\n", block_count);
+        vprint("\t4k blocks     "LPU64"\n", block_count);
         vprint("\toptions       %s\n", mop->mo_mkfsopts);
 
         /* mkfs_cmd's trailing space is important! */
@@ -706,7 +718,7 @@ int make_lustre_backfs(struct mkfs_opts *mop)
         strscat(mkfs_cmd, " ", sizeof(mkfs_cmd));
         strscat(mkfs_cmd, dev, sizeof(mkfs_cmd));
         if (block_count != 0) {
-                sprintf(buf, " %d", block_count);
+                sprintf(buf, " "LPU64, block_count);
                 strscat(mkfs_cmd, buf, sizeof(mkfs_cmd));
         }
 
@@ -833,7 +845,8 @@ int write_local_files(struct mkfs_opts *mop)
         if (mop->mo_flags & MO_IS_LOOP)
                 dev = mop->mo_loopdev;
 
-        ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0, NULL);
+        ret = mount(dev, mntpt, MT_STR(&mop->mo_ldd), 0,
+                    mop->mo_ldd.ldd_mount_opts);
         if (ret) {
                 fprintf(stderr, "%s: Unable to mount %s: %s\n",
                         progname, dev, strerror(errno));
@@ -1212,6 +1225,7 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                 {"verbose", 0, 0, 'v'},
                 {"writeconf", 0, 0, 'w'},
                 {"upgrade_to_18", 0, 0, 'U'},
+                {"network", 1, 0, 't'},
                 {0, 0, 0, 0}
         };
         char *optstring = "b:c:C:d:ef:Ghi:k:L:m:MnNo:Op:Pqru:vw";
@@ -1367,6 +1381,22 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
                 case 'r':
                         mop->mo_flags |= MO_FORCEFORMAT;
                         break;
+                case 't':
+                        if (!IS_MDT(&mop->mo_ldd) && !IS_OST(&mop->mo_ldd)) {
+                                badopt(long_opt[longidx].name, "MDT,OST");
+                                return 1;
+                        }
+
+                        if (!optarg)
+                                return 1;
+
+                        rc = add_param(mop->mo_ldd.ldd_params,
+                                       PARAM_NETWORK, optarg);
+                        if (rc != 0)
+                                return rc;
+                        /* Must update the mgs logs */
+                        mop->mo_ldd.ldd_flags |= LDD_F_UPDATE;
+                        break;
                 case 'u':
                         strscpy(mop->mo_ldd.ldd_userdata, optarg,
                                 sizeof(mop->mo_ldd.ldd_userdata));
@@ -1403,6 +1433,76 @@ int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
         return 0;
 }
 
+/* Search for opt in mntlist, returning true if found.
+ */
+static int in_mntlist(char *opt, char *mntlist)
+{
+        char *ml, *mlp, *item, *ctx = NULL;
+
+        if (!(ml = strdup(mntlist))) {
+                fprintf(stderr, "%s: out of memory\n", progname);
+                exit(1);
+        }
+        mlp = ml;
+        while ((item = strtok_r(mlp, ",", &ctx))) {
+                if (!strcmp(opt, item))
+                        break;
+                mlp = NULL;
+        }
+        free(ml);
+        return (item != NULL);
+}
+
+/* Issue a message on stderr for every item in wanted_mountopts that is not
+ * present in mountopts.  The justwarn boolean toggles between error and
+ * warning message.  Return an error count.
+ */
+static int check_mountfsoptions(char *mountopts, char *wanted_mountopts,
+                                int justwarn)
+{
+        char *ml, *mlp, *item, *ctx = NULL;
+        int errors = 0;
+
+        if (!(ml = strdup(wanted_mountopts))) {
+                fprintf(stderr, "%s: out of memory\n", progname);
+                exit(1);
+        }
+        mlp = ml;
+        while ((item = strtok_r(mlp, ",", &ctx))) {
+                if (!in_mntlist(item, mountopts)) {
+                        fprintf(stderr, "%s: %s mount option `%s' is missing\n",
+                                progname, justwarn ? "Warning: default"
+                                : "Error: mandatory", item);
+                        errors++;
+                }
+                mlp = NULL;
+        }
+        free(ml);
+        return errors;
+}
+
+/* Trim embedded white space, leading and trailing commas from string s.
+ */
+static void trim_mountfsoptions(char *s)
+{
+        char *p;
+
+        for (p = s; *p; ) {
+                if (isspace(*p)) {
+                        memmove(p, p + 1, strlen(p + 1) + 1);
+                        continue;
+                }
+                p++;
+        }
+
+        while (s[0] == ',')
+                memmove(&s[0], &s[1], strlen(&s[1]) + 1);
+
+        p = s + strlen(s) - 1;
+        while (p >= s && *p == ',')
+                *p-- = '\0';
+}
+
 int main(int argc, char *const argv[])
 {
         struct mkfs_opts mop;
@@ -1517,7 +1617,8 @@ int main(int argc, char *const argv[])
         case LDD_MT_EXT3:
         case LDD_MT_LDISKFS:
         case LDD_MT_LDISKFS2: {
-                sprintf(always_mountopts, "errors=remount-ro");
+                strscat(default_mountopts, ",errors=remount-ro",
+                        sizeof(default_mountopts));
                 if (IS_MDT(ldd) || IS_MGS(ldd))
                         strscat(always_mountopts, ",iopen_nopriv,user_xattr",
                                 sizeof(always_mountopts));
@@ -1537,7 +1638,7 @@ int main(int argc, char *const argv[])
         }
         case LDD_MT_SMFS: {
                 mop.mo_flags |= MO_IS_LOOP;
-                sprintf(always_mountopts, "type=ext3,dev=%s",
+                sprintf(always_mountopts, ",type=ext3,dev=%s",
                         mop.mo_device);
                 break;
         }
@@ -1552,10 +1653,13 @@ int main(int argc, char *const argv[])
         }
 
         if (mountopts) {
-                /* If user specifies mount opts, don't use defaults,
-                   but always use always_mountopts */
-                sprintf(ldd->ldd_mount_opts, "%s,%s",
-                        always_mountopts, mountopts);
+                trim_mountfsoptions(mountopts);
+                (void)check_mountfsoptions(mountopts, default_mountopts, 1);
+                if (check_mountfsoptions(mountopts, always_mountopts, 0)) {
+                        ret = EINVAL;
+                        goto out;
+                }
+                sprintf(ldd->ldd_mount_opts, "%s", mountopts);
         } else {
 #ifdef TUNEFS
                 if (ldd->ldd_mount_opts[0] == 0)
@@ -1564,6 +1668,7 @@ int main(int argc, char *const argv[])
                 {
                         sprintf(ldd->ldd_mount_opts, "%s%s",
                                 always_mountopts, default_mountopts);
+                        trim_mountfsoptions(ldd->ldd_mount_opts);
                 }
         }