示例#1
0
文件: mount.c 项目: atinmu/glusterfs
int
gf_fuse_mount (const char *mountpoint, char *fsname,
               unsigned long mountflags, char *mnt_param,
               pid_t *mnt_pid, int status_fd)
{
        int   fd  = -1;
        pid_t pid = -1;
        int   ret = -1;

        fd = open ("/dev/fuse", O_RDWR);
        if (fd == -1) {
                GFFUSE_LOGERR ("cannot open /dev/fuse (%s)",
                                strerror (errno));
                return -1;
        }

        /* start mount agent */
        pid = fork();
        switch (pid) {
        case 0:
                /* hello it's mount agent */
                if (!mnt_pid) {
                        /* daemonize mount agent, caller is
                         * not interested in waiting for it
                         */
                        pid = fork ();
                        if (pid)
                                exit (pid == -1 ? 1 : 0);
                }

                ret = fuse_mount_sys (mountpoint, fsname, mountflags, mnt_param,
                                      fd);
                if (ret == -1) {
                        gf_log ("glusterfs-fuse", GF_LOG_INFO,
                                "direct mount failed (%s) errno %d, "
                                "retry to mount via fusermount",
                                strerror (errno), errno);

                        ret = fuse_mount_fusermount (mountpoint, fsname,
                                                     mountflags, mnt_param, fd);
                }

                if (ret == -1)
                        GFFUSE_LOGERR ("mount of %s to %s (%s) failed",
                                       fsname, mountpoint, mnt_param);

                if (status_fd >= 0)
                        (void)write (status_fd, &ret, sizeof (ret));
                exit (!!ret);
                /* bye mount agent */
        case -1:
                close (fd);
                fd = -1;
        }

        if (mnt_pid)
               *mnt_pid = pid;

        return fd;
}
示例#2
0
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
    struct mount_opts mo;
    int res = -1;
    char *mnt_opts = NULL;
#ifdef __SOLARIS__
    struct solaris_mount_opts smo;
    struct fuse_args sa = FUSE_ARGS_INIT(0, NULL);
#endif /* __SOLARIS__ */

    memset(&mo, 0, sizeof(mo));
#ifdef __SOLARIS__
    mo.flags = 0;
    memset(&smo, 0, sizeof(smo));
    if (args != NULL) {
    	while (args->argv[sa.argc] != NULL)
		fuse_opt_add_arg(&sa, args->argv[sa.argc]);
    }
#else
    mo.flags = MS_NOSUID | MS_NODEV;
#endif /* __SOLARIS__ */

    if (args &&
        fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
        goto out; /* if SOLARIS, clean up 'sa' */

#ifdef __SOLARIS__
    /*
     * In Solaris, nosuid is equivalent to nosetuid + nodevices. We only
     * have MS_NOSUID for mount flags (no MS_(NO)SETUID, etc.). But if
     * we set that as a default, it restricts specifying just nosetuid
     * or nodevices; there is no way for the user to specify setuid +
     * nodevices or vice-verse. So we parse the existing options, then
     * add restrictive defaults if needed.
     */
    if (fuse_opt_parse(&sa, &smo, solaris_mnt_opts, NULL) == -1)
         goto out;
    if (smo.nosuid || (!smo.nodevices && !smo.devices
        && !smo.nosetuid && !smo.setuid)) {
        mo.flags |= MS_NOSUID;
    } else {
        /*
         * Defaults; if neither nodevices|devices,nosetuid|setuid has
         * been specified, add the default negative option string. If
         * both have been specified (i.e., -osuid,nosuid), leave them
         * alone; the last option will have precedence.
         */
        if (!smo.nodevices && !smo.devices)
             if (fuse_opt_add_opt(&mo.kernel_opts, "nodevices") == -1)
                 goto out;
        if (!smo.nosetuid && !smo.setuid)
            if (fuse_opt_add_opt(&mo.kernel_opts, "nosetuid") == -1)
                 goto out;
    }
#endif /* __SOLARIS__ */

    if (mo.allow_other && mo.allow_root) {
        fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
        goto out;
    }
    res = 0;
    if (mo.ishelp)
        goto out;

    res = -1;
    if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
        goto out;
    if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
        goto out;
    if (mo.mtab_opts &&  fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
        goto out;

    res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
    if (res == -2) {
        if (mo.fusermount_opts &&
            fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
            goto out;

        if (mo.subtype) {
            char *tmp_opts = NULL;

            res = -1;
            if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
                fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
                free(tmp_opts);
                goto out;
            }

            res = fuse_mount_fusermount(mountpoint, tmp_opts, 1);
            free(tmp_opts);
            if (res == -1)
                res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
        } else {
            res = fuse_mount_fusermount(mountpoint, mnt_opts, 0);
        }
    }
 out:
#ifdef __SOLARIS__
    fuse_opt_free_args(&sa);
#endif /* __SOLARIS__ */
    free(mnt_opts);
    free(mo.fsname);
    free(mo.subtype);
    free(mo.fusermount_opts);
    free(mo.subtype_opt);
    free(mo.kernel_opts);
    free(mo.mtab_opts);
    return res;
}
示例#3
0
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
{
	struct mount_opts mo;
	int res = -1;
	char *mnt_opts = NULL;

	memset(&mo, 0, sizeof(mo));
	mo.flags = MS_NOSUID | MS_NODEV;

	if (args &&
	    fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
		return -1;

	if (mo.allow_other && mo.allow_root) {
		fprintf(stderr, "fuse: 'allow_other' and 'allow_root' options are mutually exclusive\n");
		goto out;
	}
	res = 0;
	if (mo.ishelp)
		goto out;

	res = -1;
	if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
		goto out;
	if (mo.kernel_opts && fuse_opt_add_opt(&mnt_opts, mo.kernel_opts) == -1)
		goto out;
	if (mo.mtab_opts &&  fuse_opt_add_opt(&mnt_opts, mo.mtab_opts) == -1)
		goto out;

	res = fuse_mount_sys(mountpoint, &mo, mnt_opts);
	if (res == -2) {
		if (mo.fusermount_opts &&
		    fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
			goto out;

		if (mo.subtype) {
			char *tmp_opts = NULL;

			res = -1;
			if (fuse_opt_add_opt(&tmp_opts, mnt_opts) == -1 ||
			    fuse_opt_add_opt(&tmp_opts, mo.subtype_opt) == -1) {
				free(tmp_opts);
				goto out;
			}

			res = fuse_mount_fusermount(mountpoint, &mo, tmp_opts, 1);
			free(tmp_opts);
			if (res == -1)
				res = fuse_mount_fusermount(mountpoint, &mo,
							    mnt_opts, 0);
		} else {
			res = fuse_mount_fusermount(mountpoint, &mo, mnt_opts, 0);
		}
	}
out:
	free(mnt_opts);
	free(mo.fsname);
	free(mo.subtype);
	free(mo.fusermount_opts);
	free(mo.subtype_opt);
	free(mo.kernel_opts);
	free(mo.mtab_opts);
	return res;
}