mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-19 16:16:48 +00:00
Misc updates to arg parsing (#1554)
Ignore "defaults" and add a number of more modern VFS mount switches
This commit is contained in:
@@ -69,7 +69,7 @@ OBJS := $(SRC:src/%.cpp=build/.objs/%.cpp.o)
|
||||
DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d)
|
||||
|
||||
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_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d)
|
||||
TESTS_DEPS += $(DEPS)
|
||||
|
||||
+93
-108
@@ -49,14 +49,11 @@ enum {
|
||||
KEY_FUSERMOUNT_OPT,
|
||||
KEY_SUBTYPE_OPT,
|
||||
KEY_MTAB_OPT,
|
||||
KEY_RO,
|
||||
KEY_HELP,
|
||||
KEY_VERSION,
|
||||
KEY_RO
|
||||
};
|
||||
|
||||
struct mount_opts {
|
||||
int allow_other;
|
||||
int ishelp;
|
||||
int flags;
|
||||
int auto_unmount;
|
||||
int blkdev;
|
||||
@@ -70,59 +67,54 @@ struct mount_opts {
|
||||
|
||||
#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[])
|
||||
{
|
||||
@@ -132,56 +124,63 @@ static void exec_fusermount(const 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 {
|
||||
const char *opt;
|
||||
unsigned long flag;
|
||||
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__
|
||||
{"dirsync", MS_DIRSYNC, 1},
|
||||
{"dirsync", MS_DIRSYNC, 1},
|
||||
#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;
|
||||
|
||||
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");
|
||||
abort();
|
||||
}
|
||||
@@ -211,16 +210,6 @@ static int fuse_mount_opt_proc(void *data, const char *arg, int key,
|
||||
|
||||
case KEY_MTAB_OPT:
|
||||
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;
|
||||
}
|
||||
@@ -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)
|
||||
return -1;
|
||||
|
||||
res = 0;
|
||||
if (mo.ishelp)
|
||||
goto out;
|
||||
|
||||
res = -1;
|
||||
if (get_mnt_flag_opts(&mnt_opts, mo.flags) == -1)
|
||||
goto out;
|
||||
|
||||
+58
-41
@@ -579,49 +579,66 @@ static int begins_with(const char *s, const char *beg)
|
||||
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}
|
||||
};
|
||||
|
||||
static int find_mount_flag(const char *s, unsigned len, int *on, int *flag)
|
||||
struct mount_flags
|
||||
{
|
||||
int i;
|
||||
const char *opt;
|
||||
unsigned long flag;
|
||||
int on;
|
||||
int safe;
|
||||
};
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
static int add_option(char **optsp, const char *opt, unsigned expand)
|
||||
|
||||
@@ -211,6 +211,7 @@ Config::Config()
|
||||
_map["category.create"] = &category.create;
|
||||
_map["category.search"] = &category.search;
|
||||
_map["config"] = &config_file;
|
||||
_map["defaults"] = &_dummy;
|
||||
_map["debug"] = &debug;
|
||||
_map["direct-io-allow-mmap"] = &direct_io_allow_mmap;
|
||||
_map["direct-io"] = &_dummy;
|
||||
|
||||
+1
-3
@@ -169,8 +169,6 @@ test_config_cachefiles()
|
||||
{
|
||||
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.to_string() == "off");
|
||||
TEST_CHECK(cf.from_string("partial") == 0);
|
||||
@@ -303,7 +301,7 @@ test_config()
|
||||
{
|
||||
Config cfg;
|
||||
|
||||
TEST_CHECK(cfg.set_raw("async_read","true") == 0);
|
||||
TEST_CHECK(cfg.set("async-read","true") == 0);
|
||||
}
|
||||
|
||||
TEST_LIST =
|
||||
|
||||
Reference in New Issue
Block a user