Browse Source

Misc updates to arg parsing (#1554)

Ignore "defaults" and add a number of more modern VFS mount switches
pull/1555/head
trapexit 2 weeks ago
committed by GitHub
parent
commit
cfaad60275
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      Makefile
  2. 201
      libfuse/lib/mount_generic.c
  3. 97
      libfuse/util/fusermount.c
  4. 1
      src/config.cpp
  5. 4
      tests/tests.cpp

2
Makefile

@ -69,7 +69,7 @@ OBJS := $(SRC:src/%.cpp=build/.objs/%.cpp.o)
DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d) DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d)
TESTS := $(wildcard tests/*.cpp) TESTS := $(wildcard tests/*.cpp)
TESTS_OBJS := $(filter-out build/.objs/mergerfs.o,$(OBJS))
TESTS_OBJS := $(filter-out build/.objs/mergerfs.cpp.o,$(OBJS))
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.o) TESTS_OBJS += $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.o)
TESTS_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d) TESTS_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d)
TESTS_DEPS += $(DEPS) TESTS_DEPS += $(DEPS)

201
libfuse/lib/mount_generic.c

@ -49,14 +49,11 @@ enum {
KEY_FUSERMOUNT_OPT, KEY_FUSERMOUNT_OPT,
KEY_SUBTYPE_OPT, KEY_SUBTYPE_OPT,
KEY_MTAB_OPT, KEY_MTAB_OPT,
KEY_RO,
KEY_HELP,
KEY_VERSION,
KEY_RO
}; };
struct mount_opts { struct mount_opts {
int allow_other; int allow_other;
int ishelp;
int flags; int flags;
int auto_unmount; int auto_unmount;
int blkdev; int blkdev;
@ -70,59 +67,54 @@ struct mount_opts {
#define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 } #define FUSE_MOUNT_OPT(t, p) { t, offsetof(struct mount_opts, p), 1 }
static const struct fuse_opt fuse_mount_opts[] = {
FUSE_MOUNT_OPT("allow_other", allow_other),
FUSE_MOUNT_OPT("blkdev", blkdev),
FUSE_MOUNT_OPT("auto_unmount", auto_unmount),
FUSE_MOUNT_OPT("fsname=%s", fsname),
FUSE_MOUNT_OPT("subtype=%s", subtype),
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
FUSE_OPT_KEY("auto_unmount", 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),
FUSE_OPT_KEY("context=", KEY_KERN_OPT),
FUSE_OPT_KEY("fscontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("defcontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("rootcontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
FUSE_OPT_KEY("-r", KEY_RO),
FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
FUSE_OPT_KEY("async", KEY_KERN_FLAG),
FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
FUSE_OPT_KEY("-h", KEY_HELP),
FUSE_OPT_KEY("--help", KEY_HELP),
FUSE_OPT_KEY("-V", KEY_VERSION),
FUSE_OPT_KEY("--version", KEY_VERSION),
FUSE_OPT_END
};
static void mount_help(void)
{
fprintf(stderr,
" -o auto_unmount auto unmount on process termination\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");
}
static
const
struct fuse_opt fuse_mount_opts[] =
{
FUSE_MOUNT_OPT("allow_other", allow_other),
FUSE_MOUNT_OPT("blkdev", blkdev),
FUSE_MOUNT_OPT("auto_unmount", auto_unmount),
FUSE_MOUNT_OPT("fsname=%s", fsname),
FUSE_MOUNT_OPT("subtype=%s", subtype),
FUSE_OPT_KEY("allow_other", KEY_KERN_OPT),
FUSE_OPT_KEY("auto_unmount", 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),
FUSE_OPT_KEY("context=", KEY_KERN_OPT),
FUSE_OPT_KEY("fscontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("defcontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("rootcontext=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", KEY_KERN_OPT),
FUSE_OPT_KEY("max_read=", FUSE_OPT_KEY_KEEP),
FUSE_OPT_KEY("user=", KEY_MTAB_OPT),
FUSE_OPT_KEY("-r", KEY_RO),
FUSE_OPT_KEY("ro", KEY_KERN_FLAG),
FUSE_OPT_KEY("rw", KEY_KERN_FLAG),
FUSE_OPT_KEY("suid", KEY_KERN_FLAG),
FUSE_OPT_KEY("nosuid", KEY_KERN_FLAG),
FUSE_OPT_KEY("dev", KEY_KERN_FLAG),
FUSE_OPT_KEY("nodev", KEY_KERN_FLAG),
FUSE_OPT_KEY("exec", KEY_KERN_FLAG),
FUSE_OPT_KEY("noexec", KEY_KERN_FLAG),
FUSE_OPT_KEY("async", KEY_KERN_FLAG),
FUSE_OPT_KEY("sync", KEY_KERN_FLAG),
FUSE_OPT_KEY("dirsync", KEY_KERN_FLAG),
FUSE_OPT_KEY("atime", KEY_KERN_FLAG),
FUSE_OPT_KEY("noatime", KEY_KERN_FLAG),
FUSE_OPT_KEY("relatime", KEY_KERN_FLAG),
FUSE_OPT_KEY("norelatime", KEY_KERN_FLAG),
FUSE_OPT_KEY("lazytime", KEY_KERN_FLAG),
FUSE_OPT_KEY("nolazytime", KEY_KERN_FLAG),
FUSE_OPT_KEY("diratime", KEY_KERN_FLAG),
FUSE_OPT_KEY("nodiratime", KEY_KERN_FLAG),
FUSE_OPT_KEY("strictatime", KEY_KERN_FLAG),
FUSE_OPT_KEY("nostrictatime", KEY_KERN_FLAG),
FUSE_OPT_END
};
static void exec_fusermount(const char *argv[]) static void exec_fusermount(const char *argv[])
{ {
@ -132,56 +124,63 @@ static void exec_fusermount(const char *argv[])
execvp(FUSERMOUNT_PROG, (char **) argv); execvp(FUSERMOUNT_PROG, (char **) argv);
} }
static void mount_version(void)
{
int pid = fork();
if (!pid) {
const char *argv[] = { FUSERMOUNT_PROG, "--version", NULL };
exec_fusermount(argv);
_exit(1);
} else if (pid != -1)
waitpid(pid, NULL, 0);
}
struct mount_flags { struct mount_flags {
const char *opt; const char *opt;
unsigned long flag; unsigned long flag;
int on; int on;
}; };
static const struct mount_flags mount_flags[] = {
{"rw", MS_RDONLY, 0},
{"ro", MS_RDONLY, 1},
{"suid", MS_NOSUID, 0},
{"nosuid", MS_NOSUID, 1},
{"dev", MS_NODEV, 0},
{"nodev", MS_NODEV, 1},
{"exec", MS_NOEXEC, 0},
{"noexec", MS_NOEXEC, 1},
{"async", MS_SYNCHRONOUS, 0},
{"sync", MS_SYNCHRONOUS, 1},
{"atime", MS_NOATIME, 0},
{"noatime", MS_NOATIME, 1},
static
const
struct mount_flags
mount_flags[] =
{
{"rw", MS_RDONLY, 0},
{"ro", MS_RDONLY, 1},
{"suid", MS_NOSUID, 0},
{"nosuid", MS_NOSUID, 1},
{"dev", MS_NODEV, 0},
{"nodev", MS_NODEV, 1},
{"exec", MS_NOEXEC, 0},
{"noexec", MS_NOEXEC, 1},
{"async", MS_SYNCHRONOUS, 0},
{"sync", MS_SYNCHRONOUS, 1},
{"atime", MS_NOATIME, 0},
{"noatime", MS_NOATIME, 1},
{"relatime", MS_RELATIME, 1},
{"norelatime", MS_RELATIME, 0},
{"lazytime", MS_LAZYTIME, 1},
{"nolazytime", MS_LAZYTIME, 0},
{"diratime", MS_NODIRATIME, 0},
{"nodiratime", MS_NODIRATIME, 1},
{"strictatime", MS_STRICTATIME, 1},
{"nostrictatime",MS_STRICTATIME, 0},
#ifndef __NetBSD__ #ifndef __NetBSD__
{"dirsync", MS_DIRSYNC, 1},
{"dirsync", MS_DIRSYNC, 1},
#endif #endif
{NULL, 0, 0}
};
{NULL, 0, 0}
};
static void set_mount_flag(const char *s, int *flags)
static
void
set_mount_flag(const char *s,
int *flags)
{ {
int i; int i;
for (i = 0; mount_flags[i].opt != NULL; i++) {
const char *opt = mount_flags[i].opt;
if (strcmp(opt, s) == 0) {
if (mount_flags[i].on)
*flags |= mount_flags[i].flag;
else
*flags &= ~mount_flags[i].flag;
return;
for (i = 0; mount_flags[i].opt != NULL; i++)
{
const char *opt = mount_flags[i].opt;
if(strcmp(opt, s) == 0)
{
if(mount_flags[i].on)
*flags |= mount_flags[i].flag;
else
*flags &= ~mount_flags[i].flag;
return;
}
} }
}
fprintf(stderr, "fuse: internal error, can't find mount flag\n"); fprintf(stderr, "fuse: internal error, can't find mount flag\n");
abort(); abort();
} }
@ -211,16 +210,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
case KEY_MTAB_OPT: case KEY_MTAB_OPT:
return fuse_opt_add_opt(&mo->mtab_opts, arg); return fuse_opt_add_opt(&mo->mtab_opts, arg);
case KEY_HELP:
mount_help();
mo->ishelp = 1;
break;
case KEY_VERSION:
mount_version();
mo->ishelp = 1;
break;
} }
return 1; return 1;
} }
@ -547,10 +536,6 @@ int fuse_kern_mount(const char *mountpoint, struct fuse_args *args)
fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1) fuse_opt_parse(args, &mo, fuse_mount_opts, fuse_mount_opt_proc) == -1)
return -1; return -1;
res = 0;
if (mo.ishelp)
goto out;
res = -1; res = -1;
if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1) if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
goto out; goto out;

97
libfuse/util/fusermount.c

@ -579,49 +579,66 @@ static int begins_with(const char *s, const char *beg)
return 0; return 0;
} }
struct mount_flags {
const char *opt;
unsigned long flag;
int on;
int safe;
};
static struct mount_flags mount_flags[] = {
{"rw", MS_RDONLY, 0, 1},
{"ro", MS_RDONLY, 1, 1},
{"suid", MS_NOSUID, 0, 0},
{"nosuid", MS_NOSUID, 1, 1},
{"dev", MS_NODEV, 0, 0},
{"nodev", MS_NODEV, 1, 1},
{"exec", MS_NOEXEC, 0, 1},
{"noexec", MS_NOEXEC, 1, 1},
{"async", MS_SYNCHRONOUS, 0, 1},
{"sync", MS_SYNCHRONOUS, 1, 1},
{"atime", MS_NOATIME, 0, 1},
{"noatime", MS_NOATIME, 1, 1},
{"dirsync", MS_DIRSYNC, 1, 1},
{NULL, 0, 0, 0}
struct mount_flags
{
const char *opt;
unsigned long flag;
int on;
int safe;
}; };
static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
static
struct mount_flags
mount_flags[] =
{
{"rw", MS_RDONLY, 0, 1},
{"ro", MS_RDONLY, 1, 1},
{"suid", MS_NOSUID, 0, 0},
{"nosuid", MS_NOSUID, 1, 1},
{"dev", MS_NODEV, 0, 0},
{"nodev", MS_NODEV, 1, 1},
{"exec", MS_NOEXEC, 0, 1},
{"noexec", MS_NOEXEC, 1, 1},
{"async", MS_SYNCHRONOUS, 0, 1},
{"sync", MS_SYNCHRONOUS, 1, 1},
{"atime", MS_NOATIME, 0, 1},
{"noatime", MS_NOATIME, 1, 1},
{"dirsync", MS_DIRSYNC, 1, 1},
{"relatime", MS_RELATIME, 1, 1},
{"norelatime", MS_RELATIME, 0, 1},
{"lazytime", MS_LAZYTIME, 1, 1},
{"nolazytime", MS_LAZYTIME, 0, 1},
{"diratime", MS_NODIRATIME, 0, 1},
{"nodiratime", MS_NODIRATIME, 1, 1},
{"strictatime", MS_STRICTATIME, 1, 1},
{"nostrictatime", MS_STRICTATIME, 0, 1},
{NULL, 0, 0, 0}
};
static
int
find_mount_flag(const char *s, unsigned len, int *on, int *flag)
{ {
int i;
for (i = 0; mount_flags[i].opt != NULL; i++) {
const char *opt = mount_flags[i].opt;
if (strlen(opt) == len && strncmp(opt, s, len) == 0) {
*on = mount_flags[i].on;
*flag = mount_flags[i].flag;
if (!mount_flags[i].safe && getuid() != 0) {
*flag = 0;
fprintf(stderr,
"%s: unsafe option %s ignored\n",
progname, opt);
}
return 1;
}
}
return 0;
int i;
for (i = 0; mount_flags[i].opt != NULL; i++)
{
const char *opt = mount_flags[i].opt;
if(strlen(opt) == len && strncmp(opt, s, len) == 0)
{
*on = mount_flags[i].on;
*flag = mount_flags[i].flag;
if(!mount_flags[i].safe && getuid() != 0)
{
*flag = 0;
fprintf(stderr,
"%s: unsafe option %s ignored\n",
progname, opt);
}
return 1;
}
}
return 0;
} }
static int add_option(char **optsp, const char *opt, unsigned expand) static int add_option(char **optsp, const char *opt, unsigned expand)

1
src/config.cpp

@ -211,6 +211,7 @@ Config::Config()
_map["category.create"] = &category.create; _map["category.create"] = &category.create;
_map["category.search"] = &category.search; _map["category.search"] = &category.search;
_map["config"] = &config_file; _map["config"] = &config_file;
_map["defaults"] = &_dummy;
_map["debug"] = &debug; _map["debug"] = &debug;
_map["direct-io-allow-mmap"] = &direct_io_allow_mmap; _map["direct-io-allow-mmap"] = &direct_io_allow_mmap;
_map["direct-io"] = &_dummy; _map["direct-io"] = &_dummy;

4
tests/tests.cpp

@ -169,8 +169,6 @@ test_config_cachefiles()
{ {
CacheFiles cf; CacheFiles cf;
TEST_CHECK(cf.from_string("libfuse") == 0);
TEST_CHECK(cf.to_string() == "libfuse");
TEST_CHECK(cf.from_string("off") == 0); TEST_CHECK(cf.from_string("off") == 0);
TEST_CHECK(cf.to_string() == "off"); TEST_CHECK(cf.to_string() == "off");
TEST_CHECK(cf.from_string("partial") == 0); TEST_CHECK(cf.from_string("partial") == 0);
@ -303,7 +301,7 @@ test_config()
{ {
Config cfg; Config cfg;
TEST_CHECK(cfg.set_raw("async_read","true") == 0);
TEST_CHECK(cfg.set("async-read","true") == 0);
} }
TEST_LIST = TEST_LIST =

Loading…
Cancel
Save