X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Fmkfs_lustre.c;h=5e70ed61bc72275cba051ac346a717de9d61de39;hp=070cb20379425c453a2a48f3e66688632fd21859;hb=7e0208da21f9358d96feebce5124f8587778c318;hpb=56e0d0bd401ba7dadb19e21dac624f6eb9cee3f7 diff --git a/lustre/utils/mkfs_lustre.c b/lustre/utils/mkfs_lustre.c index 070cb20..5e70ed6 100644 --- a/lustre/utils/mkfs_lustre.c +++ b/lustre/utils/mkfs_lustre.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Whamcloud, Inc. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -53,6 +49,7 @@ #include #include #include +#include #include #include @@ -63,645 +60,1040 @@ #include #include #include +#include +#include +#include +#include -#ifdef __linux__ -/* libcfs.h is not really needed here, but on SLES10/PPC, fs.h includes idr.h - * which requires BITS_PER_LONG to be defined */ -#include -#ifndef BLKGETSIZE64 -#include /* for BLKGETSIZE64 */ -#endif -#include -#endif -#include -#include -#include -#include #include "mount_utils.h" -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - char *progname; int verbose = 1; -static int print_only = 0; -static int upgrade_to_18 = 0; +int version; +static int print_only; + +#ifdef HAVE_LDISKFS_OSD +#define FSLIST_LDISKFS "ldiskfs" +#define HAVE_FSLIST +#else + #define FSLIST_LDISKFS "" +#endif /* HAVE_LDISKFS_OSD */ +#ifdef HAVE_ZFS_OSD + #ifdef HAVE_FSLIST + #define FSLIST_ZFS "|zfs" + #else + #define FSLIST_ZFS "zfs" + #define HAVE_FSLIST + #endif +#else + #define FSLIST_ZFS "" +#endif /* HAVE_ZFS_OSD */ + +#ifndef HAVE_FSLIST + #error "no backing OSD types (ldiskfs or ZFS) are configured" +#endif + +#define FSLIST FSLIST_LDISKFS FSLIST_ZFS void usage(FILE *out) { - fprintf(out, "%s v"LUSTRE_VERSION_STRING"\n", progname); - fprintf(out, "usage: %s [options] \n", progname); - fprintf(out, - "\t:block device or file (e.g /dev/sda or /tmp/ost1)\n" - "\ttarget types:\n" - "\t\t--ost: object storage, mutually exclusive with mdt,mgs\n" - "\t\t--mdt: metadata storage, mutually exclusive with ost\n" - "\t\t--mgs: configuration management service - one per site\n" - "\toptions (in order of popularity):\n" - "\t\t--mgsnode=[,<...>] : NID(s) of a remote mgs node\n" - "\t\t\trequired for all targets other than the mgs node\n" - "\t\t--fsname= : default is 'lustre'\n" - "\t\t--failnode=[,<...>] : NID(s) of a failover partner\n" - "\t\t\tcannot be used with --servicenode\n" - "\t\t--servicenode=[,<...>] : NID(s) of all service partners\n" - "\t\t\ttreat all nodes as equal service node, cannot be used with --failnode\n" - "\t\t--param = : set a permanent parameter\n" - "\t\t\te.g. --param sys.timeout=40\n" - "\t\t\t --param lov.stripesize=2M\n" - "\t\t--index=#N : target index (i.e. ost index within lov)\n" - "\t\t--comment=: arbitrary string (%d bytes)\n" - "\t\t--mountfsoptions= : permanent mount options\n" - "\t\t--network=[,<...>] : restrict OST/MDT to network(s)\n" + fprintf(out, "usage: %s [--backfstype="FSLIST"] " + "--fsname=\n" + "\t--index= [options] \n", progname); +#ifdef HAVE_ZFS_OSD + fprintf(out, "usage: %s --backfstype=zfs " + "--fsname= [options]\n" + "\t/\n" + "\t[[] [ ...] [vdev type>] ...]\n", + progname); +#endif + fprintf(out, + "\t:block device or file (e.g /dev/sda or /tmp/ost1)\n" +#ifdef HAVE_ZFS_OSD + "\t: name of ZFS pool where target is created " + "(e.g. tank)\n" + "\t: name of new dataset, must be unique within " + "pool (e.g. ost1)\n" + "\t: type of vdev (mirror, raidz, raidz2, spare, " + "cache, log)\n" +#endif + "\n" + "\ttarget types:\n" + "\t\t--mgs: configuration management service\n" + "\t\t--nomgs: turn off MGS service on this MDT\n" +#ifndef TUNEFS + "\t\t--mdt: metadata storage, mutually exclusive with ost\n" + "\t\t--ost: object storage, mutually exclusive with mdt, mgs\n" +#endif + "\toptions (in order of popularity):\n" + "\t\t--index=#N: numerical target index (0..N)\n" + "\t\t\trequired for all targets other than the MGS,\n" + "\t\t\ttarget index may either be a decimal number or\n" + "\t\t\thexadecimal number starting with '0x'\n" + "\t\t--fsname=<8_char_filesystem_name>: fs targets belong to\n" + "\t\t\trequired for all targets other than MGS\n" + "\t\t--mgsnode=[,<...>]: NID(s) of remote MGS\n" + "\t\t\trequired for all targets other than MGS\n" + "\t\t--mountfsoptions=: permanent Lustre mount options\n" + "\t\t--backfs-mount-opts=: backing fs mount options\n" + "\t\t--failnode=[,<...>]: NID(s) of backup failover node\n" + "\t\t\tmutually exclusive with --servicenode\n" + "\t\t--servicenode=[,<...>]: NID(s) of service partners\n" + "\t\t\ttreat nodes as equal service node, mutually exclusive " + "with --failnode\n" + "\t\t--param =: set a permanent parameter\n" + "\t\t\te.g. --param sys.timeout=40\n" + "\t\t\t --param lov.stripesize=2M\n" + "\t\t--network=[,<...>]: restrict OST/MDT to network(s)\n" #ifndef TUNEFS - "\t\t--backfstype= : backing fs type (ext3, ldiskfs)\n" - "\t\t--device-size=#N(KB) : device size for loop devices\n" - "\t\t--mkfsoptions= : format options\n" - "\t\t--reformat: overwrite an existing disk\n" - "\t\t--stripe-count-hint=#N : for optimizing MDT inode size\n" - "\t\t--iam-dir: use IAM directory format, not ext3 compatible\n" + "\t\t--backfstype=: backing fs type (ldiskfs, zfs)\n" + "\t\t--device-size=#N(KB): device size for loop devices\n" + "\t\t--mkfsoptions=: format options\n" + "\t\t--reformat: overwrite an existing disk\n" + "\t\t--replace: replace an old target with the same index\n" + "\t\t--stripe-count-hint=#N: for optimizing MDT inode size\n" #else - "\t\t--erase-params : erase all old parameter settings\n" - "\t\t--nomgs: turn off MGS service on this MDT\n" - "\t\t--writeconf: erase all config logs for this fs.\n" + "\t\t--erase-param : erase all instances of a parameter\n" + "\t\t--erase-params: erase all old parameter settings\n" + "\t\t--writeconf: erase all config logs for this fs.\n" + "\t\t--quota: enable space accounting on old 2.x device.\n" + "\t\t--rename: rename the filesystem name\n" #endif - "\t\t--dryrun: just report what we would do; " - "don't write to disk\n" - "\t\t--verbose : e.g. show mkfs progress\n" - "\t\t--quiet\n", - (int)sizeof(((struct lustre_disk_data *)0)->ldd_userdata)); - return; + "\t\t--comment=: arbitrary string (%d bytes)\n" + "\t\t--dryrun: report what we would do; don't write to disk\n" + "\t\t--verbose: e.g. show mkfs progress\n" + "\t\t--force-nohostid: Ignore hostid requirement for ZFS " + "import\n" + "\t\t-V|--version: output build version of the utility and\n" + "\t\t\texit\n" + "\t\t--quiet\n", + (int)sizeof(((struct lustre_disk_data *)0)->ldd_userdata)); } /* ==================== Lustre config functions =============*/ -void print_ldd(char *str, struct lustre_disk_data *ldd) +void print_ldd(char *str, struct mkfs_opts *mop) { - printf("\n %s:\n", str); - printf("Target: %s\n", ldd->ldd_svname); - if (ldd->ldd_svindex == INDEX_UNASSIGNED) - printf("Index: unassigned\n"); - else - printf("Index: %d\n", ldd->ldd_svindex); - if (ldd->ldd_uuid[0]) - printf("UUID: %s\n", (char *)ldd->ldd_uuid); - printf("Lustre FS: %s\n", ldd->ldd_fsname); - printf("Mount type: %s\n", MT_STR(ldd)); - printf("Flags: %#x\n", ldd->ldd_flags); - printf(" (%s%s%s%s%s%s%s%s%s%s)\n", - IS_MDT(ldd) ? "MDT ":"", - IS_OST(ldd) ? "OST ":"", - IS_MGS(ldd) ? "MGS ":"", - ldd->ldd_flags & LDD_F_NEED_INDEX ? "needs_index ":"", - ldd->ldd_flags & LDD_F_VIRGIN ? "first_time ":"", - ldd->ldd_flags & LDD_F_UPDATE ? "update ":"", - ldd->ldd_flags & LDD_F_WRITECONF ? "writeconf ":"", - ldd->ldd_flags & LDD_F_IAM_DIR ? "IAM_dir_format ":"", - ldd->ldd_flags & LDD_F_NO_PRIMNODE? "no_primnode ":"", - ldd->ldd_flags & LDD_F_UPGRADE14 ? "upgrade1.4 ":""); - printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts); - printf("Parameters:%s\n", ldd->ldd_params); - if (ldd->ldd_userdata[0]) - printf("Comment: %s\n", ldd->ldd_userdata); - printf("\n"); + struct lustre_disk_data *ldd = &mop->mo_ldd; + + printf("\n %s:\n", str); + printf("Target: %s\n", ldd->ldd_svname); + if (ldd->ldd_svindex == INDEX_UNASSIGNED) + printf("Index: unassigned\n"); + else + printf("Index: %d\n", ldd->ldd_svindex); + if (ldd->ldd_uuid[0]) + printf("UUID: %s\n", (char *)ldd->ldd_uuid); + printf("Lustre FS: %s\n", ldd->ldd_fsname); + printf("Mount type: %s\n", MT_STR(ldd)); + printf("Flags: %#x\n", ldd->ldd_flags); + printf(" (%s%s%s%s%s%s%s%s)\n", + IS_MDT(ldd) ? "MDT " : "", + IS_OST(ldd) ? "OST " : "", + IS_MGS(ldd) ? "MGS " : "", + ldd->ldd_flags & LDD_F_NEED_INDEX ? "needs_index " : "", + ldd->ldd_flags & LDD_F_VIRGIN ? "first_time " : "", + ldd->ldd_flags & LDD_F_UPDATE ? "update " : "", + ldd->ldd_flags & LDD_F_WRITECONF ? "writeconf " : "", + ldd->ldd_flags & LDD_F_NO_PRIMNODE ? "no_primnode " : ""); + printf("Persistent mount opts: %s\n", ldd->ldd_mount_opts); + osd_print_ldd_params(mop); + if (ldd->ldd_userdata[0]) + printf("Comment: %s\n", ldd->ldd_userdata); + printf("\n"); } 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_mgs_failnodes = 0; - strcpy(mop->mo_ldd.ldd_fsname, "lustre"); - mop->mo_ldd.ldd_mount_type = LDD_MT_LDISKFS; - - mop->mo_ldd.ldd_svindex = INDEX_UNASSIGNED; - mop->mo_stripe_count = 1; + 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; +#ifdef HAVE_LDISKFS_OSD + mop->mo_ldd.ldd_mount_type = LDD_MT_LDISKFS; +#else + mop->mo_ldd.ldd_mount_type = LDD_MT_ZFS; +#endif + mop->mo_ldd.ldd_svindex = INDEX_UNASSIGNED; + mop->mo_mgs_failnodes = 0; + mop->mo_stripe_count = 1; + mop->mo_pool_vdevs = NULL; +} + +/* Make the mdt/ost server obd name based on the filesystem name */ +static bool server_make_name(__u32 flags, __u16 index, const char *fs, + char *name_buf, size_t name_buf_size) +{ + bool invalid_flag = false; + + if (flags & (LDD_F_SV_TYPE_MDT | LDD_F_SV_TYPE_OST)) { + if (!(flags & LDD_F_SV_ALL)) + snprintf(name_buf, name_buf_size, "%.8s%c%s%04x", fs, + (flags & LDD_F_VIRGIN) ? ':' : + ((flags & LDD_F_WRITECONF) ? '=' : '-'), + (flags & LDD_F_SV_TYPE_MDT) ? "MDT" : "OST", + index); + } else if (flags & LDD_F_SV_TYPE_MGS) { + snprintf(name_buf, name_buf_size, "MGS"); + } else { + fprintf(stderr, "unknown server type %#x\n", flags); + invalid_flag = true; + } + return invalid_flag; } static inline void badopt(const char *opt, char *type) { - fprintf(stderr, "%s: '--%s' only valid for %s\n", - progname, opt, type); - usage(stderr); + fprintf(stderr, "%s: '--%s' only valid for %s\n", + progname, opt, type); + usage(stderr); } +#ifdef TUNEFS +/** + * Removes all existing instances of the parameter passed in \a param, + * which are in the form of "key=", from the buffer at \a buf. + * + * The parameter can be either in the form of "key" when passed by option + * "--erase-param", or in the form of "key=" when passed by option + * "--param". + * + * \param buf the buffer holding on-disk server parameters. + * \param param the parameter whose instances are to be removed from \a buf. + * \param withval true means the parameter is in the form of "key=" + * false means the parameter is in the form of "key" + * + * \retval 0 success, parameter was erased, + * \retval 1 success, parameter was not found, don't need to do erase_ldd, + * \retval EINVAL failure, invalid input parameter. + */ +static int erase_param(const char *const buf, const char *const param, + bool withval) +{ + char search[PARAM_MAX + 1] = ""; + char *buffer = (char *)buf; + bool found = false; + + if (strlen(param) > PARAM_MAX) { + fprintf(stderr, "%s: param to erase is too long-\n%s\n", + progname, param); + return EINVAL; + } + + /* add_param() writes a space as the first character in ldd_params */ + search[0] = ' '; + + /* "key" or "key=" */ + if (withval) { + char *keyend; + + keyend = strchr(param, '='); + if (!keyend) + return EINVAL; + strncpy(&search[1], param, keyend - param + 1); + } else { + snprintf(search + 1, sizeof(search) - 1, "%s=", param); + } + + while (1) { + char *space; + + buffer = strstr(buffer, search); + if (!buffer) + return found == true ? 0 : 1; + found = true; + space = strchr(buffer + 1, ' '); + if (space) { + memmove(buffer, space, strlen(space) + 1); + } else { + *buffer = '\0'; + return 0; + } + } +} +#endif + /* 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, *end, sep; - int left = MAXNIDSTR; - lnet_nid_t nid; - - converted = malloc(left); - if (converted == NULL) { - return NULL; - } - - end = s1 + strlen(s1); - c = converted; - while ((left > 0) && (s1 < end)) { - s2 = strpbrk(s1, ",:"); - if (!s2) - s2 = end; - sep = *s2; - *s2 = '\0'; - nid = libcfs_str2nid(s1); - - if (nid == LNET_NID_ANY) { - fprintf(stderr, "%s: Can't parse NID '%s'\n", - progname, s1); - free(converted); - return NULL; - } - if (strncmp(libcfs_nid2str(nid), "127.0.0.1", - strlen("127.0.0.1")) == 0) { - fprintf(stderr, "%s: The NID '%s' resolves to the " - "loopback address '%s'. Lustre requires a " - "non-loopback address.\n", - progname, s1, libcfs_nid2str(nid)); - free(converted); - return NULL; - } - - c += snprintf(c, left, "%s%c", libcfs_nid2str(nid), sep); - left = converted + MAXNIDSTR - c; - s1 = s2 + 1; - } - return converted; + char *converted, *s2 = 0, *c, *end, sep; + int left = MAXNIDSTR; + lnet_nid_t nid; + + converted = malloc(left); + if (!converted) + return NULL; + + end = s1 + strlen(s1); + c = converted; + while ((left > 0) && (s1 < end)) { + s2 = strpbrk(s1, ",:"); + if (!s2) + s2 = end; + sep = *s2; + *s2 = '\0'; + nid = libcfs_str2nid(s1); + *s2 = sep; + + if (nid == LNET_NID_ANY) { + fprintf(stderr, "%s: Cannot resolve hostname '%s'.\n", + progname, s1); + free(converted); + return NULL; + } + if (strncmp(libcfs_nid2str(nid), "127.0.0.1", + strlen("127.0.0.1")) == 0) { + fprintf(stderr, + "%s: The NID '%s' resolves to the loopback address '%s'. Lustre requires a non-loopback address.\n", + progname, s1, libcfs_nid2str(nid)); + free(converted); + return NULL; + } + + c += snprintf(c, left, "%s%c", libcfs_nid2str(nid), sep); + left = converted + MAXNIDSTR - c; + s1 = s2 + 1; + } + return converted; } int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop, - char **mountopts) + char **mountopts, char *old_fsname) { - static struct option long_opt[] = { - {"iam-dir", 0, 0, 'a'}, - {"backfstype", 1, 0, 'b'}, - {"stripe-count-hint", 1, 0, 'c'}, - {"comment", 1, 0, 'u'}, - {"configdev", 1, 0, 'C'}, - {"device-size", 1, 0, 'd'}, - {"dryrun", 0, 0, 'n'}, - {"erase-params", 0, 0, 'e'}, - {"failnode", 1, 0, 'f'}, - {"failover", 1, 0, 'f'}, - {"mgs", 0, 0, 'G'}, - {"help", 0, 0, 'h'}, - {"index", 1, 0, 'i'}, - {"mkfsoptions", 1, 0, 'k'}, - {"mgsnode", 1, 0, 'm'}, - {"mgsnid", 1, 0, 'm'}, - {"mdt", 0, 0, 'M'}, - {"fsname",1, 0, 'L'}, - {"noformat", 0, 0, 'n'}, - {"nomgs", 0, 0, 'N'}, - {"mountfsoptions", 1, 0, 'o'}, - {"ost", 0, 0, 'O'}, - {"param", 1, 0, 'p'}, - {"print", 0, 0, 'n'}, - {"quiet", 0, 0, 'q'}, - {"reformat", 0, 0, 'r'}, - {"servicenode", 1, 0, 's'}, - {"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:Pqrs:t:Uu:vw"; - int opt; - int rc, longidx; - int failnode_set = 0, servicenode_set = 0; - - while ((opt = getopt_long(argc, argv, optstring, long_opt, &longidx)) != - EOF) { - switch (opt) { - case 'a': { - if (IS_MDT(&mop->mo_ldd)) - mop->mo_ldd.ldd_flags |= LDD_F_IAM_DIR; - break; - } - case 'b': { - int i = 0; - while (i < LDD_MT_LAST) { - if (strcmp(optarg, mt_str(i)) == 0) { - mop->mo_ldd.ldd_mount_type = i; - break; - } - i++; - } - break; - } - case 'c': - if (IS_MDT(&mop->mo_ldd)) { - int stripe_count = atol(optarg); - if (stripe_count <= 0) { - fprintf(stderr, "%s: bad stripe count " - "%d\n", progname, stripe_count); - return 1; - } - mop->mo_stripe_count = stripe_count; - } else { - badopt(long_opt[longidx].name, "MDT"); - return 1; - } - break; - case 'C': /* Configdev */ - //FIXME - printf("Configdev not implemented\n"); - return 1; - case 'd': - mop->mo_device_sz = atol(optarg); - break; - case 'e': - mop->mo_ldd.ldd_params[0] = '\0'; - /* Must update the mgs logs */ - mop->mo_ldd.ldd_flags |= LDD_F_UPDATE; - break; - case 'f': - case 's': { - char *nids; - - if ((opt == 'f' && servicenode_set) - || (opt == 's' && failnode_set)) { - fprintf(stderr, "%s: %s cannot use with --%s\n", - progname, long_opt[longidx].name, - opt == 'f' ? "servicenode" : "failnode"); - return 1; - } - - nids = convert_hostnames(optarg); - if (!nids) - return 1; - rc = add_param(mop->mo_ldd.ldd_params, PARAM_FAILNODE, - nids); - free(nids); - if (rc) - return rc; - /* Must update the mgs logs */ - mop->mo_ldd.ldd_flags |= LDD_F_UPDATE; - if (opt == 'f') { - failnode_set = 1; - } else { - mop->mo_ldd.ldd_flags |= LDD_F_NO_PRIMNODE; - servicenode_set = 1; - } + static struct option long_opts[] = { + { .val = 'B', .name = "backfs-mount-opts", + .has_arg = required_argument}, + { .val = 'f', .name = "failnode", .has_arg = required_argument}, + { .val = 'f', .name = "failover", .has_arg = required_argument}, + { .val = 'G', .name = "mgs", .has_arg = no_argument}, + { .val = 'h', .name = "help", .has_arg = no_argument}, + { .val = 'i', .name = "index", .has_arg = required_argument}, + { .val = 'L', .name = "fsname", .has_arg = required_argument}, + { .val = 'm', .name = "mgsnode", .has_arg = required_argument}, + { .val = 'm', .name = "mgsnid", .has_arg = required_argument}, + { .val = 'n', .name = "dryrun", .has_arg = no_argument}, + { .val = 'N', .name = "nomgs", .has_arg = no_argument}, + { .val = 'o', .name = "mountfsoptions", + .has_arg = required_argument}, + { .val = 'p', .name = "param", .has_arg = required_argument}, + { .val = 'q', .name = "quiet", .has_arg = no_argument}, + { .val = 's', .name = "servicenode", .has_arg = required_argument}, + { .val = 't', .name = "network", .has_arg = required_argument}, + { .val = 'u', .name = "comment", .has_arg = required_argument}, + { .val = 'U', .name = "force-nohostid", + .has_arg = no_argument}, + { .val = 'v', .name = "verbose", .has_arg = no_argument}, + { .val = 'V', .name = "version", .has_arg = no_argument}, +#ifndef TUNEFS + { .val = 'b', .name = "backfstype", .has_arg = required_argument}, + { .val = 'c', .name = "stripe-count-hint", + .has_arg = required_argument}, + { .val = 'd', .name = "device-size", .has_arg = required_argument}, + { .val = 'k', .name = "mkfsoptions", .has_arg = required_argument}, + { .val = 'M', .name = "mdt", .has_arg = no_argument}, + { .val = 'O', .name = "ost", .has_arg = no_argument}, + { .val = 'r', .name = "reformat", .has_arg = no_argument}, + { .val = 'R', .name = "replace", .has_arg = no_argument}, +#else + { .val = 'E', .name = "erase-param", .has_arg = required_argument}, + { .val = 'e', .name = "erase-params", + .has_arg = no_argument}, + { .val = 'Q', .name = "quota", .has_arg = no_argument}, + { .val = 'R', .name = "rename", .has_arg = optional_argument}, + { .val = 'w', .name = "writeconf", .has_arg = no_argument}, +#endif + { .name = NULL } }; + char *short_opts = "B:f:Ghi:L:m:nNo:p:qs:t:u:vV" +#ifndef TUNEFS + "b:c:d:k:MOrR"; +#else + "E:eQR::w"; +#endif + struct lustre_disk_data *ldd = &mop->mo_ldd; + char new_fsname[16] = { 0 }; + int opt; + int rc, longidx; + int failnode_set = 0, servicenode_set = 0; + int replace = 0; + bool index_option = false; + +#ifdef TUNEFS + /* + * For the right semantics, if '-e'/'--erase-params' is specified, + * it must be picked out and all old parameters should be erased + * before any other changes are done. + */ + while ((opt = getopt_long(argc, argv, short_opts, long_opts, + &longidx)) != EOF) { + switch (opt) { + case 'e': + ldd->ldd_params[0] = '\0'; + mop->mo_flags |= MO_ERASE_ALL; + ldd->ldd_flags |= LDD_F_UPDATE; + break; + default: + break; + } + if (mop->mo_flags & MO_ERASE_ALL) + break; + } + optind = 0; +#endif + while ((opt = getopt_long(argc, argv, short_opts, long_opts, + &longidx)) != EOF) { + switch (opt) { + case 'B': + mop->mo_mountopts = optarg; + break; + case 'f': + case 's': { + char *nids; + + if ((opt == 'f' && servicenode_set) || + (opt == 's' && failnode_set)) { + fprintf(stderr, "%s: %s cannot use with --%s\n", + progname, long_opts[longidx].name, + opt == 'f' ? "servicenode" : + "failnode"); + return 1; + } + + nids = convert_hostnames(optarg); + if (!nids) + return 1; + + rc = append_param(ldd->ldd_params, PARAM_FAILNODE, + nids, ':'); + free(nids); + if (rc != 0) + return rc; + + /* Must update the mgs logs */ + ldd->ldd_flags |= LDD_F_UPDATE; + if (opt == 'f') { + ldd->ldd_flags &= ~LDD_F_NO_PRIMNODE; + failnode_set = 1; + } else { + ldd->ldd_flags |= LDD_F_NO_PRIMNODE; + servicenode_set = 1; + } mop->mo_flags |= MO_FAILOVER; - break; - } - case 'G': - mop->mo_ldd.ldd_flags |= LDD_F_SV_TYPE_MGS; - break; - case 'h': - usage(stdout); - return 1; - case 'i': - if (!(mop->mo_ldd.ldd_flags & - (LDD_F_UPGRADE14 | LDD_F_VIRGIN | - LDD_F_WRITECONF))) { - fprintf(stderr, "%s: cannot change the index of" - " a registered target\n", progname); - return 1; - } - if (IS_MDT(&mop->mo_ldd) || IS_OST(&mop->mo_ldd)) { - mop->mo_ldd.ldd_svindex = atol(optarg); - mop->mo_ldd.ldd_flags &= ~LDD_F_NEED_INDEX; - } else { - badopt(long_opt[longidx].name, "MDT,OST"); - return 1; - } - break; - case 'k': - strscpy(mop->mo_mkfsopts, optarg, - sizeof(mop->mo_mkfsopts)); - break; - case 'L': { - char *tmp; - if (!(mop->mo_flags & MO_FORCEFORMAT) && - (!(mop->mo_ldd.ldd_flags & - (LDD_F_UPGRADE14 | LDD_F_VIRGIN | - LDD_F_WRITECONF)))) { - fprintf(stderr, "%s: cannot change the name of" - " a registered target\n", progname); - return 1; - } - if ((strlen(optarg) < 1) || (strlen(optarg) > 8)) { - fprintf(stderr, "%s: filesystem name must be " - "1-8 chars\n", progname); - return 1; - } - if ((tmp = strpbrk(optarg, "/:"))) { - fprintf(stderr, "%s: char '%c' not allowed in " - "filesystem name\n", progname, *tmp); - return 1; - } - strscpy(mop->mo_ldd.ldd_fsname, optarg, - sizeof(mop->mo_ldd.ldd_fsname)); - break; - } - case 'm': { - char *nids = convert_hostnames(optarg); - if (!nids) - return 1; - rc = add_param(mop->mo_ldd.ldd_params, PARAM_MGSNODE, - nids); - free(nids); - if (rc) - return rc; - mop->mo_mgs_failnodes++; - break; - } - case 'M': - mop->mo_ldd.ldd_flags |= LDD_F_SV_TYPE_MDT; - break; - case 'n': - print_only++; - break; - case 'N': - mop->mo_ldd.ldd_flags &= ~LDD_F_SV_TYPE_MGS; - break; - case 'o': - *mountopts = optarg; - break; - case 'O': - 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; - /* Must update the mgs logs */ - mop->mo_ldd.ldd_flags |= LDD_F_UPDATE; - break; - case 'q': - verbose--; - break; - 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)); - break; - case 'v': - verbose++; - break; - case 'w': - mop->mo_ldd.ldd_flags |= LDD_F_WRITECONF; - break; - case 'U': - upgrade_to_18 = 1; - break; - default: - if (opt != '?') { - fatal(); - fprintf(stderr, "Unknown option '%c'\n", opt); - } - return EINVAL; - } - }//while - - /* Last arg is device */ - if (optind != argc - 1) { - fatal(); - fprintf(stderr, "Bad argument: %s\n", argv[optind]); - return EINVAL; - } - - /* single argument: */ - if (argc == 2) - ++print_only; - - return 0; + break; + } + case 'G': + ldd->ldd_flags |= LDD_F_SV_TYPE_MGS; + break; + case 'h': + usage(stdout); + return 1; + case 'i': { + char *endptr = NULL; + int base; + + index_option = true; + /* LU-2374: check whether it is OST/MDT later */ + base = (strlen(optarg) > 1 && + !strncmp(optarg, "0x", 2)) ? 16 : 10; + /* Allowed input are base 16 and base 10 numbers only */ + mop->mo_ldd.ldd_svindex = strtoul(optarg, + &endptr, base); + if (*endptr != '\0') { + fprintf(stderr, + "%s: wrong index %s. Target index must be decimal or hexadecimal.\n", + progname, optarg); + return 1; + } + if (ldd->ldd_svindex >= INDEX_UNASSIGNED) { + fprintf(stderr, + "%s: wrong index %u. Target index must be less than %u.\n", + progname, ldd->ldd_svindex, + INDEX_UNASSIGNED); + return 1; + } + + ldd->ldd_flags &= ~LDD_F_NEED_INDEX; + break; + } + case 'L': { + const char *tmp; + size_t len; + + len = strlen(optarg); + if (len < 1 || len > LUSTRE_MAXFSNAME) { + fprintf(stderr, + "%s: filesystem name must be 1-%d chars\n", + progname, LUSTRE_MAXFSNAME); + return 1; + } + + for (tmp = optarg; *tmp != '\0'; ++tmp) { + if (isalnum(*tmp) || *tmp == '_' || *tmp == '-') + continue; + else + break; + } + if (*tmp != '\0') { + fprintf(stderr, + "%s: char '%c' not allowed in filesystem name\n", + progname, *tmp); + return 1; + } + strscpy(new_fsname, optarg, sizeof(new_fsname)); + break; + } + case 'm': { + char *nids = convert_hostnames(optarg); + + if (!nids) + return 1; + + rc = append_param(ldd->ldd_params, PARAM_MGSNODE, + nids, ':'); + free(nids); + if (rc != 0) + return rc; + + mop->mo_mgs_failnodes++; + break; + } + case 'n': + print_only++; + break; + case 'N': + ldd->ldd_flags &= ~LDD_F_SV_TYPE_MGS; + break; + case 'o': + *mountopts = optarg; + break; + case 'p': +#ifdef TUNEFS + /* + * Removes all existing instances of the parameter + * before adding new values. + */ + rc = erase_param(ldd->ldd_params, optarg, true); + if (rc > 1) + return rc; +#endif + rc = add_param(ldd->ldd_params, NULL, optarg); + if (rc != 0) + return rc; + /* Must update the mgs logs */ + ldd->ldd_flags |= LDD_F_UPDATE; + break; + case 'q': + verbose--; + break; + case 't': + if (!IS_MDT(ldd) && !IS_OST(ldd)) { + badopt(long_opts[longidx].name, "MDT,OST"); + return 1; + } + + if (!optarg) + return 1; + + rc = add_param(ldd->ldd_params, PARAM_NETWORK, optarg); + if (rc != 0) + return rc; + + /* Must update the mgs logs */ + ldd->ldd_flags |= LDD_F_UPDATE; + break; + case 'u': + strscpy(ldd->ldd_userdata, optarg, + sizeof(ldd->ldd_userdata)); + break; + case 'U': + mop->mo_flags |= MO_NOHOSTID_CHECK; + break; + case 'v': + verbose++; + break; + case 'V': + ++version; + fprintf(stdout, "%s %s\n", progname, + LUSTRE_VERSION_STRING); + return 0; +#ifndef TUNEFS + case 'b': { + int i = 0; + + do { + if (strcmp(optarg, mt_str(i)) == 0) { + ldd->ldd_mount_type = i; + break; + } + } while (++i < LDD_MT_LAST); + + if (i == LDD_MT_LAST) { + fprintf(stderr, + "%s: invalid backend filesystem type %s\n", + progname, optarg); + return 1; + } + break; + } + case 'c': + if (IS_MDT(ldd)) { + int stripe_count = atol(optarg); + + if (stripe_count <= 0) { + fprintf(stderr, + "%s: bad stripe count %s\n", + progname, optarg); + return 1; + } + mop->mo_stripe_count = stripe_count; + } else { + badopt(long_opts[longidx].name, "MDT"); + return 1; + } + break; + case 'd': + mop->mo_device_kb = atol(optarg); + break; + case 'k': + strscpy(mop->mo_mkfsopts, optarg, + sizeof(mop->mo_mkfsopts)); + break; + case 'M': + ldd->ldd_flags |= LDD_F_SV_TYPE_MDT; + break; + case 'O': + ldd->ldd_flags |= LDD_F_SV_TYPE_OST; + break; + case 'r': + mop->mo_flags |= MO_FORCEFORMAT; + break; + case 'R': + replace = 1; + break; +#else /* TUNEFS */ + case 'E': + rc = erase_param(ldd->ldd_params, optarg, false); + /* + * (rc == 1) means not found, so don't need to + * call osd_erase_ldd(). + */ + if (rc > 1) + return rc; + if (!rc) { + rc = osd_erase_ldd(mop, optarg); + if (rc) + return rc; + } + /* Must update the mgs logs */ + ldd->ldd_flags |= LDD_F_UPDATE; + break; + case 'e': + /* Already done in the beginning */ + break; + case 'Q': + mop->mo_flags |= MO_QUOTA; + break; + case 'R': { + char *tmp; + + mop->mo_flags |= MO_RENAME; + if (!optarg) { + if (IS_SEPARATED_MGS(ldd)) { + fprintf(stderr, + "%s: must specify the old fsname to be renamed for separated MGS\n", + progname); + return 1; + } + break; + } + + if ((strlen(optarg) < 1) || (strlen(optarg) > 8)) { + fprintf(stderr, + "%s: filesystem name must be 1-8 chars\n", + progname); + return 1; + } + + tmp = strpbrk(optarg, "/:"); + if (tmp) { + fprintf(stderr, + "%s: char '%c' not allowed in filesystem name\n", + progname, *tmp); + return 1; + } + + if (IS_SEPARATED_MGS(ldd)) { + strscpy(old_fsname, optarg, + sizeof(ldd->ldd_fsname)); + } else if (strlen(old_fsname) != strlen(optarg) || + strcmp(old_fsname, optarg) != 0) { + fprintf(stderr, + "%s: the given fsname '%s' to be renamed does not exist\n", + progname, optarg); + return 1; + } + break; + } + case 'w': + ldd->ldd_flags |= LDD_F_WRITECONF; + break; +#endif /* !TUNEFS */ + default: + if (opt != '?') { + fatal(); + fprintf(stderr, "Unknown option '%c'\n", opt); + } + return EINVAL; + } + } + + if (strlen(new_fsname) > 0) { + if (!(mop->mo_flags & (MO_FORCEFORMAT | MO_RENAME)) && + (!(ldd->ldd_flags & (LDD_F_VIRGIN | LDD_F_WRITECONF)))) { + fprintf(stderr, + "%s: cannot change the name of a registered target\n", + progname); + return 1; + } + + strscpy(ldd->ldd_fsname, new_fsname, sizeof(ldd->ldd_fsname)); + } + + if (index_option && !(mop->mo_ldd.ldd_flags & + (LDD_F_VIRGIN | LDD_F_WRITECONF))) { + fprintf(stderr, + "%s: cannot change the index of a registered target\n", + progname); + return 1; + } + +#ifdef TUNEFS + if (mop->mo_flags & MO_RENAME) { + if (new_fsname[0] == '\0') { + fprintf(stderr, + "%s: need to specify new fsname for renaming case\n", + progname); + return 1; + } + + if (strcmp(old_fsname, new_fsname) == 0) { + fprintf(stderr, + "%s: cannot rename fsname '%s' to the same name\n", + progname, old_fsname); + return 1; + } + } +#endif + + /* Need to clear this flag after parsing 'L' and 'i' options. */ + if (replace) + ldd->ldd_flags &= ~LDD_F_VIRGIN; + + if (optind == argc) { + /* The user didn't specify device name */ + fatal(); + fprintf(stderr, + "Not enough arguments - device name or pool/dataset name not specified.\n"); + return EINVAL; + } + + /* The device or pool/filesystem name */ + strscpy(mop->mo_device, argv[optind], sizeof(mop->mo_device)); + + /* Followed by optional vdevs */ + if (optind < argc - 1) + mop->mo_pool_vdevs = (char **)&argv[optind + 1]; + + return 0; } int main(int argc, char *const argv[]) { - struct mkfs_opts mop; - struct lustre_disk_data *ldd; - char *mountopts = NULL; - char always_mountopts[512] = ""; - char default_mountopts[512] = ""; - unsigned mount_type; - int ret = 0; - - if ((progname = strrchr(argv[0], '/')) != NULL) - progname++; - else - progname = argv[0]; - - if ((argc < 2) || (argv[argc - 1][0] == '-')) { - usage(stderr); - return(EINVAL); - } - - memset(&mop, 0, sizeof(mop)); - set_defaults(&mop); - - /* device is last arg */ - strscpy(mop.mo_device, argv[argc - 1], sizeof(mop.mo_device)); + struct mkfs_opts mop; + struct lustre_disk_data *ldd = &mop.mo_ldd; + char *mountopts = NULL; + char wanted_mountopts[512] = ""; + char old_fsname[16] = ""; + unsigned int mount_type; + int ret = 0; + int ret2 = 0; + + progname = strrchr(argv[0], '/'); + if (progname) + progname++; + else + progname = argv[0]; + + if ((argc < 2) || (argv[argc - 1][0] == '-')) { + usage(stderr); + return EINVAL; + } + + memset(&mop, 0, sizeof(mop)); + set_defaults(&mop); + + /* device is last arg */ + strscpy(mop.mo_device, argv[argc - 1], sizeof(mop.mo_device)); + + ret = osd_init(); + if (ret != 0) + return ret; #ifdef TUNEFS - /* For tunefs, we must read in the old values before parsing any - new ones. */ + /* + * For tunefs, we must read in the old values before parsing any + * new ones. + */ - /* Check whether the disk has already been formatted by mkfs.lustre */ + /* Check whether the disk has already been formatted by mkfs.lustre */ ret = osd_is_lustre(mop.mo_device, &mount_type); - if (ret == 0) { - fatal(); - fprintf(stderr, "Device %s has not been formatted with " - "mkfs.lustre\n", mop.mo_device); - ret = ENODEV; - goto out; - } - - ret = osd_read_ldd(mop.mo_device, &mop.mo_ldd); - if (ret) { - fatal(); - fprintf(stderr, "Failed to read previous Lustre data from %s " - "(%d)\n", mop.mo_device, ret); - goto out; - } - if (strstr(mop.mo_ldd.ldd_params, PARAM_MGSNODE)) - mop.mo_mgs_failnodes++; - - if (verbose > 0) - print_ldd("Read previous values", &(mop.mo_ldd)); + if (ret == 0) { + fatal(); + fprintf(stderr, + "Device %s has not been formatted with mkfs.lustre\n", + mop.mo_device); + ret = ENODEV; + goto out; + } + ldd->ldd_mount_type = mount_type; + + ret = osd_read_ldd(mop.mo_device, ldd); + if (ret != 0) { + fatal(); + fprintf(stderr, + "Failed to read previous Lustre data from %s (%d)\n", + mop.mo_device, ret); + goto out; + } + + strscpy(old_fsname, ldd->ldd_fsname, sizeof(ldd->ldd_fsname)); + ldd->ldd_flags &= ~(LDD_F_WRITECONF | LDD_F_VIRGIN); + + /* svname of the form lustre:OST1234 means never registered */ + ret = strlen(ldd->ldd_svname); + if (ldd->ldd_svname[ret - 8] == ':') { + ldd->ldd_svname[ret - 8] = '-'; + ldd->ldd_flags |= LDD_F_VIRGIN; + } else if (ldd->ldd_svname[ret - 8] == '=') { + ldd->ldd_svname[ret - 8] = '-'; + ldd->ldd_flags |= LDD_F_WRITECONF; + } + + if (strstr(ldd->ldd_params, PARAM_MGSNODE)) + mop.mo_mgs_failnodes++; + + if (verbose > 0) + print_ldd("Read previous values", &mop); +#endif /* TUNEFS */ + + ret = parse_opts(argc, argv, &mop, &mountopts, old_fsname); + if (ret != 0 || version) + goto out; + + if (!IS_MDT(ldd) && !IS_OST(ldd) && !IS_MGS(ldd)) { + fatal(); + fprintf(stderr, "must set target type: MDT,OST,MGS\n"); + ret = EINVAL; + goto out; + } + + if (((IS_MDT(ldd) || IS_MGS(ldd))) && IS_OST(ldd)) { + fatal(); + fprintf(stderr, "OST type is exclusive with MDT,MGS\n"); + ret = EINVAL; + goto out; + } + + /* Stand alone MGS doesn't need an index */ + if (!IS_MDT(ldd) && IS_MGS(ldd)) { +#ifndef TUNEFS + /* But if --index was specified flag an error */ + if (!(ldd->ldd_flags & LDD_F_NEED_INDEX)) { + badopt("index", "MDT,OST"); + goto out; + } #endif + ldd->ldd_flags &= ~LDD_F_NEED_INDEX; + } - ret = parse_opts(argc, argv, &mop, &mountopts); - if (ret) - goto out; - - ldd = &mop.mo_ldd; - - if (!(IS_MDT(ldd) || IS_OST(ldd) || IS_MGS(ldd))) { - fatal(); - fprintf(stderr, "must set target type: MDT,OST,MGS\n"); - ret = EINVAL; - goto out; - } - - if (((IS_MDT(ldd) || IS_MGS(ldd))) && IS_OST(ldd)) { - fatal(); - fprintf(stderr, "OST type is exclusive with MDT,MGS\n"); - ret = EINVAL; - goto out; - } - - if ((mop.mo_ldd.ldd_flags & (LDD_F_NEED_INDEX | LDD_F_UPGRADE14)) == - (LDD_F_NEED_INDEX | LDD_F_UPGRADE14)) { - fatal(); - fprintf(stderr, "Can't find the target index, " - "specify with --index\n"); - ret = EINVAL; - goto out; - } -#if 0 - /* - * Comment out these 2 checks temporarily, since for multi-MDSes - * in single node only 1 mds node could have mgs service - */ - if (IS_MDT(ldd) && !IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) { - verrprint("No management node specified, adding MGS to this " - "MDT\n"); - ldd->ldd_flags |= LDD_F_SV_TYPE_MGS; - } - if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) { - fatal(); - if (IS_MDT(ldd)) - fprintf(stderr, "Must specify --mgs or --mgsnode=\n"); - else - fprintf(stderr, "Must specify --mgsnode=\n"); - ret = EINVAL; - goto out; - } + if (ldd->ldd_flags & LDD_F_NEED_INDEX) + fprintf(stderr, + "warning: %s: for Lustre 2.4 and later, the target index must be specified with --index\n", + mop.mo_device); + + /* If no index is supplied for MDT by default set index to zero */ + if (IS_MDT(ldd) && (ldd->ldd_svindex == INDEX_UNASSIGNED)) { + ldd->ldd_flags &= ~LDD_F_NEED_INDEX; + ldd->ldd_svindex = 0; + } +#ifndef TUNEFS + if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0)) { +#else + /* + * Don't check --mgs or --mgsnode if print_only is set or + * --erase-params is set. + */ + if (!IS_MGS(ldd) && (mop.mo_mgs_failnodes == 0) && !print_only && + !(mop.mo_flags & MO_ERASE_ALL)) { #endif + fatal(); + if (IS_MDT(ldd)) + fprintf(stderr, "Must specify --mgs or --mgsnode\n"); + else + fprintf(stderr, "Must specify --mgsnode\n"); + ret = EINVAL; + goto out; + } + if ((IS_MDT(ldd) || IS_OST(ldd)) && ldd->ldd_fsname[0] == '\0') { + fatal(); + fprintf(stderr, "Must specify --fsname for MDT/OST device\n"); + ret = EINVAL; + goto out; + } - /* These are the permanent mount options (always included) */ + /* These are the permanent mount options (always included) */ ret = osd_prepare_lustre(&mop, - default_mountopts, sizeof(default_mountopts), - always_mountopts, sizeof(always_mountopts)); - if (ret) { + wanted_mountopts, sizeof(wanted_mountopts)); + if (ret != 0) { fatal(); fprintf(stderr, "unable to prepare backend (%d)\n", ret); goto out; } - if (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 { + if (mountopts) { + trim_mountfsoptions(mountopts); + if (check_mountfsoptions(mountopts, wanted_mountopts)) { + ret = EINVAL; + goto out; + } + snprintf(ldd->ldd_mount_opts, sizeof(ldd->ldd_mount_opts), + "%s", mountopts); + } else { #ifdef TUNEFS - if (ldd->ldd_mount_opts[0] == 0) - /* use the defaults unless old opts exist */ + if (ldd->ldd_mount_opts[0] == 0) + /* use the defaults unless old opts exist */ #endif - { - sprintf(ldd->ldd_mount_opts, "%s%s", - always_mountopts, default_mountopts); - trim_mountfsoptions(ldd->ldd_mount_opts); - } - } + { + snprintf(ldd->ldd_mount_opts, + sizeof(ldd->ldd_mount_opts), + "%s", wanted_mountopts); + trim_mountfsoptions(ldd->ldd_mount_opts); + } + } - server_make_name(ldd->ldd_flags, ldd->ldd_svindex, - ldd->ldd_fsname, ldd->ldd_svname); + ret = osd_fix_mountopts(&mop, ldd->ldd_mount_opts, + sizeof(ldd->ldd_mount_opts)); + if (ret != 0) { + fatal(); + fprintf(stderr, "unable to fix mountfsoptions (%d)\n", ret); + goto out; + } + + if (server_make_name(ldd->ldd_flags, ldd->ldd_svindex, + ldd->ldd_fsname, ldd->ldd_svname, + sizeof(ldd->ldd_svname))) { + printf("unknown server type %#x\n", ldd->ldd_flags); + goto out; + } - if (verbose >= 0) - print_ldd("Permanent disk data", ldd); + if (verbose >= 0) + print_ldd("Permanent disk data", &mop); - if (print_only) { - printf("exiting before disk write.\n"); - goto out; - } + if (print_only) { + printf("exiting before disk write.\n"); + goto out; + } if (check_mtab_entry(mop.mo_device, mop.mo_device, NULL, NULL)) - return(EEXIST); - - /* Create the loopback file */ - if (mop.mo_flags & MO_IS_LOOP) { - ret = access(mop.mo_device, F_OK); - if (ret) - ret = errno; -#ifndef TUNEFS /* mkfs.lustre */ - /* Reformat the loopback file */ - if (ret || (mop.mo_flags & MO_FORCEFORMAT)) { - ret = loop_format(&mop); - if (ret) - goto out; - } + return EEXIST; + + /* Create the loopback file */ + if (mop.mo_flags & MO_IS_LOOP) { + ret = access(mop.mo_device, F_OK); + if (ret != 0) + ret = errno; + +#ifndef TUNEFS + /* Reformat the loopback file */ + if (ret != 0 || (mop.mo_flags & MO_FORCEFORMAT)) { + ret = loop_format(&mop); + if (ret != 0) + goto out; + } #endif - if (ret == 0) - ret = loop_setup(&mop); - if (ret) { - fatal(); - fprintf(stderr, "Loop device setup for %s failed: %s\n", - mop.mo_device, strerror(ret)); - goto out; - } - } - -#ifndef TUNEFS /* mkfs.lustre */ - /* Check whether the disk has already been formatted by mkfs.lustre */ - if (!(mop.mo_flags & MO_FORCEFORMAT)) { + if (ret == 0) + ret = loop_setup(&mop); + if (ret != 0) { + fatal(); + fprintf(stderr, "Loop device setup for %s failed: %s\n", + mop.mo_device, strerror(ret)); + goto out; + } + } + +#ifndef TUNEFS + /* Check whether the disk has already been formatted by mkfs.lustre */ + if (!(mop.mo_flags & MO_FORCEFORMAT)) { ret = osd_is_lustre(mop.mo_device, &mount_type); - if (ret) { - fatal(); - fprintf(stderr, "Device %s was previously formatted " - "for lustre. Use --reformat to reformat it, " - "or tunefs.lustre to modify.\n", - mop.mo_device); - goto out; - } - } - - /* Format the backing filesystem */ - ret = make_lustre_backfs(&mop); - if (ret != 0) { - fatal(); - fprintf(stderr, "mkfs failed %d\n", ret); - goto out; - } -#endif + if (ret != 0) { + fatal(); + fprintf(stderr, + "Device %s was previously formatted for lustre. Use --reformat to reformat it, or tunefs.lustre to modify.\n", + mop.mo_device); + goto out; + } + } - /* Write our config files */ - ret = write_local_files(&mop); - if (ret != 0) { - fatal(); - fprintf(stderr, "failed to write local files\n"); - goto out; - } + /* Format the backing filesystem */ + ret = osd_make_lustre(&mop); + if (ret != 0) { + fatal(); + fprintf(stderr, "mkfs failed %d\n", ret); + goto out; + } +#else /* TUNEFS */ + /* update svname with '=' to refresh config */ + if (ldd->ldd_flags & LDD_F_WRITECONF) { + struct mount_opts opts; + + opts.mo_ldd = *ldd; + opts.mo_source = mop.mo_device; + (void)osd_label_lustre(&opts); + } + /* Rename filesystem fsname */ + if (mop.mo_flags & MO_RENAME) { + ret = osd_rename_fsname(&mop, old_fsname); + if (ret) + goto out; + } + + /* Enable quota accounting */ + if (mop.mo_flags & MO_QUOTA) { + ret = osd_enable_quota(&mop); + goto out; + } +#endif /* !TUNEFS */ + + /* Write our config files */ + ret = osd_write_ldd(&mop); + if (ret != 0) { + fatal(); + fprintf(stderr, "failed to write local files\n"); + goto out; + } out: - loop_cleanup(&mop); - - /* Fix any crazy return values from system() */ - if (ret && ((ret & 255) == 0)) - return (1); - if (ret) - verrprint("%s: exiting with %d (%s)\n", - progname, ret, strerror(ret)); - return (ret); + osd_fini(); + ret2 = loop_cleanup(&mop); + if (ret == 0) + ret = ret2; + + /* Fix any crazy return values from system() */ + if (ret != 0 && ((ret & 255) == 0)) + return 1; + + if (ret != 0) + verrprint("%s: exiting with %d (%s)\n", + progname, ret, strerror(ret)); + return ret; }