diff options
author | Nikolaus Rath <Nikolaus@rath.org> | 2023-03-17 09:56:55 +0000 |
---|---|---|
committer | Nikolaus Rath <Nikolaus@rath.org> | 2023-05-12 23:29:03 +0100 |
commit | 4c177c904778c45ebd992b7f651af4f0039c550c (patch) | |
tree | 7d8405daf0fcca86d83ad502610b69a3387ec3f2 /example/passthrough_hp.cc | |
parent | ad1abf3f2e15d9d23d0a2c60aec6a011762ccfa6 (diff) | |
download | fuse-master.tar.gz |
Diffstat (limited to 'example/passthrough_hp.cc')
-rw-r--r-- | example/passthrough_hp.cc | 58 |
1 files changed, 56 insertions, 2 deletions
diff --git a/example/passthrough_hp.cc b/example/passthrough_hp.cc index 53efd9f..4e32789 100644 --- a/example/passthrough_hp.cc +++ b/example/passthrough_hp.cc @@ -157,6 +157,7 @@ struct Fs { bool nocache; size_t num_threads; bool clone_fd; + std::string fuse_mount_options; }; static Fs fs{}; @@ -1169,8 +1170,36 @@ static cxxopts::ParseResult parse_wrapper(cxxopts::Options& parser, int& argc, c } +static void string_split(std::string s, std::vector<std::string>& out, std::string delimiter) { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + + while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) { + token = s.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + out.push_back(token); + } + + out.push_back(s.substr(pos_start)); +} + + +static std::string string_join(const std::vector<std::string>& elems, char delim) +{ + std::ostringstream out; + for (auto ii = elems.begin(); ii != elems.end(); ++ii) { + out << (*ii); + if (ii + 1 != elems.end()) { + out << delim; + } + } + return out.str(); +} + + static cxxopts::ParseResult parse_options(int argc, char **argv) { cxxopts::Options opt_parser(argv[0]); + std::vector<std::string> mount_options; opt_parser.add_options() ("debug", "Enable filesystem debug messages") ("debug-fuse", "Enable libfuse debug messages") @@ -1179,6 +1208,8 @@ static cxxopts::ParseResult parse_options(int argc, char **argv) { ("nocache", "Disable all caching") ("nosplice", "Do not use splice(2) to transfer data") ("single", "Run single-threaded") + ("o", "Mount options (see mount.fuse(5) - only use if you know what " + "you are doing)", cxxopts::value(mount_options)) ("num-threads", "Number of libfuse worker threads", cxxopts::value<int>()->default_value(SFS_DEFAULT_THREADS)) ("clone-fd", "use separate fuse device fd for each thread", @@ -1220,6 +1251,30 @@ static cxxopts::ParseResult parse_options(int argc, char **argv) { fs.source = std::string {resolved_path}; free(resolved_path); + std::vector<std::string> flattened_mount_opts; + for (auto opt : mount_options) { + string_split(opt, flattened_mount_opts, ","); + } + + bool found_fsname = false; + for (auto opt : flattened_mount_opts) { + if (opt.find("fsname=") == 0) { + found_fsname = true; + continue; + } + + /* Filter out some obviously incorrect options. */ + if (opt == "fd") { + std::cout << argv[0] << ": Unsupported mount option: " << opt << "\n"; + print_usage(argv[0]); + exit(2); + } + } + if (!found_fsname) { + flattened_mount_opts.push_back("fsname=" + fs.source); + } + flattened_mount_opts.push_back("default_permissions"); + fs.fuse_mount_options = string_join(flattened_mount_opts, ','); return options; } @@ -1245,7 +1300,6 @@ int main(int argc, char *argv[]) { // Parse command line options auto options {parse_options(argc, argv)}; - // We need an fd for every dentry in our the filesystem that the // kernel knows about. This is way more than most processes need, // so try to get rid of any resource softlimit. @@ -1272,7 +1326,7 @@ int main(int argc, char *argv[]) { fuse_args args = FUSE_ARGS_INIT(0, nullptr); if (fuse_opt_add_arg(&args, argv[0]) || fuse_opt_add_arg(&args, "-o") || - fuse_opt_add_arg(&args, "default_permissions,fsname=hpps") || + fuse_opt_add_arg(&args, fs.fuse_mount_options.c_str()) || (fs.debug_fuse && fuse_opt_add_arg(&args, "-odebug"))) errx(3, "ERROR: Out of memory"); |