* [LTP] [PATCH v3] Add epoll_wait05 test
@ 2023-03-15 15:03 Andrea Cervesato
2023-07-21 15:45 ` Petr Vorel
0 siblings, 1 reply; 3+ messages in thread
From: Andrea Cervesato @ 2023-03-15 15:03 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
This test verifies that epoll receives EPOLLRDHUP event when we hang
a reading half-socket we are polling on.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
.../kernel/syscalls/epoll_wait/.gitignore | 1 +
.../kernel/syscalls/epoll_wait/epoll_wait05.c | 117 ++++++++++++++++++
2 files changed, 118 insertions(+)
create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
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..e43cac933
--- /dev/null
+++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
@@ -0,0 +1,117 @@
+// 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.
+ */
+
+#define _GNU_SOURCE
+#include "tst_test.h"
+#include "tst_epoll.h"
+
+static int epfd;
+static in_port_t *sock_port;
+
+static void create_server(void)
+{
+ int sockfd;
+ socklen_t len;
+ struct sockaddr_in serv_addr;
+ struct sockaddr_in sin;
+
+ memset(&serv_addr, 0, sizeof(struct sockaddr_in));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = 0;
+
+ sockfd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+ SAFE_BIND(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
+ SAFE_LISTEN(sockfd, 10);
+
+ len = sizeof(sin);
+ memset(&sin, 0, sizeof(struct sockaddr_in));
+ SAFE_GETSOCKNAME(sockfd, (struct sockaddr *)&sin, &len);
+
+ *sock_port = sin.sin_port;
+
+ tst_res(TINFO, "Listening on port %d", *sock_port);
+
+ TST_CHECKPOINT_WAKE_AND_WAIT(0);
+
+ SAFE_CLOSE(sockfd);
+}
+
+static void run(void)
+{
+ int sockfd;
+ 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 = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
+
+ memset(&client_addr, 0, sizeof(struct sockaddr));
+ client_addr.sin_family = AF_INET;
+ client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+ client_addr.sin_port = *sock_port;
+
+ SAFE_CONNECT(sockfd, (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, &evt_req);
+
+ tst_res(TINFO, "Hang socket");
+
+ TST_EXP_PASS_SILENT(shutdown(sockfd, 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);
+
+ 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 (epfd > 0)
+ SAFE_CLOSE(epfd);
+}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .forks_child = 1,
+ .needs_checkpoints = 1,
+};
--
2.35.3
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [LTP] [PATCH v3] Add epoll_wait05 test
2023-03-15 15:03 [LTP] [PATCH v3] Add epoll_wait05 test Andrea Cervesato
@ 2023-07-21 15:45 ` Petr Vorel
2023-08-23 8:40 ` Richard Palethorpe
0 siblings, 1 reply; 3+ messages in thread
From: Petr Vorel @ 2023-07-21 15:45 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
> This test verifies that epoll receives EPOLLRDHUP event when we hang
> a reading half-socket we are polling on.
Commit message would deserver
Implements: https://github.com/linux-test-project/ltp/issues/860
(Although the ticket asks to cover more flags than just EPOLLET).
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> .../kernel/syscalls/epoll_wait/.gitignore | 1 +
> .../kernel/syscalls/epoll_wait/epoll_wait05.c | 117 ++++++++++++++++++
Test is missing a record in runtest/syscalls.
> 2 files changed, 118 insertions(+)
> create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
> 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..e43cac933
> --- /dev/null
> +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
> @@ -0,0 +1,117 @@
> +// 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.
I'd put here the LWN article:
https://lwn.net/Articles/864947/
> + */
> +
> +#define _GNU_SOURCE
Why is _GNU_SOURCE needed?
> +#include "tst_test.h"
> +#include "tst_epoll.h"
> +
> +static int epfd;
> +static in_port_t *sock_port;
> +
> +static void create_server(void)
> +{
> + int sockfd;
> + socklen_t len;
> + struct sockaddr_in serv_addr;
> + struct sockaddr_in sin;
> +
> + memset(&serv_addr, 0, sizeof(struct sockaddr_in));
> + serv_addr.sin_family = AF_INET;
> + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
> + serv_addr.sin_port = 0;
You could use tst_init_sockaddr_inet_bin() (include include "tst_net.h").
> +
> + sockfd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
> + SAFE_BIND(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
> + SAFE_LISTEN(sockfd, 10);
> +
> + len = sizeof(sin);
> + memset(&sin, 0, sizeof(struct sockaddr_in));
> + SAFE_GETSOCKNAME(sockfd, (struct sockaddr *)&sin, &len);
> +
> + *sock_port = sin.sin_port;
> +
> + tst_res(TINFO, "Listening on port %d", *sock_port);
> +
> + TST_CHECKPOINT_WAKE_AND_WAIT(0);
> +
> + SAFE_CLOSE(sockfd);
> +}
> +
> +static void run(void)
> +{
> + int sockfd;
> + 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 = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
> +
> + memset(&client_addr, 0, sizeof(struct sockaddr));
> + client_addr.sin_family = AF_INET;
> + client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
> + client_addr.sin_port = *sock_port;
And here as well.
> +
> + SAFE_CONNECT(sockfd, (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, &evt_req);
> +
> + tst_res(TINFO, "Hang socket");
> +
> + TST_EXP_PASS_SILENT(shutdown(sockfd, 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);
In extreme case when SAFE_EPOLL_WAIT() fails sockfd will not get closed, right?
This could be problem on high number of iterations. But I guess it's just a
theoretical problem.
> +
> + 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 (epfd > 0)
> + SAFE_CLOSE(epfd);
> +}
> +
> +static struct tst_test test = {
> + .setup = setup,
> + .cleanup = cleanup,
> + .test_all = run,
> + .forks_child = 1,
> + .needs_checkpoints = 1,
IMHO there should be 3a34b13a88ca commit marked in tags:
.tags = (const struct tst_tag[]) {
{"linux-git", "3a34b13a88ca"},
{}
The rest LGTM.
Reviewed-by: Petr Vorel <pvorel@suse.cz>
> +};
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [LTP] [PATCH v3] Add epoll_wait05 test
2023-07-21 15:45 ` Petr Vorel
@ 2023-08-23 8:40 ` Richard Palethorpe
0 siblings, 0 replies; 3+ messages in thread
From: Richard Palethorpe @ 2023-08-23 8:40 UTC (permalink / raw)
To: Petr Vorel; +Cc: ltp
Hello,
Petr Vorel <pvorel@suse.cz> writes:
> Hi Andrea,
>
>> This test verifies that epoll receives EPOLLRDHUP event when we hang
>> a reading half-socket we are polling on.
>
> Commit message would deserver
>
> Implements: https://github.com/linux-test-project/ltp/issues/860
> (Although the ticket asks to cover more flags than just EPOLLET).
>
>> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
>> ---
>> .../kernel/syscalls/epoll_wait/.gitignore | 1 +
>> .../kernel/syscalls/epoll_wait/epoll_wait05.c | 117 ++++++++++++++++++
> Test is missing a record in runtest/syscalls.
>
>> 2 files changed, 118 insertions(+)
>> create mode 100644 testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
>
>> 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..e43cac933
>> --- /dev/null
>> +++ b/testcases/kernel/syscalls/epoll_wait/epoll_wait05.c
>> @@ -0,0 +1,117 @@
>> +// 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.
>
> I'd put here the LWN article:
> https://lwn.net/Articles/864947/
>> + */
>> +
>> +#define _GNU_SOURCE
> Why is _GNU_SOURCE needed?
>
>> +#include "tst_test.h"
>> +#include "tst_epoll.h"
>> +
>> +static int epfd;
>> +static in_port_t *sock_port;
>> +
>> +static void create_server(void)
>> +{
>> + int sockfd;
>> + socklen_t len;
>> + struct sockaddr_in serv_addr;
>> + struct sockaddr_in sin;
>> +
>> + memset(&serv_addr, 0, sizeof(struct sockaddr_in));
>> + serv_addr.sin_family = AF_INET;
>> + serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
>> + serv_addr.sin_port = 0;
> You could use tst_init_sockaddr_inet_bin() (include include "tst_net.h").
>> +
>> + sockfd = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
>> + SAFE_BIND(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
>> + SAFE_LISTEN(sockfd, 10);
>> +
>> + len = sizeof(sin);
>> + memset(&sin, 0, sizeof(struct sockaddr_in));
>> + SAFE_GETSOCKNAME(sockfd, (struct sockaddr *)&sin, &len);
>> +
>> + *sock_port = sin.sin_port;
>> +
>> + tst_res(TINFO, "Listening on port %d", *sock_port);
>> +
>> + TST_CHECKPOINT_WAKE_AND_WAIT(0);
>> +
>> + SAFE_CLOSE(sockfd);
>> +}
>> +
>> +static void run(void)
>> +{
>> + int sockfd;
>> + 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 = SAFE_SOCKET(AF_INET, SOCK_STREAM, 0);
>> +
>> + memset(&client_addr, 0, sizeof(struct sockaddr));
>> + client_addr.sin_family = AF_INET;
>> + client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
>> + client_addr.sin_port = *sock_port;
> And here as well.
>
>> +
>> + SAFE_CONNECT(sockfd, (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, &evt_req);
>> +
>> + tst_res(TINFO, "Hang socket");
>> +
>> + TST_EXP_PASS_SILENT(shutdown(sockfd, 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);
> In extreme case when SAFE_EPOLL_WAIT() fails sockfd will not get closed, right?
> This could be problem on high number of iterations. But I guess it's just a
> theoretical problem.
Let's just assume it is a problem because it is easy to add the cleanup
code.
Something to think about is that regardless of test iterations, the
kernel may behave differently when cleaning up a socket on process
termination rather than a deliberate close. For e.g. it could do a bulk
cleanup after some delay, so you may get errors happening as the next
test executes.
Of course that can happen with a deliberate close as well, but you are
bringing the close forward at least. Also it makes the behaviour of the
test after an error more similar to if there were not an error. So
comparing the output may be easier.
>
>> +
>> + 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 (epfd > 0)
>> + SAFE_CLOSE(epfd);
>> +}
>> +
>> +static struct tst_test test = {
>> + .setup = setup,
>> + .cleanup = cleanup,
>> + .test_all = run,
>> + .forks_child = 1,
>> + .needs_checkpoints = 1,
> IMHO there should be 3a34b13a88ca commit marked in tags:
>
> .tags = (const struct tst_tag[]) {
> {"linux-git", "3a34b13a88ca"},
> {}
>
> The rest LGTM.
>
> Reviewed-by: Petr Vorel <pvorel@suse.cz>
>
>> +};
I'll set this to changes requested in patchwork
--
Thank you,
Richard.
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-08-23 9:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-15 15:03 [LTP] [PATCH v3] Add epoll_wait05 test Andrea Cervesato
2023-07-21 15:45 ` Petr Vorel
2023-08-23 8:40 ` Richard Palethorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox