mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-23 12:14:15 +08:00
Add fs subtype support to libfuse and fusermount
This commit is contained in:
parent
2b3a22fea0
commit
62c24a8e4b
@ -1,3 +1,7 @@
|
||||
2007-06-20 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* Add fs subtype support to libfuse and fusermount
|
||||
|
||||
2007-06-19 Miklos Szeredi <miklos@szeredi.hu>
|
||||
|
||||
* kernel: sync with mainline (2.6.22)
|
||||
|
@ -160,9 +160,21 @@ void fuse_unmount(const char *mountpoint, struct fuse_chan *ch);
|
||||
int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
|
||||
int *multithreaded, int *foreground);
|
||||
|
||||
|
||||
/**
|
||||
* Go into the background
|
||||
*
|
||||
* @param foreground if true, stay in the foreground
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int fuse_daemonize(int foreground);
|
||||
|
||||
/**
|
||||
* Get the version of the library
|
||||
*
|
||||
* @return the version
|
||||
*/
|
||||
int fuse_version(void);
|
||||
|
||||
/* ----------------------------------------------------------- *
|
||||
* Signal handling *
|
||||
* ----------------------------------------------------------- */
|
||||
|
@ -150,6 +150,7 @@ FUSE_2.7 {
|
||||
fuse_fs_utimens;
|
||||
fuse_fs_write;
|
||||
fuse_register_module;
|
||||
fuse_version;
|
||||
|
||||
local:
|
||||
*;
|
||||
|
29
lib/helper.c
29
lib/helper.c
@ -29,7 +29,7 @@ enum {
|
||||
struct helper_opts {
|
||||
int singlethread;
|
||||
int foreground;
|
||||
int fsname;
|
||||
int nodefault_subtype;
|
||||
char *mountpoint;
|
||||
};
|
||||
|
||||
@ -40,7 +40,8 @@ static const struct fuse_opt fuse_helper_opts[] = {
|
||||
FUSE_HELPER_OPT("debug", foreground),
|
||||
FUSE_HELPER_OPT("-f", foreground),
|
||||
FUSE_HELPER_OPT("-s", singlethread),
|
||||
FUSE_HELPER_OPT("fsname=", fsname),
|
||||
FUSE_HELPER_OPT("fsname=", nodefault_subtype),
|
||||
FUSE_HELPER_OPT("subtype=", nodefault_subtype),
|
||||
|
||||
FUSE_OPT_KEY("-h", KEY_HELP),
|
||||
FUSE_OPT_KEY("--help", KEY_HELP),
|
||||
@ -50,6 +51,7 @@ static const struct fuse_opt fuse_helper_opts[] = {
|
||||
FUSE_OPT_KEY("-d", FUSE_OPT_KEY_KEEP),
|
||||
FUSE_OPT_KEY("debug", FUSE_OPT_KEY_KEEP),
|
||||
FUSE_OPT_KEY("fsname=", FUSE_OPT_KEY_KEEP),
|
||||
FUSE_OPT_KEY("subtype=", FUSE_OPT_KEY_KEEP),
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
@ -117,24 +119,24 @@ static int fuse_helper_opt_proc(void *data, const char *arg, int key,
|
||||
}
|
||||
}
|
||||
|
||||
static int add_default_fsname(const char *progname, struct fuse_args *args)
|
||||
static int add_default_subtype(const char *progname, struct fuse_args *args)
|
||||
{
|
||||
int res;
|
||||
char *fsname_opt;
|
||||
char *subtype_opt;
|
||||
const char *basename = strrchr(progname, '/');
|
||||
if (basename == NULL)
|
||||
basename = progname;
|
||||
else if (basename[1] != '\0')
|
||||
basename++;
|
||||
|
||||
fsname_opt = (char *) malloc(strlen(basename) + 64);
|
||||
if (fsname_opt == NULL) {
|
||||
subtype_opt = (char *) malloc(strlen(basename) + 64);
|
||||
if (subtype_opt == NULL) {
|
||||
fprintf(stderr, "fuse: memory allocation failed\n");
|
||||
return -1;
|
||||
}
|
||||
sprintf(fsname_opt, "-ofsname=%s", basename);
|
||||
res = fuse_opt_add_arg(args, fsname_opt);
|
||||
free(fsname_opt);
|
||||
sprintf(subtype_opt, "-osubtype=%s", basename);
|
||||
res = fuse_opt_add_arg(args, subtype_opt);
|
||||
free(subtype_opt);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -149,8 +151,8 @@ int fuse_parse_cmdline(struct fuse_args *args, char **mountpoint,
|
||||
if (res == -1)
|
||||
return -1;
|
||||
|
||||
if (!hopts.fsname) {
|
||||
res = add_default_fsname(args->argv[0], args);
|
||||
if (!hopts.nodefault_subtype) {
|
||||
res = add_default_subtype(args->argv[0], args);
|
||||
if (res == -1)
|
||||
goto err;
|
||||
}
|
||||
@ -331,6 +333,11 @@ int fuse_main(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fuse_version(void)
|
||||
{
|
||||
return FUSE_VERSION;
|
||||
}
|
||||
|
||||
#include "fuse_compat.h"
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
101
lib/mount.c
101
lib/mount.c
@ -39,6 +39,7 @@ enum {
|
||||
KEY_KERN_FLAG,
|
||||
KEY_KERN_OPT,
|
||||
KEY_FUSERMOUNT_OPT,
|
||||
KEY_SUBTYPE_OPT,
|
||||
KEY_MTAB_OPT,
|
||||
KEY_ALLOW_ROOT,
|
||||
KEY_RO,
|
||||
@ -54,6 +55,8 @@ struct mount_opts {
|
||||
int nonempty;
|
||||
int blkdev;
|
||||
char *fsname;
|
||||
char *subtype;
|
||||
char *subtype_opt;
|
||||
char *mtab_opts;
|
||||
char *fusermount_opts;
|
||||
char *kernel_opts;
|
||||
@ -67,11 +70,13 @@ static const struct fuse_opt fuse_mount_opts[] = {
|
||||
FUSE_MOUNT_OPT("nonempty", nonempty),
|
||||
FUSE_MOUNT_OPT("blkdev", blkdev),
|
||||
FUSE_MOUNT_OPT("fsname=%s", fsname),
|
||||
FUSE_MOUNT_OPT("subtype=%s", subtype),
|
||||
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
|
||||
FUSE_OPT_KEY("allow_root", KEY_ALLOW_ROOT),
|
||||
FUSE_OPT_KEY("nonempty", KEY_FUSERMOUNT_OPT),
|
||||
FUSE_OPT_KEY("blkdev", KEY_FUSERMOUNT_OPT),
|
||||
FUSE_OPT_KEY("fsname=", KEY_FUSERMOUNT_OPT),
|
||||
FUSE_OPT_KEY("subtype=", KEY_SUBTYPE_OPT),
|
||||
FUSE_OPT_KEY("large_read", KEY_KERN_OPT),
|
||||
FUSE_OPT_KEY("blksize=", KEY_KERN_OPT),
|
||||
FUSE_OPT_KEY("default_permissions", KEY_KERN_OPT),
|
||||
@ -107,6 +112,7 @@ static void mount_help(void)
|
||||
" -o nonempty allow mounts over non-empty file/dir\n"
|
||||
" -o default_permissions enable permission checking by kernel\n"
|
||||
" -o fsname=NAME set filesystem name\n"
|
||||
" -o subtype=NAME set filesystem type\n"
|
||||
" -o large_read issue large read requests (2.4 only)\n"
|
||||
" -o max_read=N set maximum size of read requests\n"
|
||||
"\n"
|
||||
@ -196,6 +202,9 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
|
||||
case KEY_FUSERMOUNT_OPT:
|
||||
return fuse_opt_add_opt(&mo->fusermount_opts, arg);
|
||||
|
||||
case KEY_SUBTYPE_OPT:
|
||||
return fuse_opt_add_opt(&mo->subtype_opt, arg);
|
||||
|
||||
case KEY_MTAB_OPT:
|
||||
return fuse_opt_add_opt(&mo->mtab_opts, arg);
|
||||
|
||||
@ -304,7 +313,8 @@ void fuse_unmount_compat22(const char *mountpoint)
|
||||
fuse_kern_unmount(mountpoint, -1);
|
||||
}
|
||||
|
||||
int fuse_mount_compat22(const char *mountpoint, const char *opts)
|
||||
static int fuse_mount_fusermount(const char *mountpoint, const char *opts,
|
||||
int quiet)
|
||||
{
|
||||
int fds[2], pid;
|
||||
int res;
|
||||
@ -334,6 +344,12 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts)
|
||||
const char *argv[32];
|
||||
int a = 0;
|
||||
|
||||
if (quiet) {
|
||||
int fd = open("/dev/null", O_RDONLY);
|
||||
dup2(fd, 1);
|
||||
dup2(fd, 2);
|
||||
}
|
||||
|
||||
argv[a++] = FUSERMOUNT_PROG;
|
||||
if (opts) {
|
||||
argv[a++] = "-o";
|
||||
@ -360,13 +376,18 @@ int fuse_mount_compat22(const char *mountpoint, const char *opts)
|
||||
return rv;
|
||||
}
|
||||
|
||||
int fuse_mount_compat22(const char *mountpoint, const char *opts)
|
||||
{
|
||||
return fuse_mount_fusermount(mountpoint, opts, 0);
|
||||
}
|
||||
|
||||
static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
const char *mnt_opts)
|
||||
{
|
||||
const char *type = mo->blkdev ? "fuseblk" : "fuse";
|
||||
char tmp[128];
|
||||
const char *devname = "/dev/fuse";
|
||||
char *source = NULL;
|
||||
char *type = NULL;
|
||||
struct stat stbuf;
|
||||
int fd;
|
||||
int res;
|
||||
@ -395,9 +416,6 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mo->fsname)
|
||||
devname = mo->fsname;
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "fd=%i,rootmode=%o,user_id=%i,group_id=%i", fd,
|
||||
stbuf.st_mode & S_IFMT, getuid(), getgid());
|
||||
|
||||
@ -405,16 +423,52 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
if (res == -1)
|
||||
goto out_close;
|
||||
|
||||
res = mount(devname, mnt, type, mo->flags, mo->kernel_opts);
|
||||
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)
|
||||
if (errno == EPERM) {
|
||||
res = -2;
|
||||
else
|
||||
perror("fuse: mount failed");
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -424,7 +478,7 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
if (!newmnt)
|
||||
goto out_umount;
|
||||
|
||||
res = fuse_mnt_add_mount("fuse", devname, newmnt, type, mnt_opts);
|
||||
res = fuse_mnt_add_mount("fuse", source, newmnt, type, mnt_opts);
|
||||
free(newmnt);
|
||||
if (res == -1)
|
||||
goto out_umount;
|
||||
@ -435,6 +489,8 @@ static int fuse_mount_sys(const char *mnt, struct mount_opts *mo,
|
||||
out_umount:
|
||||
umount2(mnt, 2); /* lazy umount */
|
||||
out_close:
|
||||
free(type);
|
||||
free(source);
|
||||
close(fd);
|
||||
return res;
|
||||
}
|
||||
@ -460,6 +516,11 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
|
||||
int res = -1;
|
||||
char *mnt_opts = NULL;
|
||||
|
||||
if (!mountpoint) {
|
||||
fprintf(stderr, "fuse: missing mountpoint\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&mo, 0, sizeof(mo));
|
||||
mo.flags = MS_NOSUID | MS_NODEV;
|
||||
|
||||
@ -489,12 +550,30 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
|
||||
fuse_opt_add_opt(&mnt_opts, mo.fusermount_opts) == -1)
|
||||
goto out;
|
||||
|
||||
res = fuse_mount_compat22(mountpoint, mnt_opts);
|
||||
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:
|
||||
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;
|
||||
|
@ -193,3 +193,20 @@ int fuse_mnt_check_empty(const char *progname, const char *mnt,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fuse_mnt_check_fuseblk(void)
|
||||
{
|
||||
char buf[256];
|
||||
FILE *f = fopen("/proc/filesystems", "r");
|
||||
if (!f)
|
||||
return 1;
|
||||
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
if (strstr(buf, "fuseblk\n")) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
@ -14,3 +14,4 @@ int fuse_mnt_umount(const char *progname, const char *mnt, int lazy);
|
||||
char *fuse_mnt_resolve_path(const char *progname, const char *orig);
|
||||
int fuse_mnt_check_empty(const char *progname, const char *mnt,
|
||||
mode_t rootmode, off_t rootsize);
|
||||
int fuse_mnt_check_fuseblk(void);
|
||||
|
@ -74,10 +74,10 @@ static void restore_privs(void)
|
||||
}
|
||||
|
||||
#ifndef IGNORE_MTAB
|
||||
static int add_mount(const char *fsname, const char *mnt, const char *type,
|
||||
static int add_mount(const char *source, const char *mnt, const char *type,
|
||||
const char *opts)
|
||||
{
|
||||
return fuse_mnt_add_mount(progname, fsname, mnt, type, opts);
|
||||
return fuse_mnt_add_mount(progname, source, mnt, type, opts);
|
||||
}
|
||||
|
||||
static int unmount_fuse(const char *mnt, int quiet, int lazy)
|
||||
@ -108,7 +108,9 @@ static int unmount_fuse(const char *mnt, int quiet, int lazy)
|
||||
while ((entp = getmntent(fp)) != NULL) {
|
||||
if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
|
||||
(strcmp(entp->mnt_type, "fuse") == 0 ||
|
||||
strcmp(entp->mnt_type, "fuseblk") == 0)) {
|
||||
strcmp(entp->mnt_type, "fuseblk") == 0 ||
|
||||
strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
|
||||
strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
|
||||
char *p = strstr(entp->mnt_opts, "user=");
|
||||
if (p && (p == entp->mnt_opts || *(p-1) == ',') &&
|
||||
strcmp(p + 5, user) == 0) {
|
||||
@ -150,7 +152,8 @@ static int count_fuse_fs(void)
|
||||
return -1;
|
||||
}
|
||||
while ((entp = getmntent(fp)) != NULL) {
|
||||
if (strcmp(entp->mnt_type, "fuse") == 0)
|
||||
if (strcmp(entp->mnt_type, "fuse") == 0 ||
|
||||
strncmp(entp->mnt_type, "fuse.", 5) == 0)
|
||||
count ++;
|
||||
}
|
||||
endmntent(fp);
|
||||
@ -164,10 +167,10 @@ static int count_fuse_fs()
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int add_mount(const char *fsname, const char *mnt, const char *type,
|
||||
static int add_mount(const char *source, const char *mnt, const char *type,
|
||||
const char *opts)
|
||||
{
|
||||
(void) fsname;
|
||||
(void) source;
|
||||
(void) mnt;
|
||||
(void) type;
|
||||
(void) opts;
|
||||
@ -345,25 +348,26 @@ static int opt_eq(const char *s, unsigned len, const char *opt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int has_fuseblk(void)
|
||||
static int get_string_opt(const char *s, unsigned len, const char *opt,
|
||||
char **val)
|
||||
{
|
||||
char buf[256];
|
||||
FILE *f = fopen("/proc/filesystems", "r");
|
||||
if (!f)
|
||||
return 1;
|
||||
unsigned opt_len = strlen(opt);
|
||||
|
||||
while (fgets(buf, sizeof(buf), f))
|
||||
if (strstr(buf, "fuseblk\n")) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
if (*val)
|
||||
free(*val);
|
||||
*val = (char *) malloc(len - opt_len + 1);
|
||||
if (!*val) {
|
||||
fprintf(stderr, "%s: failed to allocate memory\n", progname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
memcpy(*val, s + opt_len, len - opt_len);
|
||||
(*val)[len - opt_len] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_mount(const char *mnt, const char **type, mode_t rootmode,
|
||||
int fd, const char *opts, const char *dev, char **fsnamep,
|
||||
static int do_mount(const char *mnt, char **typep, mode_t rootmode,
|
||||
int fd, const char *opts, const char *dev, char **sourcep,
|
||||
char **mnt_optsp, off_t rootsize)
|
||||
{
|
||||
int res;
|
||||
@ -373,6 +377,9 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
|
||||
const char *s;
|
||||
char *d;
|
||||
char *fsname = NULL;
|
||||
char *subtype = NULL;
|
||||
char *source = NULL;
|
||||
char *type = NULL;
|
||||
int check_empty = 1;
|
||||
int blkdev = 0;
|
||||
|
||||
@ -385,18 +392,14 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
|
||||
for (s = opts, d = optbuf; *s;) {
|
||||
unsigned len;
|
||||
const char *fsname_str = "fsname=";
|
||||
const char *subtype_str = "subtype=";
|
||||
for (len = 0; s[len] && s[len] != ','; len++);
|
||||
if (begins_with(s, fsname_str)) {
|
||||
unsigned fsname_str_len = strlen(fsname_str);
|
||||
if (fsname)
|
||||
free(fsname);
|
||||
fsname = (char *) malloc(len - fsname_str_len + 1);
|
||||
if (!fsname) {
|
||||
fprintf(stderr, "%s: failed to allocate memory\n", progname);
|
||||
if (!get_string_opt(s, len, fsname_str, &fsname))
|
||||
goto err;
|
||||
} else if (begins_with(s, subtype_str)) {
|
||||
if (!get_string_opt(s, len, subtype_str, &subtype))
|
||||
goto err;
|
||||
}
|
||||
memcpy(fsname, s + fsname_str_len, len - fsname_str_len);
|
||||
fsname[len - fsname_str_len] = '\0';
|
||||
} else if (opt_eq(s, len, "blkdev")) {
|
||||
if (getuid() != 0) {
|
||||
fprintf(stderr, "%s: option blkdev is privileged\n", progname);
|
||||
@ -453,35 +456,58 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
|
||||
|
||||
sprintf(d, "fd=%i,rootmode=%o,user_id=%i,group_id=%i",
|
||||
fd, rootmode, getuid(), getgid());
|
||||
if (fsname == NULL) {
|
||||
fsname = strdup(dev);
|
||||
if (!fsname) {
|
||||
fprintf(stderr, "%s: failed to allocate memory\n", progname);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (check_empty &&
|
||||
fuse_mnt_check_empty(progname, mnt, rootmode, rootsize) == -1)
|
||||
goto err;
|
||||
|
||||
if (blkdev)
|
||||
*type = "fuseblk";
|
||||
res = mount(fsname, mnt, *type, flags, optbuf);
|
||||
source = malloc((fsname ? strlen(fsname) : 0) +
|
||||
(subtype ? strlen(subtype) : 0) + strlen(dev) + 32);
|
||||
|
||||
type = malloc((subtype ? strlen(subtype) : 0) + 32);
|
||||
if (!type || !source) {
|
||||
fprintf(stderr, "%s: failed to allocate memory\n", progname);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (subtype)
|
||||
sprintf(type, "%s.%s", blkdev ? "fuseblk" : "fuse", subtype);
|
||||
else
|
||||
strcpy(type, blkdev ? "fuseblk" : "fuse");
|
||||
|
||||
if (fsname)
|
||||
strcpy(source, fsname);
|
||||
else
|
||||
strcpy(source, subtype ? subtype : dev);
|
||||
|
||||
res = mount(source, mnt, type, flags, optbuf);
|
||||
if (res == -1 && errno == ENODEV && subtype) {
|
||||
/* Probably missing subtype support */
|
||||
strcpy(type, blkdev ? "fuseblk" : "fuse");
|
||||
if (fsname) {
|
||||
if (!blkdev)
|
||||
sprintf(source, "%s#%s", subtype, fsname);
|
||||
} else {
|
||||
strcpy(source, type);
|
||||
}
|
||||
|
||||
res = mount(source, mnt, type, flags, optbuf);
|
||||
}
|
||||
if (res == -1 && errno == EINVAL) {
|
||||
/* It could be an old version not supporting group_id */
|
||||
sprintf(d, "fd=%i,rootmode=%o,user_id=%i", fd, rootmode, getuid());
|
||||
res = mount(fsname, mnt, *type, flags, optbuf);
|
||||
res = mount(source, mnt, type, flags, optbuf);
|
||||
}
|
||||
if (res == -1) {
|
||||
int errno_save = errno;
|
||||
if (blkdev && errno == ENODEV && !has_fuseblk())
|
||||
fprintf(stderr, "%s: 'fuseblk' support missing; try the kernel module from fuse-2.6.0 or later\n", progname);
|
||||
if (blkdev && errno == ENODEV && !fuse_mnt_check_fuseblk())
|
||||
fprintf(stderr, "%s: 'fuseblk' support missing\n", progname);
|
||||
else
|
||||
fprintf(stderr, "%s: mount failed: %s\n", progname, strerror(errno_save));
|
||||
goto err;
|
||||
} else {
|
||||
*fsnamep = fsname;
|
||||
*sourcep = source;
|
||||
*typep = type;
|
||||
*mnt_optsp = mnt_opts;
|
||||
}
|
||||
free(optbuf);
|
||||
@ -490,6 +516,9 @@ static int do_mount(const char *mnt, const char **type, mode_t rootmode,
|
||||
|
||||
err:
|
||||
free(fsname);
|
||||
free(subtype);
|
||||
free(source);
|
||||
free(type);
|
||||
free(mnt_opts);
|
||||
free(optbuf);
|
||||
return -1;
|
||||
@ -666,9 +695,9 @@ static int mount_fuse(const char *mnt, const char *opts)
|
||||
int res;
|
||||
int fd;
|
||||
char *dev;
|
||||
const char *type = "fuse";
|
||||
struct stat stbuf;
|
||||
char *fsname = NULL;
|
||||
char *type = NULL;
|
||||
char *source = NULL;
|
||||
char *mnt_opts = NULL;
|
||||
const char *real_mnt = mnt;
|
||||
int currdir_fd = -1;
|
||||
@ -696,7 +725,7 @@ static int mount_fuse(const char *mnt, const char *opts)
|
||||
restore_privs();
|
||||
if (res != -1)
|
||||
res = do_mount(real_mnt, &type, stbuf.st_mode & S_IFMT, fd, opts,
|
||||
dev, &fsname, &mnt_opts, stbuf.st_size);
|
||||
dev, &source, &mnt_opts, stbuf.st_size);
|
||||
} else
|
||||
restore_privs();
|
||||
|
||||
@ -713,7 +742,7 @@ static int mount_fuse(const char *mnt, const char *opts)
|
||||
}
|
||||
|
||||
if (geteuid() == 0) {
|
||||
res = add_mount(fsname, mnt, type, mnt_opts);
|
||||
res = add_mount(source, mnt, type, mnt_opts);
|
||||
if (res == -1) {
|
||||
umount2(mnt, 2); /* lazy umount */
|
||||
close(fd);
|
||||
@ -721,7 +750,8 @@ static int mount_fuse(const char *mnt, const char *opts)
|
||||
}
|
||||
}
|
||||
|
||||
free(fsname);
|
||||
free(source);
|
||||
free(type);
|
||||
free(mnt_opts);
|
||||
free(dev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user