Example #1
0
int
ntp_getopt(
	int argc,
	char *argv[],
	const char *optstring
	)
{
	register char c;
	register const char *place;

	prog = argv[0];
	ntp_optarg = NULL;

	if (ntp_optind == 0) {
		scan = NULL;
		ntp_optind++;
	}
	
	if (scan == NULL || *scan == '\0') {
		if (ntp_optind >= argc
		    || argv[ntp_optind][0] != '-'
		    || argv[ntp_optind][1] == '\0') {
			return (EOF);
		}
		if (argv[ntp_optind][1] == '-'
		    && argv[ntp_optind][2] == '\0') {
			ntp_optind++;
			return (EOF);
		}
	
		scan = argv[ntp_optind++]+1;
	}

	c = *scan++;
	ntp_optopt = c & 0377;
	for (place = optstring; place != NULL && *place != '\0'; ++place)
	    if (*place == c)
		break;

	if (place == NULL || *place == '\0' || c == ':' || c == '?') {
		return (badopt(": unknown option -", c));
	}

	place++;
	if (*place == ':') {
		if (*scan != '\0') {
			ntp_optarg = scan;
			scan = NULL;
		} else if (ntp_optind >= argc) {
			return (badopt(": option requires argument -", c));
		} else {
			ntp_optarg = argv[ntp_optind++];
		}
	}

	return (c & 0377);
}
Example #2
0
int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
	       char **mountopts)
{
	static struct option long_opt[] = {
		{ "backfs-mount-opts",  required_argument,	NULL, 'B' },
		{ "failnode",		required_argument,	NULL, 'f' },
		{ "failover",		required_argument,	NULL, 'f' },
		{ "help",		no_argument,		NULL, 'h' },
		{ "index",		required_argument,	NULL, 'i' },
		{ "fsname",		required_argument,	NULL, 'L' },
		{ "mgsnode",		required_argument,	NULL, 'm' },
		{ "mgsnid",		required_argument,	NULL, 'm' },
		{ "dryrun",		no_argument,		NULL, 'n' },
		{ "mountfsoptions",	required_argument,	NULL, 'o' },
		{ "param",		required_argument,	NULL, 'p' },
		{ "quiet",		no_argument,		NULL, 'q' },
		{ "servicenode",	required_argument,	NULL, 's' },
		{ "network",		required_argument,	NULL, 't' },
		{ "comment",		required_argument,	NULL, 'u' },
		{ "force-nohostid",	no_argument,		NULL, 'U' },
		{ "verbose",		no_argument,		NULL, 'v' },
		{ "version",		no_argument,		NULL, 'V' },
#ifndef TUNEFS
		{ "backfstype",		required_argument,	NULL, 'b' },
		{ "stripe-count-hint",	required_argument,	NULL, 'c' },
		{ "device-size",	required_argument,	NULL, 'd' },
		{ "mgs",		no_argument,		NULL, 'G' },
		{ "mkfsoptions",	required_argument,	NULL, 'k' },
		{ "mdt",		no_argument,		NULL, 'M' },
		{ "nomgs",		no_argument,		NULL, 'N' },
		{ "ost",		no_argument,		NULL, 'O' },
		{ "reformat",		no_argument,		NULL, 'r' },
		{ "replace",		no_argument,		NULL, 'R' },
#else
		{ "erase-params",	no_argument,		NULL, 'e' },
		{ "quota",		no_argument,		NULL, 'Q' },
		{ "writeconf",		no_argument,		NULL, 'w' },
#endif
		{ 0,			0,			NULL,  0  }
	};
	char *optstring = "B:f:hi:L:m:no:p:qs:t:u:vV"
#ifndef TUNEFS
			  "b:c:d:Gk:MNOrR";
#else
			  "eQw";
#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;

	while ((opt = getopt_long(argc, argv, optstring, long_opt, &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_opt[longidx].name,
					opt == 'f' ? "servicenode" :
					"failnode");
				return 1;
			}

			nids = convert_hostnames(optarg);
			if (nids == NULL)
				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') {
				failnode_set = 1;
			} else {
				ldd->ldd_flags |= LDD_F_NO_PRIMNODE;
				servicenode_set = 1;
			}
			mop->mo_flags |= MO_FAILOVER;
			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': {
			rc = lustre_is_fsname_valid(optarg, 1,
						    LUSTRE_MAXFSNAME);
			if (rc < 0) {
				fprintf(stderr, "%s: filesystem name must be "
					"1-%d chars\n", progname,
					LUSTRE_MAXFSNAME);
				return 1;
			} else if (rc > 0) {
				fprintf(stderr, "%s: char '%c' not allowed in "
					"filesystem name\n", progname, rc);
				return 1;
			}

			strscpy(new_fsname, optarg, sizeof(new_fsname));
			break;
		}
		case 'm': {
			char *nids = convert_hostnames(optarg);

			if (nids == NULL)
				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 'o':
			*mountopts = optarg;
			break;
		case 'p':
			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_opt[longidx].name, "MDT,OST");
				return 1;
			}

			if (optarg == NULL)
				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 "
						"%d\n", progname, stripe_count);
					return 1;
				}
				mop->mo_stripe_count = stripe_count;
			} else {
				badopt(long_opt[longidx].name, "MDT");
				return 1;
			}
			break;
		case 'd':
			mop->mo_device_kb = atol(optarg);
			break;
		case 'G':
			ldd->ldd_flags |= LDD_F_SV_TYPE_MGS;
			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 'N':
			ldd->ldd_flags &= ~LDD_F_SV_TYPE_MGS;
			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':
			ldd->ldd_params[0] = '\0';
			/* Must update the mgs logs */
			ldd->ldd_flags |= LDD_F_UPDATE;
			break;
		case 'Q':
			mop->mo_flags |= MO_QUOTA;
			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) &&
		     (!(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;
		}

		strscpy(ldd->ldd_fsname, new_fsname, sizeof(ldd->ldd_fsname));
	}

	if (index_option && !(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;
	}

	/* 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;
	} else {
		/*  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;
}
Example #3
0
int main(int argc, char *const argv[])
{
	struct mkfs_opts mop;
	struct lustre_disk_data *ldd = &mop.mo_ldd;
	char *mountopts = NULL;
	char wanted_mountopts[512] = "";
	unsigned mount_type;
	int ret = 0;
	int ret2 = 0;

	progname = strrchr(argv[0], '/');
	if (progname != 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));

	ret = osd_init();
	if (ret != 0)
		return ret;

#ifdef TUNEFS
	/* 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 */
	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;
	}
	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;
	}

	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", ldd);
#endif /* TUNEFS */

	ret = parse_opts(argc, argv, &mop, &mountopts);
	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;
	}

	if ((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 (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;
	}
	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 ((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) */
	ret = osd_prepare_lustre(&mop,
				 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);
		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 */
#endif
		{
			snprintf(ldd->ldd_mount_opts,
				 sizeof(ldd->ldd_mount_opts),
				 "%s", wanted_mountopts);
			trim_mountfsoptions(ldd->ldd_mount_opts);
		}
	}

	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;
	}

	server_make_name(ldd->ldd_flags, ldd->ldd_svindex,
			 ldd->ldd_fsname, ldd->ldd_svname);

	if (verbose >= 0)
		print_ldd("Permanent disk data", ldd);

	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 != 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 != 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 != 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;
		}
	}

	/* 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);
	}

	/* 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:
	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;
}
Example #4
0
int parse_opts(int argc, char *const argv[], struct mkfs_opts *mop,
               char **mountopts)
{
	static struct option long_opt[] = {
		{ "backfstype",		required_argument,	NULL, 'b' },
		{ "stripe-count-hint",	required_argument,	NULL, 'c' },
		{ "comment",		required_argument,	NULL, 'u' },
		{ "configdev",		required_argument,	NULL, 'C' },
		{ "device-size",	required_argument,	NULL, 'd' },
		{ "dryrun",		no_argument,		NULL, 'n' },
		{ "erase-params",	no_argument,		NULL, 'e' },
		{ "failnode",		required_argument,	NULL, 'f' },
		{ "failover",		required_argument,	NULL, 'f' },
		{ "mgs",		no_argument,		NULL, 'G' },
		{ "help",		no_argument,		NULL, 'h' },
		{ "index",		required_argument,	NULL, 'i' },
		{ "mkfsoptions",	required_argument,	NULL, 'k' },
		{ "mgsnode",		required_argument,	NULL, 'm' },
		{ "mgsnid",		required_argument,	NULL, 'm' },
		{ "mdt",		no_argument,		NULL, 'M' },
		{ "fsname",		required_argument,	NULL, 'L' },
		{ "noformat",		no_argument,		NULL, 'n' },
		{ "nomgs",		no_argument,		NULL, 'N' },
		{ "mountfsoptions",	required_argument,	NULL, 'o' },
		{ "ost",		no_argument,		NULL, 'O' },
		{ "param",		required_argument,	NULL, 'p' },
		{ "print",		no_argument,		NULL, 'n' },
		{ "quiet",		no_argument,		NULL, 'q' },
		{ "quota",		no_argument,		NULL, 'Q' },
		{ "reformat",		no_argument,		NULL, 'r' },
		{ "replace",		no_argument,		NULL, 'R' },
		{ "servicenode",	required_argument,	NULL, 's' },
		{ "network",		required_argument,	NULL, 't' },
		{ "verbose",		no_argument,		NULL, 'v' },
		{ "writeconf",		no_argument,		NULL, 'w' },
		{ 0,			0,			NULL,  0  }
	};
	char *optstring = "b:c:C:d:ef:Ghi:k:L:m:MnNo:Op:PqrRs:t:Uu:vw";
	int opt;
	int rc, longidx;
	int failnode_set = 0, servicenode_set = 0;
	int replace = 0;

        while ((opt = getopt_long(argc, argv, optstring, long_opt, &longidx)) !=
               EOF) {
                switch (opt) {
                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++;
                        }
			if (i == LDD_MT_LAST) {
				fprintf(stderr, "%s: invalid backend filesystem"
					" type %s\n", progname, optarg);
				return 1;
			}
                        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_kb = 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;
                        }
			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;
                        }
			/* LU-2374: check whether it is OST/MDT later */
			mop->mo_ldd.ldd_svindex = atol(optarg);
			mop->mo_ldd.ldd_flags &= ~LDD_F_NEED_INDEX;
                        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 'R':
			replace = 1;
			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 'Q':
			mop->mo_flags |= MO_QUOTA;
			break;
                default:
                        if (opt != '?') {
                                fatal();
                                fprintf(stderr, "Unknown option '%c'\n", opt);
                        }
                        return EINVAL;
                }
        }//while

	/* Need to clear this flag after parsing 'L' and 'i' options. */
	if (replace)
		mop->mo_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;
	} else {
		/*  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;
}