Message ID | 20230823130904.26051-1-andrea.cervesato@suse.de |
---|---|
State | Accepted |
Headers | show |
Series | [v4] Add epoll_wait05 test | expand |
Hi! > This test verifies that epoll receives EPOLLRDHUP event when we hang > a reading half-socket we are polling on. > > Implements: https://github.com/linux-test-project/ltp/issues/860 > Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> ... > +/*\ > + * [Description] > + * > + * Verify that epoll receives EPOLLRDHUP event when we hang a reading > + * half-socket we are polling on. > + * > + * As reference please check https://lwn.net/Articles/864947/ I'm a bit confused here, the test itself looks good, but it references an article and a kernel commit that changed how polling on _pipe_ works. The kernel change literally changes only pipe_write() in fs/pipe.c and this test actually tests inet sockets. I guess that the confusion is caused by the fact that the github issue referenced the lwn.net article as a reason why we need more epoll coverage, but these tests are not directly related to that commit at all.
Hi, On 8/29/23 09:25, Cyril Hrubis wrote: > Hi! >> This test verifies that epoll receives EPOLLRDHUP event when we hang >> a reading half-socket we are polling on. >> >> Implements: https://github.com/linux-test-project/ltp/issues/860 >> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com> > ... > >> +/*\ >> + * [Description] >> + * >> + * Verify that epoll receives EPOLLRDHUP event when we hang a reading >> + * half-socket we are polling on. >> + * >> + * As reference please check https://lwn.net/Articles/864947/ > I'm a bit confused here, the test itself looks good, but it references > an article and a kernel commit that changed how polling on _pipe_ works. > The kernel change literally changes only pipe_write() in fs/pipe.c and > this test actually tests inet sockets. > > I guess that the confusion is caused by the fact that the github issue > referenced the lwn.net article as a reason why we need more epoll > coverage, but these tests are not directly related to that commit at > all. > If patch is fine, is it possible to push it removing the reference? Thanks, Andrea
Hi!
> If patch is fine, is it possible to push it removing the reference?
Sure, will do.
Hi!
> If patch is fine, is it possible to push it removing the reference?
Pushed with one minor change, thanks.
I've also added check that epoll_wait() returns 1 otherwise the content
of the returned event is not valid.
Full diff:
diff --git a/testcases/kernel/mce-test b/testcases/kernel/mce-test
index 95e136a3b..0b4e77570 160000
--- a/testcases/kernel/mce-test
+++ b/testcases/kernel/mce-test
@@ -1 +1 @@
-Subproject commit 95e136a3b0cde818448d5fcff5bf75d58600dc0d
+Subproject commit 0b4e7757068381139db1317c07bdb7532196ef76
diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
index a055a5885..d06a024ff 100644
--- a/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
@@ -8,8 +8,6 @@
*
* Verify that epoll receives EPOLLRDHUP event when we hang a reading
* half-socket we are polling on.
- *
- * As reference please check https://lwn.net/Articles/864947/
*/
#include "tst_test.h"
@@ -52,6 +50,7 @@ static void run(void)
struct sockaddr_in client_addr;
struct epoll_event evt_req;
struct epoll_event evt_rec;
+ int ret;
if (!SAFE_FORK()) {
create_server();
@@ -79,13 +78,18 @@ static void run(void)
tst_res(TINFO, "Hang socket");
TST_EXP_PASS_SILENT(shutdown(sockfd_client, SHUT_RD));
- SAFE_EPOLL_WAIT(epfd, &evt_rec, 1, 2000);
+ ret = SAFE_EPOLL_WAIT(epfd, &evt_rec, 1, 2000);
+ if (ret != 1) {
+ tst_res(TFAIL, "Wrong number of events reported %i", ret);
+ goto exit;
+ }
if (evt_rec.events & EPOLLRDHUP)
tst_res(TPASS, "Received EPOLLRDHUP");
else
tst_res(TFAIL, "EPOLLRDHUP has not been received");
+exit:
SAFE_CLOSE(epfd);
SAFE_CLOSE(sockfd_client);
@@ -119,8 +123,4 @@ static struct tst_test test = {
.test_all = run,
.forks_child = 1,
.needs_checkpoints = 1,
- .tags = (const struct tst_tag[]) {
- {"linux-git", "3a34b13a88ca"},
- {},
- }
};
diff --git a/runtest/syscalls b/runtest/syscalls index 7af2842f3..27819b41b 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -175,6 +175,7 @@ epoll_wait01 epoll_wait01 epoll_wait02 epoll_wait02 epoll_wait03 epoll_wait03 epoll_wait04 epoll_wait04 +epoll_wait05 epoll_wait05 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 222955dd2..ab5a9c010 100644 --- a/testcases/kernel/syscalls/epoll_wait/.gitignore +++ b/testcases/kernel/syscalls/epoll_wait/.gitignore @@ -2,3 +2,4 @@ epoll_wait01 epoll_wait02 epoll_wait03 epoll_wait04 +epoll_wait05 diff --git a/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c new file mode 100644 index 000000000..a055a5885 --- /dev/null +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2023 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com> + */ + +/*\ + * [Description] + * + * Verify that epoll receives EPOLLRDHUP event when we hang a reading + * half-socket we are polling on. + * + * As reference please check https://lwn.net/Articles/864947/ + */ + +#include "tst_test.h" +#include "tst_net.h" +#include "tst_epoll.h" + +static int epfd; +static int sockfd_client; +static int sockfd_server; +static in_port_t *sock_port; + +static void create_server(void) +{ + int sockfd_server; + socklen_t len; + struct sockaddr_in serv_addr; + struct sockaddr_in sin; + + tst_init_sockaddr_inet_bin(&serv_addr, INADDR_ANY, 0); + + sockfd_server = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0); + SAFE_BIND(sockfd_server, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); + SAFE_LISTEN(sockfd_server, 10); + + len = sizeof(sin); + memset(&sin, 0, sizeof(struct sockaddr_in)); + SAFE_GETSOCKNAME(sockfd_server, (struct sockaddr *)&sin, &len); + + *sock_port = ntohs(sin.sin_port); + + tst_res(TINFO, "Listening on port %d", *sock_port); + + TST_CHECKPOINT_WAKE_AND_WAIT(0); + + SAFE_CLOSE(sockfd_server); +} + +static void run(void) +{ + struct sockaddr_in client_addr; + struct epoll_event evt_req; + struct epoll_event evt_rec; + + if (!SAFE_FORK()) { + create_server(); + return; + } + + TST_CHECKPOINT_WAIT(0); + + tst_res(TINFO, "Connecting to port %d", *sock_port); + + sockfd_client = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0); + + tst_init_sockaddr_inet(&client_addr, "127.0.0.1", *sock_port); + + SAFE_CONNECT(sockfd_client, + (struct sockaddr *)&client_addr, + sizeof(client_addr)); + + tst_res(TINFO, "Polling on socket"); + + epfd = SAFE_EPOLL_CREATE1(0); + evt_req.events = EPOLLRDHUP; + SAFE_EPOLL_CTL(epfd, EPOLL_CTL_ADD, sockfd_client, &evt_req); + + tst_res(TINFO, "Hang socket"); + + TST_EXP_PASS_SILENT(shutdown(sockfd_client, SHUT_RD)); + SAFE_EPOLL_WAIT(epfd, &evt_rec, 1, 2000); + + if (evt_rec.events & EPOLLRDHUP) + tst_res(TPASS, "Received EPOLLRDHUP"); + else + tst_res(TFAIL, "EPOLLRDHUP has not been received"); + + SAFE_CLOSE(epfd); + SAFE_CLOSE(sockfd_client); + + TST_CHECKPOINT_WAKE(0); +} + +static void setup(void) +{ + sock_port = SAFE_MMAP(NULL, sizeof(in_port_t), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); +} + +static void cleanup(void) +{ + if (sock_port) + SAFE_MUNMAP(sock_port, sizeof(in_port_t)); + + if (fcntl(sockfd_client, F_GETFD) > 0) + SAFE_CLOSE(sockfd_client); + + if (fcntl(sockfd_server, F_GETFD) > 0) + SAFE_CLOSE(sockfd_server); + + if (fcntl(epfd, F_GETFD) > 0) + SAFE_CLOSE(epfd); +} + +static struct tst_test test = { + .setup = setup, + .cleanup = cleanup, + .test_all = run, + .forks_child = 1, + .needs_checkpoints = 1, + .tags = (const struct tst_tag[]) { + {"linux-git", "3a34b13a88ca"}, + {}, + } +};