Ejemplo n.º 1
0
int main(int argc, char *const argv[])
{
	struct mount_opts mop;
	char *options;
	int i, rc, flags;

	progname = strrchr(argv[0], '/');
	progname = progname ? progname + 1 : argv[0];

	set_defaults(&mop);

	rc = osd_init();
	if (rc)
		return rc;

	rc = parse_opts(argc, argv, &mop);
	if (rc || version)
		return rc;

        if (verbose) {
                for (i = 0; i < argc; i++)
                        printf("arg[%d] = %s\n", i, argv[i]);
		printf("source = %s (%s), target = %s\n", mop.mo_usource,
		       mop.mo_source, mop.mo_target);
		printf("options = %s\n", mop.mo_orig_options);
        }

	options = malloc(MAXOPT);
        if (options == NULL) {
                fprintf(stderr, "can't allocate memory for options\n");
                return -1;
        }
	strcpy(options, mop.mo_orig_options);
	rc = parse_options(&mop, options, &flags);
        if (rc) {
                fprintf(stderr, "%s: can't parse options: %s\n",
                        progname, options);
                return(EINVAL);
        }

	if (!mop.mo_force) {
		rc = check_mtab_entry(mop.mo_usource, mop.mo_source,
				      mop.mo_target, "lustre");
                if (rc && !(flags & MS_REMOUNT)) {
                        fprintf(stderr, "%s: according to %s %s is "
				"already mounted on %s\n", progname, MOUNTED,
				mop.mo_usource, mop.mo_target);
                        return(EEXIST);
                }
                if (!rc && (flags & MS_REMOUNT)) {
                        fprintf(stderr, "%s: according to %s %s is "
				"not already mounted on %s\n", progname, MOUNTED,
				mop.mo_usource, mop.mo_target);
                        return(ENOENT);
                }
        }
        if (flags & MS_REMOUNT)
		mop.mo_nomtab++;

	rc = access(mop.mo_target, F_OK);
        if (rc) {
                rc = errno;
		fprintf(stderr, "%s: %s inaccessible: %s\n", progname,
			mop.mo_target, strerror(errno));
                return rc;
        }

	if (!strstr(mop.mo_usource, ":/")) {
		rc = parse_ldd(mop.mo_source, &mop, options);
		if (rc)
			return rc;
	}

        /* In Linux 2.4, the target device doesn't get passed to any of our
           functions.  So we'll stick it on the end of the options. */
	append_option(options, "device=");
	strcat(options, mop.mo_source);

        if (verbose)
                printf("mounting device %s at %s, flags=%#x options=%s\n",
		       mop.mo_source, mop.mo_target, flags, options);

	if (!strstr(mop.mo_usource, ":/") &&
	    osd_tune_lustre(mop.mo_source, &mop)) {
		if (verbose)
			fprintf(stderr, "%s: unable to set tunables for %s"
					" (may cause reduced IO performance)\n",
					argv[0], mop.mo_source);
	}

	if (!mop.mo_fake) {
                /* flags and target get to lustre_get_sb, but not
                   lustre_fill_super.  Lustre ignores the flags, but mount
                   does not. */
                for (i = 0, rc = -EAGAIN; i <= mop.mo_retry && rc != 0; i++) {
			rc = mount(mop.mo_source, mop.mo_target, "lustre",
				   flags, (void *)options);
			if (rc == 0) {
				/* change label from <fsname>:<index> to
				 * <fsname>-<index> to indicate the device has
				 *  been registered. only if the label is
				 *  supposed to be changed and target service
				 *  is supposed to start */
				if (mop.mo_ldd.ldd_flags &
				   (LDD_F_VIRGIN | LDD_F_WRITECONF)) {
					if (mop.mo_nosvc == 0)
						(void)osd_label_lustre(&mop);
				}
			} else {
                                if (verbose) {
                                        fprintf(stderr, "%s: mount %s at %s "
                                                "failed: %s retries left: "
                                                "%d\n", basename(progname),
						mop.mo_usource, mop.mo_target,
                                                strerror(errno),
						mop.mo_retry - i);
                                }

                                if (mop.mo_retry) {
                                        sleep(1 << max((i/2), 5));
                                }
                                else {
                                        rc = errno;
                                }
                        }
                }
        }

        if (rc) {
                char *cli;

                rc = errno;

		cli = strrchr(mop.mo_usource, ':');
                if (cli && (strlen(cli) > 2))
                        cli += 2;
                else
                        cli = NULL;

                fprintf(stderr, "%s: mount %s at %s failed: %s\n", progname,
			mop.mo_usource, mop.mo_target, strerror(errno));
		if (errno == EBUSY)
			fprintf(stderr, "Is the backend filesystem mounted?\n"
					"Check /etc/mtab and /proc/mounts\n");
                if (errno == ENODEV)
                        fprintf(stderr, "Are the lustre modules loaded?\n"
                                "Check /etc/modprobe.conf and "
                                "/proc/filesystems\n");
                if (errno == ENOTBLK)
                        fprintf(stderr, "Do you need -o loop?\n");
                if (errno == ENOMEDIUM)
                        fprintf(stderr,
                                "This filesystem needs at least 1 OST\n");
                if (errno == ENOENT) {
                        fprintf(stderr, "Is the MGS specification correct?\n");
                        fprintf(stderr, "Is the filesystem name correct?\n");
                        fprintf(stderr, "If upgrading, is the copied client log"
                                " valid? (see upgrade docs)\n");
                }
                if (errno == EALREADY)
                        fprintf(stderr, "The target service is already running."
				" (%s)\n", mop.mo_usource);
                if (errno == ENXIO)
                        fprintf(stderr, "The target service failed to start "
                                "(bad config log?) (%s).  "
				"See /var/log/messages.\n", mop.mo_usource);
                if (errno == EIO)
                        fprintf(stderr, "Is the MGS running?\n");
                if (errno == EADDRINUSE)
                        fprintf(stderr, "The target service's index is already "
				"in use. (%s)\n", mop.mo_usource);
                if (errno == EINVAL) {
                        fprintf(stderr, "This may have multiple causes.\n");
                        if (cli)
                                fprintf(stderr, "Is '%s' the correct filesystem"
                                        " name?\n", cli);
                        fprintf(stderr, "Are the mount options correct?\n");
                        fprintf(stderr, "Check the syslog for more info.\n");
                }

                /* May as well try to clean up loop devs */
		if (strncmp(mop.mo_usource, "/dev/loop", 9) == 0) {
                        char cmd[256];
                        int ret;
			sprintf(cmd, "/sbin/losetup -d %s", mop.mo_usource);
                        if ((ret = system(cmd)) < 0)
                                rc = errno;
                        else if (ret > 0)
                                rc = WEXITSTATUS(ret);
                }

	} else if (!mop.mo_nomtab) {
		rc = update_mtab_entry(mop.mo_usource, mop.mo_target, "lustre",
				       mop.mo_orig_options, 0,0,0);
	}

	free(options);
	/* mo_usource should be freed, but we can rely on the kernel */
	free(mop.mo_source);

	osd_fini();

        return rc;
}
Ejemplo n.º 2
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;
}