aboutsummaryrefslogtreecommitdiff
path: root/tests/sys/fs/fusefs/mockfs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys/fs/fusefs/mockfs.cc')
-rw-r--r--tests/sys/fs/fusefs/mockfs.cc76
1 files changed, 42 insertions, 34 deletions
diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc
index bd7bd1b663f9..65cdc3919652 100644
--- a/tests/sys/fs/fusefs/mockfs.cc
+++ b/tests/sys/fs/fusefs/mockfs.cc
@@ -39,13 +39,12 @@ extern "C" {
#include <fcntl.h>
#include <libutil.h>
+#include <mntopts.h> // for build_iovec
#include <poll.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
-
-#include "mntopts.h" // for build_iovec
}
#include <cinttypes>
@@ -416,11 +415,25 @@ void MockFS::debug_response(const mockfs_buf_out &out) {
}
}
-MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
+MockFS::MockFS(int max_read, int max_readahead, bool allow_other,
+ bool default_permissions,
bool push_symlinks_in, bool ro, enum poll_method pm, uint32_t flags,
uint32_t kernel_minor_version, uint32_t max_write, bool async,
bool noclusterr, unsigned time_gran, bool nointr, bool noatime,
- const char *fsname, const char *subtype)
+ const char *fsname, const char *subtype, bool no_auto_init)
+ : m_daemon_id(NULL),
+ m_kernel_minor_version(kernel_minor_version),
+ m_kq(pm == KQ ? kqueue() : -1),
+ m_maxread(max_read),
+ m_maxreadahead(max_readahead),
+ m_pid(getpid()),
+ m_uniques(new std::unordered_set<uint64_t>),
+ m_pm(pm),
+ m_time_gran(time_gran),
+ m_child_pid(-1),
+ m_maxwrite(MIN(max_write, max_max_write)),
+ m_nready(-1),
+ m_quit(false)
{
struct sigaction sa;
struct iovec *iov = NULL;
@@ -428,20 +441,6 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
char fdstr[15];
const bool trueval = true;
- m_daemon_id = NULL;
- m_kernel_minor_version = kernel_minor_version;
- m_maxreadahead = max_readahead;
- m_maxwrite = MIN(max_write, max_max_write);
- m_nready = -1;
- m_pm = pm;
- m_time_gran = time_gran;
- m_quit = false;
- m_last_unique = 0;
- if (m_pm == KQ)
- m_kq = kqueue();
- else
- m_kq = -1;
-
/*
* Kyua sets pwd to a testcase-unique tempdir; no need to use
* mkdtemp
@@ -466,15 +465,18 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
throw(std::system_error(errno, std::system_category(),
"Couldn't open /dev/fuse"));
- m_pid = getpid();
- m_child_pid = -1;
-
build_iovec(&iov, &iovlen, "fstype", __DECONST(void *, "fusefs"), -1);
build_iovec(&iov, &iovlen, "fspath",
__DECONST(void *, "mountpoint"), -1);
build_iovec(&iov, &iovlen, "from", __DECONST(void *, "/dev/fuse"), -1);
sprintf(fdstr, "%d", m_fuse_fd);
build_iovec(&iov, &iovlen, "fd", fdstr, -1);
+ if (m_maxread > 0) {
+ char val[10];
+
+ snprintf(val, sizeof(val), "%d", m_maxread);
+ build_iovec(&iov, &iovlen, "max_read=", &val, -1);
+ }
if (allow_other) {
build_iovec(&iov, &iovlen, "allow_other",
__DECONST(void*, &trueval), sizeof(bool));
@@ -527,7 +529,9 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
ON_CALL(*this, process(_, _))
.WillByDefault(Invoke(this, &MockFS::process_default));
- init(flags);
+ if (!no_auto_init)
+ init(flags);
+
bzero(&sa, sizeof(sa));
sa.sa_handler = sigint_handler;
sa.sa_flags = 0; /* Don't set SA_RESTART! */
@@ -541,10 +545,7 @@ MockFS::MockFS(int max_readahead, bool allow_other, bool default_permissions,
MockFS::~MockFS() {
kill_daemon();
- if (m_daemon_id != NULL) {
- pthread_join(m_daemon_id, NULL);
- m_daemon_id = NULL;
- }
+ join_daemon();
::unmount("mountpoint", MNT_FORCE);
rmdir("mountpoint");
if (m_kq >= 0)
@@ -738,14 +739,10 @@ void MockFS::audit_request(const mockfs_buf_in &in, ssize_t buflen) {
default:
FAIL() << "Unknown opcode " << in.header.opcode;
}
- /*
- * Check that the ticket's unique value is sequential. Technically it
- * doesn't need to be sequential, merely unique. But the current
- * fusefs driver _does_ make it sequential, and that's easy to check
- * for.
- */
- if (in.header.unique != ++m_last_unique)
- FAIL() << "Non-sequential unique value";
+ /* Verify that the ticket's unique value is actually unique. */
+ if (m_uniques->find(in.header.unique) != m_uniques->end())
+ FAIL() << "Non-unique \"unique\" value";
+ m_uniques->insert(in.header.unique);
}
void MockFS::init(uint32_t flags) {
@@ -789,6 +786,13 @@ void MockFS::kill_daemon() {
m_fuse_fd = -1;
}
+void MockFS::join_daemon() {
+ if (m_daemon_id != NULL) {
+ pthread_join(m_daemon_id, NULL);
+ m_daemon_id = NULL;
+ }
+}
+
void MockFS::loop() {
std::vector<std::unique_ptr<mockfs_buf_out>> out;
@@ -1035,6 +1039,10 @@ void MockFS::write_response(const mockfs_buf_out &out) {
ASSERT_EQ(-1, r);
ASSERT_EQ(out.expected_errno, errno) << strerror(errno);
} else {
+ if (r <= 0 && errno == EINVAL) {
+ printf("Failed to write response. unique=%" PRIu64
+ ":\n", out.header.unique);
+ }
ASSERT_TRUE(r > 0 || errno == EAGAIN) << strerror(errno);
}
}