aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2026-06-23 17:12:04 +0000
committerAlan Somers <asomers@FreeBSD.org>2026-06-23 18:01:48 +0000
commit2c1482e305368af182a7bde0e53d0d180b319326 (patch)
tree90b6a074afb8ad7b3ce397dd21dd438ab85a031e
parentfdca6b70aa7ebbc95b544cec6e155ea5b1041899 (diff)
fusefs: fix a race in the pre-init tests
These tests allow the user to customize the INIT response. But it's necessary to block the daemon's service loop from running until those expectations have been set. This race has never caused failures before simply due to luck. But now it's failing on slower platforms. PR: 296236 Reported by: siva MFC after: 2 weeks Sponsored by: ConnectWise Reviewed by: siva Differential Revision: https://reviews.freebsd.org/D57781
-rw-r--r--tests/sys/fs/fusefs/mockfs.cc11
-rw-r--r--tests/sys/fs/fusefs/mockfs.hh3
-rw-r--r--tests/sys/fs/fusefs/pre-init.cc6
3 files changed, 17 insertions, 3 deletions
diff --git a/tests/sys/fs/fusefs/mockfs.cc b/tests/sys/fs/fusefs/mockfs.cc
index b9e4afbbea0b..0e395a4fabb3 100644
--- a/tests/sys/fs/fusefs/mockfs.cc
+++ b/tests/sys/fs/fusefs/mockfs.cc
@@ -550,9 +550,8 @@ MockFS::MockFS(int max_read, int max_readahead, bool allow_other,
if (0 != sigaction(SIGUSR1, &sa, NULL))
throw(std::system_error(errno, std::system_category(),
"Couldn't handle SIGUSR1"));
- if (pthread_create(&m_daemon_id, NULL, service, (void*)this))
- throw(std::system_error(errno, std::system_category(),
- "Couldn't Couldn't start fuse thread"));
+ if (!no_auto_init)
+ start_service();
}
MockFS::~MockFS() {
@@ -1018,6 +1017,12 @@ void MockFS::read_request(mockfs_buf_in &in, ssize_t &res) {
ASSERT_TRUE(res == static_cast<ssize_t>(in.header.len) || m_quit);
}
+void MockFS::start_service() {
+ if (pthread_create(&m_daemon_id, NULL, service, (void*)this))
+ throw(std::system_error(errno, std::system_category(),
+ "Couldn't Couldn't start fuse thread"));
+}
+
void MockFS::write_response(const mockfs_buf_out &out) {
fd_set writefds;
pollfd fds[1];
diff --git a/tests/sys/fs/fusefs/mockfs.hh b/tests/sys/fs/fusefs/mockfs.hh
index c8f90c2f5402..19693e50d212 100644
--- a/tests/sys/fs/fusefs/mockfs.hh
+++ b/tests/sys/fs/fusefs/mockfs.hh
@@ -388,6 +388,9 @@ class MockFS {
/* Process FUSE requests endlessly */
void loop();
+ /* Begin processing requests from the kernel */
+ void start_service();
+
/*
* Send an asynchronous notification to invalidate a directory entry.
* Similar to libfuse's fuse_lowlevel_notify_inval_entry
diff --git a/tests/sys/fs/fusefs/pre-init.cc b/tests/sys/fs/fusefs/pre-init.cc
index 2d3257500304..70d7ddcdb0f4 100644
--- a/tests/sys/fs/fusefs/pre-init.cc
+++ b/tests/sys/fs/fusefs/pre-init.cc
@@ -102,6 +102,8 @@ TEST_F(PreInit, unmount_before_init)
})));
expect_destroy(0);
+ m_mock->start_service();
+
ASSERT_EQ(0, pthread_create(&th1, NULL, unmount1, NULL));
nap(); /* Wait for th1 to block in unmount() */
sem_post(&sem0);
@@ -147,6 +149,8 @@ TEST_F(PreInit, signal_during_unmount_before_init)
sem_wait(&sem0);
})));
+ m_mock->start_service();
+
if ((child = ::fork()) == 0) {
/*
* In child. This will block waiting for FUSE_INIT to complete
@@ -219,6 +223,8 @@ TEST_P(PreInitP, getattr_before_init)
out.body.attr.attr_valid = UINT64_MAX;
})));
+ m_mock->start_service();
+
EXPECT_EQ(0, stat("mountpoint", &sb));
EXPECT_EQ(nlink, sb.st_nlink);
}