[LTP] [PATCH v2 5/8] syscalls: Add epoll_wait10

Cyril Hrubis chrubis@suse.cz
Thu Apr 23 14:03:06 CEST 2026


Functional test for EPOLLPRI using /proc/mounts that produces POLLPRI
when a filesystem is mounted/umounted.

Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/syscalls                              |   1 +
 .../kernel/syscalls/epoll_wait/.gitignore     |   1 +
 .../kernel/syscalls/epoll_wait/epoll_wait10.c | 107 ++++++++++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait10.c

diff --git a/runtest/syscalls b/runtest/syscalls
index b302935d5..3fd61b814 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -198,6 +198,7 @@ epoll_wait06 epoll_wait06
 epoll_wait07 epoll_wait07
 epoll_wait08 epoll_wait08
 epoll_wait09 epoll_wait09
+epoll_wait10 epoll_wait10
 
 epoll_pwait01 epoll_pwait01
 epoll_pwait02 epoll_pwait02
diff --git a/testcases/kernel/syscalls/epoll_wait/.gitignore b/testcases/kernel/syscalls/epoll_wait/.gitignore
index f32ec535b..30139375d 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -7,3 +7,4 @@ epoll_wait06
 epoll_wait07
 epoll_wait08
 epoll_wait09
+epoll_wait10
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait10.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait10.c
new file mode 100644
index 000000000..82cd8b15e
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait10.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that epoll_wait with EPOLLPRI detects changes to /proc/mounts.
+ *
+ * The kernel generates a poll notification (POLLPRI/EPOLLERR) on
+ * /proc/mounts whenever the mount namespace changes. This test verifies
+ * that epoll can observe these notifications.
+ *
+ * [Algorithm]
+ *
+ * - Open /proc/mounts and register it with an epoll instance for EPOLLPRI.
+ * - Fork a child that mounts and then unmounts a tmpfs filesystem, using
+ *   checkpoints to synchronize with the parent.
+ * - After each mount namespace change the parent calls epoll_wait and verifies
+ *   it returns an event.
+ *
+ * Needs root to call mount/umount.
+ */
+
+#include <sys/epoll.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+#define MNTPOINT "mnt_epoll"
+
+static int efd = -1, mnt_fd = -1;
+
+static void setup(void)
+{
+	SAFE_MKDIR(MNTPOINT, 0777);
+
+	mnt_fd = SAFE_OPEN("/proc/mounts", O_RDONLY);
+
+	efd = SAFE_EPOLL_CREATE1(0);
+
+	struct epoll_event ev = {
+		.events = EPOLLPRI,
+		.data.fd = mnt_fd,
+	};
+
+	SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, mnt_fd, &ev);
+}
+
+static void check_epoll_event(const char *desc)
+{
+	struct epoll_event ret_ev;
+	char buf[1024];
+
+	TEST(epoll_wait(efd, &ret_ev, 1, 1000));
+	if (TST_RET < 1) {
+		tst_res(TFAIL | TTERRNO,
+			"epoll_wait() after %s returned %li", desc, TST_RET);
+	} else if (!(ret_ev.events & (EPOLLPRI | EPOLLERR))) {
+		tst_res(TFAIL,
+			"after %s: events %x, expected EPOLLPRI or EPOLLERR",
+			desc, ret_ev.events);
+	} else {
+		tst_res(TPASS,
+			"epoll_wait() reported event after %s", desc);
+	}
+
+	/* Re-read /proc/self/mounts to clear the notification */
+	SAFE_LSEEK(mnt_fd, 0, SEEK_SET);
+	while (SAFE_READ(0, mnt_fd, buf, sizeof(buf)) > 0)
+		;
+}
+
+static void run(void)
+{
+	if (!SAFE_FORK()) {
+		SAFE_MOUNT("none", MNTPOINT, "tmpfs", 0, NULL);
+		TST_CHECKPOINT_WAKE_AND_WAIT(0);
+		SAFE_UMOUNT(MNTPOINT);
+		TST_CHECKPOINT_WAKE(0);
+		exit(0);
+	}
+
+	TST_CHECKPOINT_WAIT(0);
+	check_epoll_event("mount");
+
+	TST_CHECKPOINT_WAKE_AND_WAIT(0);
+	check_epoll_event("umount");
+}
+
+static void cleanup(void)
+{
+	if (efd != -1)
+		SAFE_CLOSE(efd);
+
+	if (mnt_fd != -1)
+		SAFE_CLOSE(mnt_fd);
+}
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_root = 1,
+	.forks_child = 1,
+	.needs_checkpoints = 1,
+	.needs_tmpdir = 1,
+};
-- 
2.52.0



More information about the ltp mailing list