Add support for running xfstests.

This commit is contained in:
Nikolaus Rath 2023-03-17 09:56:55 +00:00
parent ad1abf3f2e
commit 4c177c9047
4 changed files with 103 additions and 2 deletions

View File

@ -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");

18
xfstests/README.md Normal file
View File

@ -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/

12
xfstests/local.config Normal file
View File

@ -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

17
xfstests/mount.fuse.passthrough Executable file
View File

@ -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}" "$@"