[LTP] [PATCH v3 5/9] syscalls: Add epoll_wait10
Cyril Hrubis
chrubis@suse.cz
Thu Jul 9 10:53:49 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>
Reviewed-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait10.c | 103 ++++++++++++++++++
3 files changed, 105 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait10.c
diff --git a/runtest/syscalls b/runtest/syscalls
index b78d565fb..08b31c9f5 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..fbc3c2ce8
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait10.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that :manpage: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 {
+ TST_EXP_EXPR(ret_ev.events & EPOLLPRI);
+ }
+
+ /* 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.53.0
More information about the ltp
mailing list