예제 #1
0
/**
 * mnt_context_prepare_mount:
 * @cxt: context
 *
 * Prepare context for mounting, unnecessary for mnt_context_mount().
 *
 * Returns: negative number on error, zero on success
 */
int mnt_context_prepare_mount(struct libmnt_context *cxt)
{
	int rc = -EINVAL;

	assert(cxt);
	assert(cxt->fs);
	assert(cxt->helper_exec_status == 1);
	assert(cxt->syscall_status == 1);

	if (!cxt || !cxt->fs || mnt_fs_is_swaparea(cxt->fs))
		return -EINVAL;
	if (!mnt_fs_get_source(cxt->fs) && !mnt_fs_get_target(cxt->fs))
		return -EINVAL;
	if (cxt->flags & MNT_FL_PREPARED)
		return 0;

	cxt->action = MNT_ACT_MOUNT;

	DBG(CXT, mnt_debug_h(cxt, "mount: preparing"));

	/* TODO: fstab is unnecessary for MS_{MOVE,BIND,STARED,...} */
	rc = mnt_context_apply_fstab(cxt);
	if (!rc)
		rc = mnt_context_merge_mflags(cxt);
	if (!rc)
		rc = evaluate_permissions(cxt);
	if (!rc)
		rc = fix_optstr(cxt);
	if (!rc)
		rc = mnt_context_prepare_srcpath(cxt);
	if (!rc)
		rc = mnt_context_prepare_target(cxt);
	if (!rc)
		rc = mnt_context_guess_fstype(cxt);
	if (!rc)
		rc = mnt_context_prepare_helper(cxt, "mount", NULL);
	if (rc) {
		DBG(CXT, mnt_debug_h(cxt, "mount: preparing failed"));
		return rc;
	}
	cxt->flags |= MNT_FL_PREPARED;
	return rc;
}
예제 #2
0
static int mount_main(struct libmnt_context *cxt, int argc, char **argv)
{
	int rc, c;
	struct libmnt_fs *fs;
	char *spec = NULL, *mount_point = NULL, *opts = NULL;

	static const struct option longopts[] = {
	  { "fake", 0, 0, 'f' },
	  { "help", 0, 0, 'h' },
	  { "no-mtab", 0, 0, 'n' },
	  { "read-only", 0, 0, 'r' },
	  { "ro", 0, 0, 'r' },
	  { "verbose", 0, 0, 'v' },
	  { "version", 0, 0, 'V' },
	  { "read-write", 0, 0, 'w' },
	  { "rw", 0, 0, 'w' },
	  { "options", 1, 0, 'o' },
	  { "sloppy", 0, 0, 's' },
	  { NULL, 0, 0, 0 }
	};

	mount_config_init(progname);
	mnt_context_init_helper(cxt, MNT_ACT_MOUNT, 0);

	while ((c = getopt_long(argc, argv, "fhnrVvwo:s", longopts, NULL)) != -1) {

		rc = mnt_context_helper_setopt(cxt, c, optarg);
		if (rc == 0)		/* valid option */
			continue;
		if (rc < 0)		/* error (probably ENOMEM) */
			goto err;
					/* rc==1 means unknow option */
		switch (c) {
		case 'V':
			printf("%s: ("PACKAGE_STRING")\n", progname);
			return EX_SUCCESS;
		case 'h':
		default:
			mount_usage();
			return EX_USAGE;
		}
	}

	if (optind < argc)
		spec = argv[optind++];
	if (optind < argc)
		mount_point = argv[optind++];

	if (!mount_point) {
		nfs_error(_("%s: no mount point provided"), progname);
		goto err;
	}
	if (!spec) {
		nfs_error(_("%s: no mount spec provided"), progname);
		goto err;
	}

	if (geteuid() != 0) {
		nfs_error(_("%s: not installed setuid - "
			    "\"user\" NFS mounts not supported."), progname);
		goto err;
	}

	verbose = mnt_context_is_verbose(cxt);
	sloppy = mnt_context_is_sloppy(cxt);
	nomtab = mnt_context_is_nomtab(cxt);

	if (strcmp(progname, "mount.nfs4") == 0)
		mnt_context_set_fstype(cxt, "nfs4");
	else
		mnt_context_set_fstype(cxt, "nfs");	/* default */

	rc = mnt_context_set_source(cxt, spec);
	if (!rc)
		mnt_context_set_target(cxt, mount_point);
	if (rc) {
		nfs_error(_("%s: failed to set spec or mountpoint: %s"),
				progname, strerror(errno));
		goto err;
	}

	mount_point = mnt_resolve_path(mount_point,
				       mnt_context_get_cache(cxt));

	if (chk_mountpoint(mount_point))
		goto err;

	/*
	 * The libmount strictly uses only options from fstab if running in
	 * restricted mode (suid, non-root user). This is done in
	 * mnt_context_prepare_mount() by default.
	 *
	 * We have to read fstab before nfsmount.conf, otherwise the options
	 * from nfsmount.conf will be ignored (overwrited).
	 */
	rc = mnt_context_apply_fstab(cxt);
	if (rc) {
		nfs_error(_("%s: failed to apply fstab options\n"), progname);
		goto err;
	}

	/*
	 * Concatenate mount options from the configuration file
	 */
	fs = mnt_context_get_fs(cxt);
	if (fs) {
		opts = mnt_fs_strdup_options(fs);

		opts = mount_config_opts(spec, mount_point, opts);
		mnt_fs_set_options(fs, opts);
	}

	rc = mnt_context_prepare_mount(cxt);
	if (rc) {
		nfs_error(_("%s: failed to prepare mount: %s\n"),
					progname, strerror(-rc));
		goto err;
	}

	rc = try_mount(cxt, FOREGROUND);

	if (rc == EX_BG) {
		printf(_("%s: backgrounding \"%s\"\n"),
			progname, mnt_context_get_source(cxt));
		printf(_("%s: mount options: \"%s\"\n"),
			progname, opts);

		fflush(stdout);

		if (daemon(0, 0)) {
			nfs_error(_("%s: failed to start "
					"background process: %s\n"),
					progname, strerror(errno));
			exit(EX_FAIL);
		}

		rc = try_mount(cxt, BACKGROUND);

		if (verbose && rc)
			printf(_("%s: giving up \"%s\"\n"),
				progname, mnt_context_get_source(cxt));
	}

	mnt_context_set_syscall_status(cxt, rc == EX_SUCCESS ? 0 : -1);
	mnt_context_finalize_mount(cxt);	/* mtab update */
	return rc;
err:
	return EX_FAIL;
}