summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/passthrough_hp.cc58
-rw-r--r--xfstests/README.md18
-rw-r--r--xfstests/local.config12
-rwxr-xr-xxfstests/mount.fuse.passthrough17
4 files changed, 103 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");
diff --git a/xfstests/README.md b/xfstests/README.md
new file mode 100644
index 0000000..deda553
--- /dev/null
+++ b/xfstests/README.md
@@ -0,0 +1,18 @@
+To test FUSE with xfstests¹:
+
+1. copy the `mount.fuse.passthrough` file into
+ `/sbin` and edit the `PASSTHROUGH_PATH`, `SCRATCH_SOURCE` and `TEST_SOURCE` variables as needed.
+
+2. Make sure that the `SCRATCH_SOURCE` and `TEST_SOURCE` directories
+exist.
+
+3. Copy `local.config` into your xfstests directory
+
+Tests can then be run with e.g.:
+
+```sh
+# make
+# sudo ./check -fuse -b
+```
+
+¹https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git/about/
diff --git a/xfstests/local.config b/xfstests/local.config
new file mode 100644
index 0000000..f20cec0
--- /dev/null
+++ b/xfstests/local.config
@@ -0,0 +1,12 @@
+export TEST_DEV=non1
+export TEST_DIR=/mnt/test
+export SCRATCH_DEV=non2
+export SCRATCH_MNT=/mnt/scratch
+export FSTYP=fuse
+export FUSE_SUBTYP=.passthrough
+export MOUNT_OPTIONS=""
+export TEST_FS_MOUNT_OPTS=""
+
+PASSTHROUGH_PATH=/home/nikratio/libfuse/build/example/passthrough_hp
+SCRATCH_SOURCE=/mnt/src/scratch
+TEST_SOURCE=/mnt/src/test
diff --git a/xfstests/mount.fuse.passthrough b/xfstests/mount.fuse.passthrough
new file mode 100755
index 0000000..47208f8
--- /dev/null
+++ b/xfstests/mount.fuse.passthrough
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+ulimit -n 1048576
+
+# It would be easier if we could just set SCRATCH_DEV and TEST_DEV to the source directory
+# path in local.options. Unfortunately, setting these variables to a path seems get
+# xfstests all worked up (even though it should treat these as opaque values), and it
+# refuses to even start running any tests).
+dev="$1"
+shift
+if [ "$dev" = "${SCRATCH_DEV}" ]; then
+ source="${SCRATCH_SOURCE}"
+else
+ source="${TEST_SOURCE}"
+fi
+
+exec "$PASSTHROUGH_PATH" -o fsname=$dev,allow_other "${source}" "$@"