예제 #1
0
파일: mount.c 프로젝트: atinmu/glusterfs
static int
fuse_mount_sys (const char *mountpoint, char *fsname,
                unsigned long mountflags, char *mnt_param, int fd)
{
        int ret = -1;
        unsigned mounted = 0;
        char *mnt_param_mnt = NULL;
        char *fstype = "fuse.glusterfs";
        char *source = fsname;

        ret = asprintf (&mnt_param_mnt,
                        "%s,fd=%i,rootmode=%o,user_id=%i,group_id=%i",
                        mnt_param, fd, S_IFDIR, getuid (), getgid ());
        if (ret == -1) {
                GFFUSE_LOGERR ("Out of memory");

                goto out;
        }

#ifdef __FreeBSD__
        struct iovec *iov = NULL;
        int iovlen = 0;
        build_iovec (&iov, &iovlen, "fstype", "fusefs", -1);
        build_iovec (&iov, &iovlen, "subtype", "glusterfs", -1);
        build_iovec (&iov, &iovlen, "fspath", mountpoint, -1);
        build_iovec (&iov, &iovlen, "from", "/dev/fuse", -1);
        build_iovec (&iov, &iovlen, "volname", source, -1);
        build_iovec_argf (&iov, &iovlen, "fd", "%d", fd);
        build_iovec_argf (&iov, &iovlen, "user_id", "%d", getuid());
        build_iovec_argf (&iov, &iovlen, "group_id", "%d", getgid());
        ret = nmount (iov, iovlen, mountflags);
#else
        ret = mount (source, mountpoint, fstype, mountflags,
                     mnt_param_mnt);
#endif /* __FreeBSD__ */
#ifdef GF_LINUX_HOST_OS
        if (ret == -1 && errno == ENODEV) {
                /* fs subtype support was added by 79c0b2df aka
                   v2.6.21-3159-g79c0b2d. Probably we have an
                   older kernel ... */
                fstype = "fuse";
                ret = asprintf (&source, "glusterfs#%s", fsname);
                if (ret == -1) {
                        GFFUSE_LOGERR ("Out of memory");

                        goto out;
                }
                ret = mount (source, mountpoint, fstype, mountflags,
                             mnt_param_mnt);
        }
#endif /* GF_LINUX_HOST_OS */
        if (ret == -1)
                goto out;
        else
                mounted = 1;

#ifdef GF_LINUX_HOST_OS
        if (geteuid () == 0) {
                char *newmnt = fuse_mnt_resolve_path ("fuse", mountpoint);
                char *mnt_param_mtab = NULL;

                if (!newmnt) {
                        ret = -1;

                        goto out;
                }

                ret = asprintf (&mnt_param_mtab, "%s%s",
                                mountflags & MS_RDONLY ? "ro," : "",
                                mnt_param);
                if (ret == -1)
                        GFFUSE_LOGERR ("Out of memory");
                else {
                        ret = fuse_mnt_add_mount ("fuse", source, newmnt,
                                                  fstype, mnt_param_mtab);
                        FREE (mnt_param_mtab);
                }

                FREE (newmnt);
                if (ret == -1) {
                        GFFUSE_LOGERR ("failed to add mtab entry");

                        goto out;
                }
        }
#endif /* GF_LINUX_HOST_OS */

out:
        if (ret == -1) {
                GFFUSE_LOGERR("ret = -1\n");
                if (mounted)
                        umount2 (mountpoint, 2); /* lazy umount */
        }
        FREE (mnt_param_mnt);
        if (source != fsname)
                FREE (source);

        return ret;
}
예제 #2
0
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
                          const char *mnt_opts)
{
    char tmp[128];
    const char *devname = "/dev/fuse";
    char *source = NULL;
    char *type = NULL;
    struct stat stbuf;
    int fd;
    int res;

    if (!mnt) {
        fprintf(stderr, "fuse: missing mountpoint\n");
        return -1;
    }

    res = lstat(mnt, &stbuf);
    if (res == -1) {
        fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
                mnt, strerror(errno));
        return -1;
    }

    if (!mo->nonempty) {
        res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode, stbuf.st_size);
        if (res == -1)
            return -1;
    }

    fd = open(devname, O_RDWR);
    if (fd == -1) {
        if (errno == ENODEV || errno == ENOENT)
            fprintf(stderr,
                    "fuse: device not found, try 'modprobe fuse' first\n");
        else
            fprintf(stderr, "fuse: failed to open %s: %s\n", devname,
                    strerror(errno));
        return -1;
    }

    snprintf(tmp, sizeof(tmp),  "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
             stbuf.st_mode & S_IFMT, getuid(), getgid());

    res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
    if (res == -1)
        goto out_close;

    source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
                    (mo->subtype ? strlen(mo->subtype) : 0) +
                    strlen(devname) + 32);

    type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
    if (!type || !source) {
        fprintf(stderr, "fuse: failed to allocate memory\n");
        goto out_close;
    }

    strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
    if (mo->subtype) {
        strcat(type, ".");
        strcat(type, mo->subtype);
    }
    strcpy(source,
           mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));

#ifdef __SOLARIS__
	res = mount(source, mnt, MS_OPTIONSTR|mo->flags, type, NULL, 0,
	    mo->kernel_opts, MAX_MNTOPT_STR);
#else
    res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
#endif /* __SOLARIS__ */

#ifdef __SOLARIS__
    if (res == -1 && errno == EINVAL && mo->subtype) {
#else
    if (res == -1 && errno == ENODEV && mo->subtype) {
#endif
        /* Probably missing subtype support */
        strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
        if (mo->fsname) {
            if (!mo->blkdev)
                sprintf(source, "%s#%s", mo->subtype, mo->fsname);
        } else {
            strcpy(source, type);
        }
#ifdef __SOLARIS__
		res = mount(source, mnt, MS_OPTIONSTR|mo->flags, type, NULL, 0,
		    mo->kernel_opts, MAX_MNTOPT_STR);
#else
        res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
#endif /* __SOLARIS__ */
    }
    if (res == -1) {
        /*
         * Maybe kernel doesn't support unprivileged mounts, in this
         * case try falling back to fusermount
         */
        if (errno == EPERM) {
            res = -2;
        } else {
            int errno_save = errno;
            if (mo->blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
                fprintf(stderr, "fuse: 'fuseblk' support missing\n");
            else
                fprintf(stderr, "fuse: mount failed: %s\n",
                        strerror(errno_save));
        }

        goto out_close;
    }

#ifndef __SOLARIS__
    if (geteuid() == 0) {
        char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
        res = -1;
        if (!newmnt)
            goto out_umount;

        res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts);
        free(newmnt);
        if (res == -1)
            goto out_umount;
    }
#endif /* __SOLARIS__ */

    return fd;

 out_umount:
    umount2(mnt, 2); /* lazy umount */
 out_close:
    free(type);
    free(source);
    close(fd);
    return res;
}

static int get_mnt_flag_opts(char **mnt_optsp, int flags)
{
    int i;

    if (!(flags & MS_RDONLY) && fuse_opt_add_opt(mnt_optsp, "rw") == -1)
        return -1;

    for (i = 0; mount_flags[i].opt != NULL; i++) {
        if (mount_flags[i].on && (flags & mount_flags[i].flag) &&
	    fuse_opt_add_opt(mnt_optsp, mount_flags[i].opt) == -1)
                return -1;
    }
    return 0;
}
예제 #3
0
static int add_mount(const char *source, const char *mnt, const char *type,
		     const char *opts)
{
	return fuse_mnt_add_mount(progname, source, mnt, type, opts);
}
예제 #4
0
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
			  const char *mnt_opts)
{
	char tmp[128];
	const char *devname = "/dev/fuse";
	char *source = NULL;
	char *type = NULL;
	struct stat stbuf;
	int fd;
	int res;

	if (!mnt) {
		fprintf(stderr, "fuse: missing mountpoint parameter\n");
		return -1;
	}

	res = stat(mnt, &stbuf);
	if (res == -1) {
		fprintf(stderr ,"fuse: failed to access mountpoint %s: %s\n",
			mnt, strerror(errno));
		return -1;
	}

	if (!mo->nonempty) {
		res = fuse_mnt_check_empty("fuse", mnt, stbuf.st_mode,
					   stbuf.st_size);
		if (res == -1)
			return -1;
	}

	if (mo->auto_unmount) {
		/* Tell the caller to fallback to fusermount because
		   auto-unmount does not work otherwise. */
		return -2;
	}

	fd = open(devname, O_RDWR);
	if (fd == -1) {
		if (errno == ENODEV || errno == ENOENT)
			fprintf(stderr, "fuse: device not found, try 'modprobe fuse' first\n");
		else
			fprintf(stderr, "fuse: failed to open %s: %s\n",
				devname, strerror(errno));
		return -1;
	}

	snprintf(tmp, sizeof(tmp),  "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
		 fd, stbuf.st_mode & S_IFMT, getuid(), getgid());

	res = fuse_opt_add_opt(&mo->kernel_opts, tmp);
	if (res == -1)
		goto out_close;

	source = malloc((mo->fsname ? strlen(mo->fsname) : 0) +
			(mo->subtype ? strlen(mo->subtype) : 0) +
			strlen(devname) + 32);

	type = malloc((mo->subtype ? strlen(mo->subtype) : 0) + 32);
	if (!type || !source) {
		fprintf(stderr, "fuse: failed to allocate memory\n");
		goto out_close;
	}

	strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
	if (mo->subtype) {
		strcat(type, ".");
		strcat(type, mo->subtype);
	}
	strcpy(source,
	       mo->fsname ? mo->fsname : (mo->subtype ? mo->subtype : devname));

	res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
	if (res == -1 && errno == ENODEV && mo->subtype) {
		/* Probably missing subtype support */
		strcpy(type, mo->blkdev ? "fuseblk" : "fuse");
		if (mo->fsname) {
			if (!mo->blkdev)
				sprintf(source, "%s#%s", mo->subtype,
					mo->fsname);
		} else {
			strcpy(source, type);
		}
		res = mount(source, mnt, type, mo->flags, mo->kernel_opts);
	}
	if (res == -1) {
		/*
		 * Maybe kernel doesn't support unprivileged mounts, in this
		 * case try falling back to fusermount
		 */
		if (errno == EPERM) {
			res = -2;
		} else {
			int errno_save = errno;
			if (mo->blkdev && errno == ENODEV &&
			    !fuse_mnt_check_fuseblk())
				fprintf(stderr,
					"fuse: 'fuseblk' support missing\n");
			else
				fprintf(stderr, "fuse: mount failed: %s\n",
					strerror(errno_save));
		}

		goto out_close;
	}

#ifndef __NetBSD__
#ifndef IGNORE_MTAB
	if (geteuid() == 0) {
		char *newmnt = fuse_mnt_resolve_path("fuse", mnt);
		res = -1;
		if (!newmnt)
			goto out_umount;

		res = fuse_mnt_add_mount("fuse", source, newmnt, type,
					 mnt_opts);
		free(newmnt);
		if (res == -1)
			goto out_umount;
	}
#endif /* IGNORE_MTAB */
#endif /* __NetBSD__ */
	free(type);
	free(source);

	return fd;

out_umount:
	umount2(mnt, 2); /* lazy umount */
out_close:
	free(type);
	free(source);
	close(fd);
	return res;
}