* [LTP] [PATCH v2 0/8] Add more epoll tests
@ 2026-04-23 12:03 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
This patchset adds much more epoll tests, with that the coverage is
mostly complete so that we can remove the old and ugly epoll-ltp test.
v2:
- fixed typos pointed out by ltp-agent
Cyril Hrubis (8):
syscalls: Add epoll_create03
syscalls: Add epoll_wait08
syscalls: Add epoll_wait09
syscalls: Add epoll_ctl06
syscalls: Add epoll_wait10
syscalls: Add epoll_wait11
syscalls: Add epoll_wait12
syscalls: Remove old epoll-ltp test
runtest/syscalls | 12 +-
testcases/kernel/syscalls/epoll/.gitignore | 1 -
testcases/kernel/syscalls/epoll/Makefile | 8 -
testcases/kernel/syscalls/epoll/README.1ST | 38 -
testcases/kernel/syscalls/epoll/epoll-ltp.c | 738 ------------------
.../kernel/syscalls/epoll_create/.gitignore | 1 +
.../syscalls/epoll_create/epoll_create03.c | 72 ++
.../kernel/syscalls/epoll_ctl/.gitignore | 1 +
.../kernel/syscalls/epoll_ctl/epoll_ctl06.c | 71 ++
.../kernel/syscalls/epoll_wait/.gitignore | 5 +
.../kernel/syscalls/epoll_wait/epoll_wait08.c | 69 ++
.../kernel/syscalls/epoll_wait/epoll_wait09.c | 132 ++++
.../kernel/syscalls/epoll_wait/epoll_wait10.c | 107 +++
.../kernel/syscalls/epoll_wait/epoll_wait11.c | 94 +++
.../kernel/syscalls/epoll_wait/epoll_wait12.c | 112 +++
15 files changed, 675 insertions(+), 786 deletions(-)
delete mode 100644 testcases/kernel/syscalls/epoll/.gitignore
delete mode 100644 testcases/kernel/syscalls/epoll/Makefile
delete mode 100644 testcases/kernel/syscalls/epoll/README.1ST
delete mode 100644 testcases/kernel/syscalls/epoll/epoll-ltp.c
create mode 100644 testcases/kernel/syscalls/epoll_create/epoll_create03.c
create mode 100644 testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait08.c
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait09.c
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait10.c
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait11.c
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait12.c
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:41 ` Petr Vorel
2026-04-23 13:43 ` [LTP] " linuxtestproject.agent
2026-04-23 12:03 ` [LTP] [PATCH v2 2/8] syscalls: Add epoll_wait08 Cyril Hrubis
` (6 subsequent siblings)
7 siblings, 2 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
Test that checks that we get EMFILE when limit on per-process file
descriptors is hit.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 2 +
.../kernel/syscalls/epoll_create/.gitignore | 1 +
.../syscalls/epoll_create/epoll_create03.c | 72 +++++++++++++++++++
3 files changed, 75 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_create/epoll_create03.c
diff --git a/runtest/syscalls b/runtest/syscalls
index df5dc02b5..d890c5516 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -177,6 +177,8 @@ dup3_02 dup3_02
epoll_create01 epoll_create01
epoll_create02 epoll_create02
+epoll_create03 epoll_create03
+
epoll_create1_01 epoll_create1_01
epoll_create1_02 epoll_create1_02
epoll01 epoll-ltp
diff --git a/testcases/kernel/syscalls/epoll_create/.gitignore b/testcases/kernel/syscalls/epoll_create/.gitignore
index 5c16cfa8c..855bf255c 100644
--- a/testcases/kernel/syscalls/epoll_create/.gitignore
+++ b/testcases/kernel/syscalls/epoll_create/.gitignore
@@ -1,2 +1,3 @@
epoll_create01
epoll_create02
+epoll_create03
diff --git a/testcases/kernel/syscalls/epoll_create/epoll_create03.c b/testcases/kernel/syscalls/epoll_create/epoll_create03.c
new file mode 100644
index 000000000..d0e66c4e5
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_create/epoll_create03.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that epoll_create() fails with EMFILE when the per-process limit on
+ * the number of open file descriptors has been reached.
+ */
+
+#include <stdlib.h>
+#include <sys/epoll.h>
+
+#include "tst_test.h"
+#include "lapi/epoll.h"
+#include "lapi/syscalls.h"
+
+#include "epoll_create.h"
+
+static int *fds;
+static int nfds;
+static long maxfds;
+
+static void setup(void)
+{
+ int fd;
+
+ variant_info();
+
+ maxfds = SAFE_SYSCONF(_SC_OPEN_MAX);
+ fds = SAFE_MALLOC(maxfds * sizeof(int));
+ memset(fds, -1, maxfds * sizeof(int));
+
+ fds[0] = SAFE_OPEN("dummy", O_RDWR | O_CREAT, 0700);
+ nfds = 1;
+
+ for (long i = 1; i < maxfds; i++) {
+ fd = dup(fds[0]);
+ if (fd == -1)
+ break;
+ fds[nfds++] = fd;
+ }
+}
+
+static void run(void)
+{
+ TST_EXP_FAIL2(do_epoll_create(1), EMFILE,
+ "epoll_create(1) with exhausted fds");
+
+ if (TST_RET != -1)
+ SAFE_CLOSE(TST_RET);
+}
+
+static void cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < nfds; i++) {
+ if (fds[i] != -1)
+ SAFE_CLOSE(fds[i]);
+ }
+
+ free(fds);
+}
+
+static struct tst_test test = {
+ .test_variants = EPOLL_CREATE_VARIANTS,
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 2/8] syscalls: Add epoll_wait08
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 3/8] syscalls: Add epoll_wait09 Cyril Hrubis
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
Tests that epoll_wait() can be interrupted by a signal and returns
EINTR.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 3 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait08.c | 69 +++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait08.c
diff --git a/runtest/syscalls b/runtest/syscalls
index d890c5516..99cdd1db8 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -187,6 +187,7 @@ epoll_ctl02 epoll_ctl02
epoll_ctl03 epoll_ctl03
epoll_ctl04 epoll_ctl04
epoll_ctl05 epoll_ctl05
+
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
epoll_wait03 epoll_wait03
@@ -194,6 +195,8 @@ epoll_wait04 epoll_wait04
epoll_wait05 epoll_wait05
epoll_wait06 epoll_wait06
epoll_wait07 epoll_wait07
+epoll_wait08 epoll_wait08
+
epoll_pwait01 epoll_pwait01
epoll_pwait02 epoll_pwait02
epoll_pwait03 epoll_pwait03
diff --git a/testcases/kernel/syscalls/epoll_wait/.gitignore b/testcases/kernel/syscalls/epoll_wait/.gitignore
index 66ac18ae2..f3b208950 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -5,3 +5,4 @@ epoll_wait04
epoll_wait05
epoll_wait06
epoll_wait07
+epoll_wait08
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait08.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait08.c
new file mode 100644
index 000000000..9d10984ef
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait08.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Linux Test Project, 2026
+ */
+
+/*\
+ * Verify that epoll_wait fails with EINTR when a signal arrives while waiting
+ * for events.
+ *
+ * [Algorithm]
+ *
+ * - Create an epoll instance and register a socket fd for EPOLLIN.
+ * - Fork a child that waits for the parent to enter epoll_wait, then sends
+ * SIGUSR1 to interrupt it.
+ * - Verify that epoll_wait returns -1 with errno set to EINTR.
+ */
+
+#include <stdlib.h>
+#include <sys/epoll.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static int efd = -1;
+
+static void sighandler(int sig LTP_ATTRIBUTE_UNUSED)
+{
+}
+
+static void setup(void)
+{
+ static struct sigaction sa = {
+ .sa_handler = sighandler,
+ };
+
+ SAFE_SIGEMPTYSET(&sa.sa_mask);
+ SAFE_SIGACTION(SIGUSR1, &sa, NULL);
+
+ efd = SAFE_EPOLL_CREATE1(0);
+}
+
+static void run(void)
+{
+ pid_t pid = SAFE_FORK();
+
+ if (!pid) {
+ struct epoll_event ev;
+
+ TST_EXP_FAIL(epoll_wait(efd, &ev, 1, -1), EINTR,
+ "epoll_wait() interrupted by signal");
+ exit(0);
+ }
+
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
+ SAFE_KILL(pid, SIGUSR1);
+}
+
+static void cleanup(void)
+{
+ if (efd != -1)
+ SAFE_CLOSE(efd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .forks_child = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 3/8] syscalls: Add epoll_wait09
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 2/8] syscalls: Add epoll_wait08 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 4/8] syscalls: Add epoll_ctl06 Cyril Hrubis
` (4 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
Test checks that events from recursive epoll are propagated correctly.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait09.c | 132 ++++++++++++++++++
3 files changed, 134 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait09.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 99cdd1db8..569e8bbe4 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -196,6 +196,7 @@ epoll_wait05 epoll_wait05
epoll_wait06 epoll_wait06
epoll_wait07 epoll_wait07
epoll_wait08 epoll_wait08
+epoll_wait09 epoll_wait09
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 f3b208950..f32ec535b 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -6,3 +6,4 @@ epoll_wait05
epoll_wait06
epoll_wait07
epoll_wait08
+epoll_wait09
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait09.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait09.c
new file mode 100644
index 000000000..790690884
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait09.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that epoll_wait works with nested epoll instances up to the maximum
+ * nesting depth of 5 allowed by the kernel (EP_MAX_NESTS).
+ *
+ * [Algorithm]
+ *
+ * - Create a pipe.
+ * - Build a chain of epoll instances of the given depth where the innermost
+ * monitors the pipe read end and each subsequent one monitors the previous.
+ * - Write data to the pipe.
+ * - Call epoll_wait on the outermost epoll instance and verify it reports
+ * EPOLLIN.
+ * - Walk the chain inward calling epoll_wait on each level and verify that
+ * every level reports EPOLLIN on the expected fd.
+ * - Read the data from the pipe to drain it.
+ */
+
+#include <sys/epoll.h>
+
+#include "tst_epoll.h"
+#include "tst_test.h"
+
+#define MAX_DEPTH 5
+
+static int epfds[MAX_DEPTH];
+static int fds[2] = {-1, -1};
+
+static struct tcase {
+ int depth;
+} tcases[] = {
+ {2},
+ {3},
+ {4},
+ {5},
+};
+
+static void run(unsigned int n)
+{
+ struct tcase *tc = &tcases[n];
+ struct epoll_event ev;
+ int prev_fd, i;
+ char buf;
+
+ prev_fd = fds[0];
+
+ for (i = 0; i < tc->depth; i++) {
+ epfds[i] = SAFE_EPOLL_CREATE1(0);
+
+ ev.events = EPOLLIN;
+ ev.data.fd = prev_fd;
+
+ SAFE_EPOLL_CTL(epfds[i], EPOLL_CTL_ADD, prev_fd, &ev);
+
+ prev_fd = epfds[i];
+ }
+
+ SAFE_WRITE(SAFE_WRITE_ALL, fds[1], "x", 1);
+
+ /* Walk from outermost to innermost verifying each level */
+ for (i = tc->depth - 1; i >= 0; i--) {
+ int expected_fd = (i > 0) ? epfds[i - 1] : fds[0];
+
+ TEST(epoll_wait(epfds[i], &ev, 1, 1000));
+ if (TST_RET != 1) {
+ tst_res(TFAIL | TTERRNO,
+ "depth %d/%d: epoll_wait() returned %li, expected 1",
+ tc->depth - i, tc->depth, TST_RET);
+ goto end;
+ }
+
+ if (ev.data.fd != expected_fd) {
+ tst_res(TFAIL,
+ "depth %d/%d: data.fd %d, expected %d",
+ tc->depth - i, tc->depth,
+ ev.data.fd, expected_fd);
+ goto end;
+ }
+
+ if (!(ev.events & EPOLLIN)) {
+ tst_res(TFAIL,
+ "depth %d/%d: events %x, expected EPOLLIN",
+ tc->depth - i, tc->depth, ev.events);
+ goto end;
+ }
+ }
+
+ tst_res(TPASS, "epoll_wait() with %d nested levels", tc->depth);
+
+end:
+ SAFE_READ(1, fds[0], &buf, 1);
+
+ for (i = tc->depth - 1; i >= 0; i--) {
+ if (epfds[i] != -1)
+ SAFE_CLOSE(epfds[i]);
+ }
+
+}
+
+static void setup(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEPTH; i++)
+ epfds[i] = -1;
+
+ SAFE_PIPE(fds);
+}
+
+static void cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_DEPTH; i++) {
+ if (epfds[i] != -1)
+ SAFE_CLOSE(epfds[i]);
+ }
+
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 4/8] syscalls: Add epoll_ctl06
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
` (2 preceding siblings ...)
2026-04-23 12:03 ` [LTP] [PATCH v2 3/8] syscalls: Add epoll_wait09 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 5/8] syscalls: Add epoll_wait10 Cyril Hrubis
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
Test that iterates over different types of file descriptors, attempts to
add them to epoll and expects either success or a failure based on the
type of the file descriptor.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_ctl/.gitignore | 1 +
.../kernel/syscalls/epoll_ctl/epoll_ctl06.c | 71 +++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 569e8bbe4..b302935d5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -187,6 +187,7 @@ epoll_ctl02 epoll_ctl02
epoll_ctl03 epoll_ctl03
epoll_ctl04 epoll_ctl04
epoll_ctl05 epoll_ctl05
+epoll_ctl06 epoll_ctl06
epoll_wait01 epoll_wait01
epoll_wait02 epoll_wait02
diff --git a/testcases/kernel/syscalls/epoll_ctl/.gitignore b/testcases/kernel/syscalls/epoll_ctl/.gitignore
index 3e05f2e1f..9c555f41b 100644
--- a/testcases/kernel/syscalls/epoll_ctl/.gitignore
+++ b/testcases/kernel/syscalls/epoll_ctl/.gitignore
@@ -3,3 +3,4 @@ epoll_ctl02
epoll_ctl03
epoll_ctl04
epoll_ctl05
+epoll_ctl06
diff --git a/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
new file mode 100644
index 000000000..b2bfce252
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_ctl/epoll_ctl06.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify epoll_ctl EPOLL_CTL_ADD behavior across all file descriptor types.
+ *
+ * The test iterates over all available fd types via TST_FD_FOREACH and
+ * attempts EPOLL_CTL_ADD on each. File descriptor types that implement the
+ * poll file operation are expected to succeed. The rest must fail with:
+ *
+ * - EPERM for fds that are valid but lack poll support (regular files,
+ * directories, /dev/zero, /proc files, memfd).
+ * - EBADF for fds that are not usable for I/O (O_PATH, open_tree).
+ */
+
+#include <sys/epoll.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+#include "tst_fd.h"
+
+static int exp_errno(enum tst_fd_type type)
+{
+ switch (type) {
+ case TST_FD_FILE:
+ case TST_FD_DIR:
+ case TST_FD_DEV_ZERO:
+ case TST_FD_PROC_MAPS:
+ case TST_FD_MEMFD:
+ case TST_FD_MEMFD_SECRET:
+ return EPERM;
+ case TST_FD_PATH:
+ case TST_FD_OPEN_TREE:
+ case TST_FD_FSOPEN:
+ case TST_FD_FSPICK:
+ return EBADF;
+ default:
+ return 0;
+ }
+}
+
+static void run(void)
+{
+ int efd, err;
+ struct epoll_event ev = {.events = EPOLLIN};
+
+ TST_FD_FOREACH(fd) {
+ efd = SAFE_EPOLL_CREATE1(0);
+ ev.data.fd = fd.fd;
+ err = exp_errno(fd.type);
+
+ if (err) {
+ TST_EXP_FAIL(epoll_ctl(efd, EPOLL_CTL_ADD,
+ fd.fd, &ev), err,
+ "epoll_ctl() on %s", tst_fd_desc(&fd));
+ } else {
+ TST_EXP_PASS(epoll_ctl(efd, EPOLL_CTL_ADD,
+ fd.fd, &ev),
+ "epoll_ctl() on %s", tst_fd_desc(&fd));
+ }
+
+ SAFE_CLOSE(efd);
+ }
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .needs_tmpdir = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 5/8] syscalls: Add epoll_wait10
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
` (3 preceding siblings ...)
2026-04-23 12:03 ` [LTP] [PATCH v2 4/8] syscalls: Add epoll_ctl06 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 6/8] syscalls: Add epoll_wait11 Cyril Hrubis
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
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
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 6/8] syscalls: Add epoll_wait11
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
` (4 preceding siblings ...)
2026-04-23 12:03 ` [LTP] [PATCH v2 5/8] syscalls: Add epoll_wait10 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 7/8] syscalls: Add epoll_wait12 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 8/8] syscalls: Remove old epoll-ltp test Cyril Hrubis
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
A test that checks that EPOLLHUP is generated properly when a pipe is
closed while epoll_wait() waits on the read end of a pipe.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait11.c | 94 +++++++++++++++++++
3 files changed, 96 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait11.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 3fd61b814..c16cf3554 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -199,6 +199,7 @@ epoll_wait07 epoll_wait07
epoll_wait08 epoll_wait08
epoll_wait09 epoll_wait09
epoll_wait10 epoll_wait10
+epoll_wait11 epoll_wait11
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 30139375d..57bdf0806 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -8,3 +8,4 @@ epoll_wait07
epoll_wait08
epoll_wait09
epoll_wait10
+epoll_wait11
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c
new file mode 100644
index 000000000..764fe5f61
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait11.c
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Cyril Hrubis <chrubis@suse.cz>
+ */
+
+/*\
+ * Verify that epoll_wait reports EPOLLHUP when the write end of a pipe is
+ * closed while a child process is blocked in epoll_wait.
+ *
+ * [Algorithm]
+ *
+ * - Create a pipe and register the read end with an epoll instance for
+ * EPOLLIN.
+ * - Fork a child that blocks in epoll_wait on the pipe read end.
+ * - Parent waits for the child to enter sleep state, then closes the write
+ * end.
+ * - The child's epoll_wait should return with EPOLLHUP and the child reports
+ * the result via its exit code.
+ */
+
+#include <sys/epoll.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static int efd = -1, fds[2] = {-1, -1};
+
+static void run(void)
+{
+ pid_t pid;
+
+ SAFE_PIPE(fds);
+
+ efd = SAFE_EPOLL_CREATE1(0);
+
+ struct epoll_event ev = {
+ .events = EPOLLIN,
+ .data.fd = fds[0],
+ };
+
+ SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, fds[0], &ev);
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ SAFE_CLOSE(fds[1]);
+
+ TEST(epoll_wait(efd, &ev, 1, 5000));
+ if (TST_RET != 1) {
+ tst_res(TFAIL | TTERRNO,
+ "epoll_wait() returned %li, expected 1",
+ TST_RET);
+ exit(0);
+ }
+
+ if (ev.data.fd != fds[0]) {
+ tst_res(TFAIL, "epoll.data.fd %d, expected %d",
+ ev.data.fd, fds[0]);
+ exit(0);
+ }
+
+ if (!(ev.events & EPOLLHUP)) {
+ tst_res(TFAIL, "events %x, EPOLLHUP not set",
+ ev.events);
+ exit(0);
+ }
+
+ tst_res(TPASS,
+ "epoll_wait() reported EPOLLHUP on pipe hangup");
+ exit(0);
+ }
+
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
+ SAFE_CLOSE(fds[1]);
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(efd);
+}
+
+static void cleanup(void)
+{
+ if (fds[1] != -1)
+ SAFE_CLOSE(fds[1]);
+
+ if (fds[0] != -1)
+ SAFE_CLOSE(fds[0]);
+
+ if (efd != -1)
+ SAFE_CLOSE(efd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .cleanup = cleanup,
+ .forks_child = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 7/8] syscalls: Add epoll_wait12
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
` (5 preceding siblings ...)
2026-04-23 12:03 ` [LTP] [PATCH v2 6/8] syscalls: Add epoll_wait11 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 8/8] syscalls: Remove old epoll-ltp test Cyril Hrubis
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
A test for EPOLLERR when we are waiting to write into a pipe and the
read end is closed.
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 1 +
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait12.c | 112 ++++++++++++++++++
3 files changed, 114 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait12.c
diff --git a/runtest/syscalls b/runtest/syscalls
index c16cf3554..0787bbe72 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -200,6 +200,7 @@ epoll_wait08 epoll_wait08
epoll_wait09 epoll_wait09
epoll_wait10 epoll_wait10
epoll_wait11 epoll_wait11
+epoll_wait12 epoll_wait12
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 57bdf0806..ad890d077 100644
--- a/testcases/kernel/syscalls/epoll_wait/.gitignore
+++ b/testcases/kernel/syscalls/epoll_wait/.gitignore
@@ -9,3 +9,4 @@ epoll_wait08
epoll_wait09
epoll_wait10
epoll_wait11
+epoll_wait12
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait12.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait12.c
new file mode 100644
index 000000000..eed395fcf
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait12.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) Linux Test Project, 2026
+ */
+
+/*\
+ * Verify that epoll_wait reports EPOLLERR when the read end of a pipe is
+ * closed while a child process is blocked in epoll_wait on the write end.
+ *
+ * [Algorithm]
+ *
+ * - Create a pipe and fill it completely so the write end is not writable.
+ * - Register the write end with an epoll instance for EPOLLOUT.
+ * - Fork a child that closes its copy of the read end and blocks in
+ * epoll_wait waiting for the pipe to become writable.
+ * - Parent waits for the child to enter sleep state, then closes the read
+ * end.
+ * - The child's epoll_wait should return with EPOLLERR set.
+ */
+
+#include <sys/epoll.h>
+#include <poll.h>
+
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static int efd = -1, fds[2] = {-1, -1};
+
+static void fill_pipe(int fd)
+{
+ char buf[4096];
+ struct pollfd pfd = {.fd = fd, .events = POLLOUT};
+ int nfd;
+
+ memset(buf, 'a', sizeof(buf));
+
+ do {
+ SAFE_WRITE(SAFE_WRITE_ANY, fd, buf, sizeof(buf));
+ nfd = poll(&pfd, 1, 0);
+ if (nfd == -1)
+ tst_brk(TBROK | TERRNO, "poll()");
+ } while (nfd > 0);
+}
+
+static void run(void)
+{
+ pid_t pid;
+
+ SAFE_PIPE(fds);
+ fill_pipe(fds[1]);
+
+ efd = SAFE_EPOLL_CREATE1(0);
+
+ struct epoll_event ev = {
+ .events = EPOLLOUT,
+ .data.fd = fds[1],
+ };
+
+ SAFE_EPOLL_CTL(efd, EPOLL_CTL_ADD, fds[1], &ev);
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ SAFE_CLOSE(fds[0]);
+
+ TEST(epoll_wait(efd, &ev, 1, 5000));
+ if (TST_RET != 1) {
+ tst_res(TFAIL | TTERRNO,
+ "epoll_wait() returned %li, expected 1",
+ TST_RET);
+ exit(0);
+ }
+
+ if (ev.data.fd != fds[1]) {
+ tst_res(TFAIL, "epoll.data.fd %d, expected %d",
+ ev.data.fd, fds[1]);
+ exit(0);
+ }
+
+ if (!(ev.events & EPOLLERR)) {
+ tst_res(TFAIL, "events %x, EPOLLERR not set",
+ ev.events);
+ exit(0);
+ }
+
+ tst_res(TPASS,
+ "epoll_wait() reported EPOLLERR on broken pipe");
+ exit(0);
+ }
+
+ TST_PROCESS_STATE_WAIT(pid, 'S', 0);
+ SAFE_CLOSE(fds[0]);
+ SAFE_CLOSE(fds[1]);
+ SAFE_CLOSE(efd);
+}
+
+static void cleanup(void)
+{
+ if (fds[1] != -1)
+ SAFE_CLOSE(fds[1]);
+
+ if (fds[0] != -1)
+ SAFE_CLOSE(fds[0]);
+
+ if (efd != -1)
+ SAFE_CLOSE(efd);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .cleanup = cleanup,
+ .forks_child = 1,
+};
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [LTP] [PATCH v2 8/8] syscalls: Remove old epoll-ltp test
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
` (6 preceding siblings ...)
2026-04-23 12:03 ` [LTP] [PATCH v2 7/8] syscalls: Add epoll_wait12 Cyril Hrubis
@ 2026-04-23 12:03 ` Cyril Hrubis
7 siblings, 0 replies; 11+ messages in thread
From: Cyril Hrubis @ 2026-04-23 12:03 UTC (permalink / raw)
To: ltp
Now that the epoll coverate is greater than it ever was we can remove
the old and ugly epoll-ltp test.
Fixes: https://github.com/linux-test-project/ltp/issues/860
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
runtest/syscalls | 2 +-
testcases/kernel/syscalls/epoll/.gitignore | 1 -
testcases/kernel/syscalls/epoll/Makefile | 8 -
testcases/kernel/syscalls/epoll/README.1ST | 38 -
testcases/kernel/syscalls/epoll/epoll-ltp.c | 738 --------------------
5 files changed, 1 insertion(+), 786 deletions(-)
delete mode 100644 testcases/kernel/syscalls/epoll/.gitignore
delete mode 100644 testcases/kernel/syscalls/epoll/Makefile
delete mode 100644 testcases/kernel/syscalls/epoll/README.1ST
delete mode 100644 testcases/kernel/syscalls/epoll/epoll-ltp.c
diff --git a/runtest/syscalls b/runtest/syscalls
index 0787bbe72..3e7587f76 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -181,7 +181,7 @@ epoll_create03 epoll_create03
epoll_create1_01 epoll_create1_01
epoll_create1_02 epoll_create1_02
-epoll01 epoll-ltp
+
epoll_ctl01 epoll_ctl01
epoll_ctl02 epoll_ctl02
epoll_ctl03 epoll_ctl03
diff --git a/testcases/kernel/syscalls/epoll/.gitignore b/testcases/kernel/syscalls/epoll/.gitignore
deleted file mode 100644
index dfb4445db..000000000
--- a/testcases/kernel/syscalls/epoll/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/epoll-ltp
diff --git a/testcases/kernel/syscalls/epoll/Makefile b/testcases/kernel/syscalls/epoll/Makefile
deleted file mode 100644
index 044619fb8..000000000
--- a/testcases/kernel/syscalls/epoll/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (c) International Business Machines Corp., 2001
-
-top_srcdir ?= ../../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/epoll/README.1ST b/testcases/kernel/syscalls/epoll/README.1ST
deleted file mode 100644
index e5c5fcc5c..000000000
--- a/testcases/kernel/syscalls/epoll/README.1ST
+++ /dev/null
@@ -1,38 +0,0 @@
-Epoll Setup
-
-
- ** Directions for glibc version of 2.3.2 or higher **
-
-Epoll support is currently implemented in glibc 2.3.2, therefore if you have a$
-glibc version of 2.3.2 or higher then do the following steps:
-
-1. Download and untar the epoll library from:
- http://www.xmailserver.org/linux-patches/epoll-lib-0.11.tar.gz
-2. Copy <epoll-lib_directory>/include/epoll.h /usr/include
-3. Compile epoll-ltp.c in the <ltp_dir>testcases/kernel/syscall/epoll
-
-
-
- ** Older version of glibc **
-To compile the epoll-ltp successfully the following libraries are needed:
-
-Epoll library http://www.xmailserver.org/linux-patches/epoll-lib-0.11.tar.gz
-Portable Coroutine Library (PCL) http://www.xmailserver.org/libpcl.html
-
-
-1. Download and untar the PCL library
-2. Run ./configure
-3. Run make
-4. Run make install
-5. Copy <libpcl_directory>/pcl/.libs/libpcl.* /lib
-6. Download and untar the epoll library
-7. *You may have to modify the makefile in <epoll-lib_directory>/Makefile and <epoll-lib_directory>/examples/Makefile with the following
-- KERNELDIR = kernel_directory
-- #all: .depend $(TARGET) epoll-example change this line to$
-- all: .$(TARGET) epoll-example
-- #include .depend comment out this line
-8. Copy <epoll-lib_directory>/include/epoll.h /usr/include
-9. <epoll-lib_directory> make
-10. Copy <epoll-lib_directory>/lib/libepoll* /lib
-11. Compile epoll-ltp.c in the <ltp_dir>testcases/kernel/syscall/epoll
-
diff --git a/testcases/kernel/syscalls/epoll/epoll-ltp.c b/testcases/kernel/syscalls/epoll/epoll-ltp.c
deleted file mode 100644
index dac132e2f..000000000
--- a/testcases/kernel/syscalls/epoll/epoll-ltp.c
+++ /dev/null
@@ -1,738 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-/******************************************************************************
-
- File: epoll-ltp.c
-
- Description:
- Test the epoll_* system calls. This test program attempts to
- be very thorough in exercising epoll_* system calls. Large
- combinations of valid and invalid parameters are passed with
- valid and invalid sequences. Due to the combinatorial nature
- of this test program the test may take a "long" time to
- execute.
-
- Total Tests: 2 (2 system calls are being tested for)
-
- Test Name: epoll_create, epoll_ctl
-
- Test Assertion
- & Strategy: Test a variety of incorrect parameters for epoll_create
-
- Then run a reasonable epoll_create and get a fd for the epoll
- set.
-
- Next run epoll_ctl on that fd (epoll_fd) with a variety of
- incorrect parameters and a couple correct ones.
-
- Finally ?How to thoroughly test epoll_wait?
-
- Author: Matt Helsley <matthltc@us.ibm.com>
-
- History: Created - May 22 2003 - Matt Helsley <matthltc@us.ibm.com>
- Added -
-
- Notes: Currently we assume that the OS will never allocate an fd s.t.
- fd == INT_MAX and that it will instead choose to allocate fds
- from the "low" numbers. -MH
-
- Currently pokes epoll_create several times in 2 + NUM_RAND_ATTEMPTS ways
- pokes epoll_ctl 27648 - (2 + NUM_RAND_ATTEMPTS) ways
- does not poke epoll_wait
-
- TODO: change errno test code to build lists of possible errno values for
- each erroneous parameter. Check that the errno value is in one
- of the lists. Currently errno is not checked at all when multiple
- erroneous parameters are passed in.
-
- test epoll_ctl with a large number of file descriptor events in the
- set
-
- Link against epoll and ltp (-lepoll -lltp)
-
-*******************************************************************************/
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <string.h>
-#include <signal.h>
-#include <assert.h>
-#include <limits.h>
-#include <ctype.h>
-#include <time.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/file.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-
-#include "config.h"
-#include "test.h"
-
-char *TCID = "epoll01";
-int TST_TOTAL = 1;
-
-#ifdef HAVE_SYS_EPOLL_H
-
-#include <sys/epoll.h>
-
-/* Local Defines */
-#if !defined(TRUE) && !defined(FALSE)
-#define TRUE 1
-#define FALSE 0
-#endif
-
-#define NUM_RAND_ATTEMPTS 16
-#define BACKING_STORE_SIZE_HINT 32
-
-/*
- Define the beginning of a "protected region".
- This is a region where a wide variety of errors
- could occur or signals could arrive (including
- SIGSEGV and SIGKILL).
-$
- The test program uses this to catch those
- conditions as best it can and continue testing.
-
- The region MUST be marked by a corresponding
- PROTECT_REGION_END.
-
- DO NOT nest protected regions! i.e. Do not build
- code of the form:
-
- PROTECT_REGION_START
- ...
- PROTECT_REGION_START
- ...
- PROTECT_REGION_END
- ...
- PROTECT_REGION_END
- */
-#define PROTECT_REGION_START \
-do { \
- pid_t kid_pid; \
- int kid_status; \
- \
- tst_old_flush(); \
- kid_pid = tst_fork(); \
- if (kid_pid == 0) {
-
-#define PROTECT_REGION_EXIT(errval) return (errval);
-
-#define PROTECT_REGION_END(result, errval) \
- return 0; \
- } else { \
- waitpid(kid_pid, &kid_status, 0); \
- if (WIFEXITED(kid_status)) { \
- (result) = WEXITSTATUS(kid_status); \
- } else { /* Must have been signaled */ \
- (result) = (errval); \
- if (WIFSIGNALED(kid_status)) \
- tst_resm(TFAIL, "Protected function test exited due to signal %d (%s)", \
- WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
- } \
- } \
-} while (0)
-
-/*
- * Call a function in a "protected" context.
- * This protects the test program proper from segfaults
- * and allows for the extraction of an integer return
- * code.
- *
- * return only integer results.
- */
-#define PROTECT_FUNC(fn, errval, epoll_fd) ( \
-{ \
- pid_t kid_pid; \
- int kid_status; \
- \
- tst_old_flush(); \
- kid_pid = tst_fork(); \
- if (kid_pid == 0) { /* Run the function */ \
- return fn(epoll_fd); \
- } else { \
- waitpid(kid_pid, &kid_status, 0); \
- if (WIFEXITED(kid_status)) { \
- kid_status = WEXITSTATUS(kid_status); \
- } else { /* Must have been signaled */ \
- kid_status = (errval); \
- if (WIFSIGNALED(kid_status)) \
- tst_resm(TFAIL, "Protected function test exited due to signal %d (%s)", \
- WTERMSIG(kid_status), strsignal(WTERMSIG(kid_status))); \
- } \
-} \
-kid_status = kid_status;})
-
-/*
- * Given the number of random size requests to test,
- * test various boundary cases of epoll_create().
- *
- * Return the number of tests that failed. 0 indicates
- * 100% passed.
- */
-int test_epoll_create(unsigned int num_rand_attempts)
-{
- int epoll_fd = -1;
- int fd_set_size = -1;
- unsigned int attempt_count;
- unsigned int num_epoll_create_test_fails = 0;
- unsigned int num_epoll_create_test_calls = 0;
-
- /* Negative set sizes */
- errno = 0;
- fd_set_size = -1;
- num_epoll_create_test_calls++;
- epoll_fd = epoll_create(fd_set_size);
- if (epoll_fd >= 0) {
- tst_resm(TFAIL | TERRNO,
- "epoll_create with negative set size succeeded unexpectedly");
- num_epoll_create_test_fails++;
- close(epoll_fd);
- } else {
- if (errno != EINVAL) {
- tst_resm(TFAIL | TERRNO,
- "epoll_create with negative set size didn't set errno to EINVAL");
- num_epoll_create_test_fails++;
- } else {
- tst_resm(TPASS, "epoll_create with negative set size");
- }
- }
-
- /* Large set sizes -- try several less than or equal to INT_MAX by some
- small amount (expect num_rand_attempts to be approximately the
- amount we'd like to go below INT_MAX). */
- fd_set_size = INT_MAX;
- for (attempt_count = num_rand_attempts; attempt_count > 0;
- attempt_count--, fd_set_size--) {
- num_epoll_create_test_calls++;
- epoll_fd = epoll_create(fd_set_size);
- if (epoll_fd == -1) {
- if (errno != ENOMEM) {
- tst_resm(TFAIL,
- "epoll_create with large set size (size = %d)",
- fd_set_size);
- num_epoll_create_test_fails++;
- } else {
- tst_resm(TPASS,
- "epoll_create with large set size (size = %d)",
- fd_set_size);
- }
- } else {
- tst_resm(TPASS,
- "epoll_create with large set size (size = %d)",
- fd_set_size);
- close(epoll_fd);
- }
- }
-
- /* Random large set sizes */
- for (attempt_count = num_rand_attempts; attempt_count > 0;
- attempt_count--) {
- fd_set_size = abs(rand() + SHRT_MAX) % INT_MAX;
- errno = 0;
- num_epoll_create_test_calls++;
- epoll_fd = epoll_create(fd_set_size);
- if (epoll_fd < 0) {
- if (errno != ENOMEM) {
- tst_resm(TFAIL,
- "epoll_create with random random large set size (size = %d)",
- fd_set_size);
- num_epoll_create_test_fails++;
- } else {
- tst_resm(TPASS,
- "epoll_create with random random large set size (size = %d)",
- fd_set_size);
- }
- } else {
- tst_resm(TPASS,
- "epoll_create with random large set size (size = %d)",
- fd_set_size);
- close(epoll_fd);
- }
- }
-
- tst_resm(TINFO,
- "Summary: Of %d tests, epoll_create failed %d (%3.0f%% passed).",
- num_epoll_create_test_calls, num_epoll_create_test_fails,
- ((float)
- (num_epoll_create_test_calls - num_epoll_create_test_fails)
- * 100.0f / (float)
- num_epoll_create_test_calls));
- /* Return 0 on success. */
-
- return num_epoll_create_test_fails;
-}
-
-/* RES_PASS indicates a PASS result */
-#define RES_PASS 0
-
-/*
- * RES_FAIL_* indicates a FAIL result
- * In brief, there are two things that can go wrong in a
- * failure. The return value (result = epoll_ctl(...)) and
- * the errno value may not match expectations. In this notation,
- * MIS -> mismatch, MAT -> match, BAD -> bad, and IGN -> ignored.
- *
- * RETV_MIS_* indicates the return value was either 0 or 1, but did
- * not match the expected return value
- *
- * _RETV_MAT_* indicates that the return value was 0 xor 1 and did
- * match the expected value
- *
- *_RETV_BAD_* the return value was neither 0 nor 1.
- *_ERRNO_MAT the error number matched the expected number
- *_ERRNO_MIS the error number did not match the expected number
- *_ERRNO_IGN no error number was expected and so errno was ignored
- *
- * Keep these values below 256 as only 1 byte gets passed as a
- * return value for the process. Note that RES_PASS is 0 which
- * LTP interprets as a PASS.
- */
-
-/* Did not get the expected return value, but errno value was expected */
-#define RES_FAIL_RETV_MIS_ERRNO_MAT 1
-/* Did not get the expected return value, but errno value was expected */
-#define RES_FAIL_RETV_BAD_ERRNO_MAT 2
-/* Did get the expected return value, and errno value was not expected */
-#define RES_FAIL_RETV_MAT_ERRNO_MIS 3
-/* Return value was neither 0 nor -1. Mismatch in value of errno */
-#define RES_FAIL_RETV_BAD_ERRNO_MIS 4
-/* Did not get the expected return value and errno is irrelevant */
-#define RES_FAIL_RETV_MIS_ERRNO_IGN 5
-/* Return value was neither 0 nor -1. value of errno is irrelevant */
-#define RES_FAIL_RETV_BAD_ERRNO_IGN 6
-/* We expected multiple errors so we were unable to check errno for conformance */
-#define RES_PASS_RETV_MAT_ERRNO_IGN 7
-
-static const char *result_strings[] = {
- "Passed",
- "Return value mismatched yet errno matched.",
- "Return value was bad yet errno matched.",
- "Return value matched yet errno mismatched.",
- "Return value was bad and errno mismatched.",
- "Return value mismatched so errno ignored.",
- "Return value was bad so errno ignored.",
- "Return value matched but errno ignored. (multiple errors expected)"
-};
-
-/****************************************************************************************/
-/* This macro helps keep the code below understandable. It prints out the
- failure message passed to it plus the parameters to the system call. */
-#define EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS 1
-#if EPOLL_CTL_TEST_RESULTS_SHOW_PARAMS
-#define EPOLL_CTL_TEST_FAIL(msg , ...) \
-({ \
- if (ev_ptr != NULL) { \
- tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
- epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
- epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
- strerror(errno)); \
- } else { \
- tst_resm(TFAIL, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
- epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
- epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
- } \
-})
-
-#define EPOLL_CTL_TEST_PASS(msg , ...) \
-({ \
- if (ev_ptr != NULL) { \
- tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p = {%08x,%08d}) returned %d:%s)" ) , ##__VA_ARGS__ , \
- epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
- epoll_fds[fd_index], ev_ptr, ev_ptr->events, ev_ptr->data.fd, errno, \
- strerror(errno)); \
- } else { \
- tst_resm(TPASS, ( "(epoll_ctl(%d,%08x,%d,%p) returned %d:%s)" ) , ##__VA_ARGS__ , \
- epoll_fds[epfd_index], epoll_ctl_ops[op_index], \
- epoll_fds[fd_index], ev_ptr, errno, strerror(errno)); \
- } \
-})
-#else
-#define EPOLL_CTL_TEST_FAIL(msg , ...) tst_resm(TFAIL, msg , ##__VA_ARGS__)
-#define EPOLL_CTL_TEST_PASS(msg , ...) tst_resm(TPASS, msg , ##__VA_ARGS__)
-#endif
-
-/****************************************************************************************/
-
-int test_epoll_ctl(int epoll_fd)
-{
- int fds[] = { -1, INT_MAX };
- int epoll_fds[] = { 0, -1, 0, INT_MAX };
- int epoll_events[64];
- /* The list of operations to try AND THE ORDER THEY ARE TRIED IN */
- int epoll_ctl_ops[] =
- { EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_ADD, EPOLL_CTL_MOD,
- EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLL_CTL_DEL, INT_MAX, -1
- };
- struct epoll_event event;
- char event_mem[sizeof(struct epoll_event) * 2];
- struct epoll_event *unaligned_event_ptr;
-
- /* Indices into lists */
- int index = 0; /* multi-use index. First uses are to initialize
- lists. Second use is to iterate over the implicit
- list of structs to pass in */
- unsigned int epfd_index; /* index into fd list for the epfd parameter */
- unsigned int event_index; /* index into event list for the events field of the
- struct epoll_event parameter */
- unsigned int fd_index; /* index into fd list for the fd parameter */
- unsigned int op_index; /* index into the list of operations for the op
- parameter */
- unsigned int num_epoll_ctl_test_fails = 0;
- unsigned int num_epoll_ctl_test_calls = 0;
-
- /* Generate all possible combinations of events (2^6 == 64)
- Assume we know nothing about the EPOLL event types _except_
- that they describe bits in a set. */
- for (index = 0; index < 64; index++) {
- epoll_events[index] = ((EPOLLIN * ((index & 0x01) >> 0)) |
- (EPOLLOUT * ((index & 0x02) >> 1)) |
- (EPOLLPRI * ((index & 0x04) >> 2)) |
- (EPOLLERR * ((index & 0x08) >> 3)) |
- (EPOLLHUP * ((index & 0x10) >> 4)) |
- (EPOLLET * ((index & 0x20) >> 5)));
- }
-
- /* Get a pointer to an unaligned struct epoll_event */
- {
- char *unalign_ptr = event_mem;
-
- unalign_ptr =
- unalign_ptr + (((unsigned long)unalign_ptr & 1) ? 0 : 1);
- unaligned_event_ptr = (struct epoll_event *)unalign_ptr;
- }
-
- /* One of the fds we want to test is the valid one */
- epoll_fds[0] = epoll_fd;
-
- /* Test out all of the interesting combinations. This is going to
- take a while (in compute cycles). It took less than 1 minute to
- run on a PIII 500 without checking the results. */
- for (index = 0; index < 3; index++) {
- struct epoll_event *ev_ptr = NULL;
-
- switch (index) {
- case 0: /* Pass aligned struct */
- event.data.u64 = 0;
- ev_ptr = &event;
- break;
- case 1: /* Pass unaligned struct */
- unaligned_event_ptr->data.u64 = 0;
- ev_ptr = unaligned_event_ptr;
- break;
- case 2:
- default: /* Pass NULL ptr */
- ev_ptr = NULL;
- break;
- }
-
- for (epfd_index = 0;
- epfd_index < (sizeof(epoll_fds) / sizeof(int));
- epfd_index++) {
- for (event_index = 0;
- event_index < (sizeof(epoll_events) / sizeof(int));
- event_index++) {
- for (fd_index = 0;
- fd_index < (sizeof(fds) / sizeof(int));
- fd_index++) {
- /* Now epoll_fd is a descriptor that references the set of
- file descriptors we are interested in. Next we test epoll_ctl */
- for (op_index = 0;
- op_index <
- (sizeof(epoll_ctl_ops) /
- sizeof(int)); op_index++) {
- int result;
- int expected_errno = 0;
- int num_errors_expected = 0;
-
- if (ev_ptr != NULL)
- ev_ptr->events =
- epoll_events
- [event_index];
-
- /* Perform the call itself. Put it in a protected region which
- returns -1 in the variable result if a protection violation
- occurs (see PROTECT_REGION_END for the result) */
- PROTECT_REGION_START errno = 0;
-
- /* NOTE that we are assuming that epoll will operate across
- a fork() call such that a subsequent fork() in the parent
- will also manipulate the same set */
- result =
- epoll_ctl(epoll_fds
- [epfd_index],
- epoll_ctl_ops
- [op_index],
- fds[fd_index],
- ev_ptr);
-
- /* We can't test errno resulting from the epoll_ctl call outside of
- the PROTECT_REGION hence we do not have a PROTECT_REGION_END
- here */
-
- /*
- Test the results. Look for appropriate error conditions
- */
-
- /* Check the epfd */
- if (epoll_fds[epfd_index] !=
- epoll_fd) {
- /* Expect an error */
- if (epoll_fds
- [epfd_index] == 0)
- expected_errno =
- EINVAL;
- else /* epfd is not a valid file descriptor since it is
- neither epoll_fd nor stdin */
- expected_errno =
- EBADF;
- num_errors_expected++;
- }
-
- switch (epoll_ctl_ops[op_index]) {
- case EPOLL_CTL_ADD:
- case EPOLL_CTL_MOD:
- case EPOLL_CTL_DEL:
- break;
- default: /* Expect an error */
- expected_errno = EINVAL;
- num_errors_expected++;
- break;
- }
-
- expected_errno = EPERM;
- num_errors_expected++;
-
- if (ev_ptr == NULL) {
- expected_errno = EINVAL;
- num_errors_expected++;
- } else if ((ev_ptr == &event)
- || (ev_ptr ==
- unaligned_event_ptr))
- {
- if (ev_ptr->events == 0) {
- expected_errno =
- EINVAL;
- num_errors_expected++;
- }
-
- for (index = 1;
- index < 64;
- index++) {
- if ((int)ev_ptr->events != epoll_events[index]) {
- expected_errno
- =
- EINVAL;
- num_errors_expected++;
- }
- }
- } else {
- /* Do not expect an error */
- }
-
- if (num_errors_expected == 0) {
- /* We did not expect an error */
- if (result == 0) {
- /* We didn't get an error. Think of this as RES_PASS_RETV_MAT_ERRNO_IGN */
- return RES_PASS;
- } else if (result == -1) { /* The return value is -1, so it's not bad */
- return
- RES_FAIL_RETV_MIS_ERRNO_IGN;
- } else {
- return
- RES_FAIL_RETV_BAD_ERRNO_IGN;
- }
- } else if (num_errors_expected
- == 1) {
- /* We expected an error */
- if (result == 0) {
- return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
- } else if (result == -1) {
- /* We got an error. Check errno */
- if (errno ==
- expected_errno)
- {
- return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
- } else {
- return
- RES_FAIL_RETV_MAT_ERRNO_MIS;
- }
- } else {
- /* We got a bad return code! Interpret this as
- getting an error and check errno. */
- if (errno ==
- expected_errno)
- return
- RES_FAIL_RETV_BAD_ERRNO_MAT;
- else
- return
- RES_FAIL_RETV_BAD_ERRNO_MIS;
- }
- } else if (num_errors_expected >
- 1) {
- /* We expected multiple errors */
- if (result == 0) {
- return RES_FAIL_RETV_MIS_ERRNO_IGN; /* Unexpected success */
- } else if (result == -1) {
- /* We got an error. Check errno */
- if (errno ==
- expected_errno)
- {
- return RES_PASS; /* think of this as RETV_MAT_ERRNO_MAT */
- } else {
- /* Ignore errno because the desired value is unknowable
- without looking at the structure of the code. */
- return
- RES_PASS_RETV_MAT_ERRNO_IGN;
- }
- } else {
- /* We got a bad return code! Interpret this as
- getting an error and check errno. */
- if (errno ==
- expected_errno)
- /* Don't Ignore errno because the desired value
- happened to match what we expected. */
- return
- RES_FAIL_RETV_BAD_ERRNO_MAT;
- else
- /* Ignore errno because the desired value is unknowable
- without looking at the structure of the code. */
- return
- RES_FAIL_RETV_BAD_ERRNO_IGN;
- }
- }
-
- /* All "return"s between PROTECT_REGION_BEGIN
- and PROTECT_REGION_END place their value in
- the result parameter. If the region caused
- a protection violation (segfault or otherwise)
- then the result is set to the second parameter's
- value (-1 in this case). */
- PROTECT_REGION_END(result, -1);
-
- /* Count the number of tests run */
- num_epoll_ctl_test_calls++;
-
- /* Now test the result */
- if (!((result == RES_PASS)
- || (result ==
- RES_PASS_RETV_MAT_ERRNO_IGN)))
- {
- if (result >
- (int)(sizeof(result_strings) /
- sizeof(const char
- *))) {
- /* Returned a result which has no corresponding text description */
- EPOLL_CTL_TEST_FAIL
- ("FIXME FIX ME BUG in Test Program itself!");
- } else {
- if (result == -1) /* Segfault during epoll_ctl call */
- EPOLL_CTL_TEST_FAIL
- ("Test arguments caused abnormal exit.");
- else /* The 'normal' failure */
- EPOLL_CTL_TEST_FAIL
- ((result_strings[result]));
- }
- num_epoll_ctl_test_fails++;
-#ifdef DEBUG
- } else /* The call of epoll_ctl behaved as expected */
- EPOLL_CTL_TEST_PASS((result_strings[result]));
-#else
- }
-#endif
- }
- }
- }
- }
- close(epoll_fd);
- }
-
- tst_resm(TINFO,
- "Summary: Of %d tests, epoll_ctl failed %d (%3.0f%% passed).",
- num_epoll_ctl_test_calls, num_epoll_ctl_test_fails,
- ((float)(num_epoll_ctl_test_calls - num_epoll_ctl_test_fails) *
- 100.0f / (float)num_epoll_ctl_test_calls));
- return (num_epoll_ctl_test_fails / num_epoll_ctl_test_calls);
-}
-
-int main(void)
-{
- int epoll_fd;
- struct timeval tv;
- int last_result;
-
- tst_resm(TINFO, "testing if epoll() system call works");
-
- /* Get the current time */
- if (gettimeofday(&tv, NULL) != 0) {
- tst_brkm(TBROK | TERRNO, NULL, "gettimeofday failed");
- } else {
- tst_resm(TINFO, "gettimeofday() works");
- }
-
- /* Set up RNG */
- srand(tv.tv_usec);
- tst_resm(TINFO,
- "random number seeded with gettimeofday() [seed = %ld] works",
- tv.tv_usec);
-
- tst_resm(TINFO, "Testing epoll_create");
- /* Testing epoll_create with some different sizes */
- last_result = PROTECT_FUNC(test_epoll_create, -1, NUM_RAND_ATTEMPTS);
- if (last_result != 0) {
- /* create test(s) failed */
- }
-
- /* Create an epoll_fd for testing epoll_ctl */
- epoll_fd = epoll_create(BACKING_STORE_SIZE_HINT);
- if (epoll_fd < 0) {
- tst_brkm(TFAIL | TERRNO, NULL, "epoll_create failed");
- }
-
- tst_resm(TINFO, "Testing epoll_ctl");
- last_result = PROTECT_FUNC(test_epoll_ctl, -1, epoll_fd);
- if (last_result != 0) {
- /* ctl test(s) failed */
- }
-
- tst_exit();
-}
-
-#else
-
-int main(void)
-{
- tst_brkm(TCONF, NULL, "No epoll support found.");
-}
-
-#endif
--
2.52.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
@ 2026-04-23 12:41 ` Petr Vorel
2026-04-23 13:43 ` [LTP] " linuxtestproject.agent
1 sibling, 0 replies; 11+ messages in thread
From: Petr Vorel @ 2026-04-23 12:41 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
LGTM, thanks!
Reviewed-by: Petr Vorel <pvorel@suse.cz>
> +
> +/*\
> + * Verify that epoll_create() fails with EMFILE when the per-process limit on
nit (please fix before merge):
:manpage:`epoll_create(2)`
to have link to the man page in the test catalog
https://man7.org/linux/man-pages/man2/epoll_create.2.html
https://github.com/linux-test-project/ltp-agent/pull/4
Kind regards,
Petr
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [LTP] syscalls: Add epoll_create03
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
2026-04-23 12:41 ` Petr Vorel
@ 2026-04-23 13:43 ` linuxtestproject.agent
1 sibling, 0 replies; 11+ messages in thread
From: linuxtestproject.agent @ 2026-04-23 13:43 UTC (permalink / raw)
To: Cyril Hrubis; +Cc: ltp
Hi Cyril,
--- [PATCH 2/8] ---
On 2026-04-23, Cyril Hrubis wrote:
> syscalls: Add epoll_wait08
> + * - Create an epoll instance and register a socket fd for EPOLLIN.
> + * - Fork a child that waits for the parent to enter epoll_wait, then sends
> + * SIGUSR1 to interrupt it.
The algorithm comment is wrong on two counts. No fd is registered with the
epoll instance — setup() only calls SAFE_EPOLL_CREATE1(). And it is the
child that blocks in epoll_wait, not the parent; the parent sends SIGUSR1.
--- [PATCH 6/8] ---
On 2026-04-23, Cyril Hrubis wrote:
> syscalls: Add epoll_wait11
> + * - The child's epoll_wait should return with EPOLLHUP and the child reports
> + * the result via its exit code.
The child reports via tst_res(TPASS/TFAIL, ...) before exit(0), not via
the exit code. Fix the comment accordingly.
---
Note:
Our agent completed the review of the patch. The full review can be
found at: https://patchwork.ozlabs.org/project/ltp/list/?series=501188
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-04-23 13:43 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-23 12:03 [LTP] [PATCH v2 0/8] Add more epoll tests Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 1/8] syscalls: Add epoll_create03 Cyril Hrubis
2026-04-23 12:41 ` Petr Vorel
2026-04-23 13:43 ` [LTP] " linuxtestproject.agent
2026-04-23 12:03 ` [LTP] [PATCH v2 2/8] syscalls: Add epoll_wait08 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 3/8] syscalls: Add epoll_wait09 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 4/8] syscalls: Add epoll_ctl06 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 5/8] syscalls: Add epoll_wait10 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 6/8] syscalls: Add epoll_wait11 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 7/8] syscalls: Add epoll_wait12 Cyril Hrubis
2026-04-23 12:03 ` [LTP] [PATCH v2 8/8] syscalls: Remove old epoll-ltp test Cyril Hrubis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox