[v2,10/10] test: eventfs00 -- Extend to test duped fd

Submitted by Andrei Vagin on June 30, 2018, 1:44 a.m.

Details

Message ID 20180630014458.GB24896@outlook.office365.com
State New
Series "epoll: Add support for duped targets"
Headers show

Commit Message

Andrei Vagin June 30, 2018, 1:44 a.m.
On Wed, Jun 27, 2018 at 12:12:05PM +0300, Cyrill Gorcunov wrote:
> From: Cyrill Gorcunov <gorcunov@openvz.org>
> 
> To make sure criu can handle dup'ed and closed
> file descriptors.

Cyrill, this test checks nothing about epollfd and I don't know why we
check epoll in the eventfs test. eventfs and epoll are two different
sub-systems, aren't they?

Pls, take a look at the attached test and try to understand why it
fails.

Thanks,
Andrei

> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
> ---
>  test/zdtm/static/eventfs00.c | 81 ++++++++++++++++++++++++++++++++++----------
>  1 file changed, 63 insertions(+), 18 deletions(-)
> 
> diff --git a/test/zdtm/static/eventfs00.c b/test/zdtm/static/eventfs00.c
> index 72fd38a9cfa2..abcfd036e395 100644
> --- a/test/zdtm/static/eventfs00.c
> +++ b/test/zdtm/static/eventfs00.c
> @@ -29,67 +29,112 @@ const char *test_doc	= "Check for eventfs";
>  const char *test_author	= "Cyrill Gorcunov <gorcunov@openvz.org>";
>  
>  #define EVENTFD_INITIAL	30
> -#define EVENTFD_FINAL	90
> +#define EVENTFD_FINAL1	90
> +#define EVENTFD_FINAL2	(EVENTFD_FINAL1 * 2)
> +#define DUPFDNO		999
>  
>  int main(int argc, char *argv[])
>  {
> -	int efd, ret, epollfd;
> -	int pipefd[2];
>  	uint64_t v = EVENTFD_INITIAL;
> +	int efd, ret, epollfd, fd;
>  	struct epoll_event ev;
> +	int i;
> +
> +	struct {
> +		int	pipefd1[2];
> +		int	pipefd2[2];
> +	} pipes[10];
>  
>  	test_init(argc, argv);
>  
>  	epollfd = epoll_create(1);
>  	if (epollfd < 0) {
> -		fail("epoll_create");
> +		pr_perror("epoll_create failed");
>  		exit(1);
>  	}
>  
>  	efd = eventfd((unsigned int)v, EFD_NONBLOCK);
>  	if (efd < 0) {
> -		fail("eventfd");
> +		pr_perror("eventfd failed");
>  		exit(1);
>  	}
>  
> +	test_msg("created eventfd with %lld\n", (long long)v);
> +
>  	memset(&ev, 0xff, sizeof(ev));
>  	ev.events = EPOLLIN | EPOLLOUT;
>  
> -	if (pipe(pipefd)) {
> -		fail("pipe");
> +	for (i = 0; i < ARRAY_SIZE(pipes); i++) {
> +		if (pipe(pipes[i].pipefd1) || pipe(pipes[i].pipefd2)) {
> +			pr_err("Can't create pipe %d\n", i);
> +			exit(1);
> +		}
> +
> +		test_msg("epoll %d add %d native\n", epollfd, pipes[i].pipefd1[0]);
> +		if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipes[i].pipefd1[0], &ev)) {
> +			pr_perror("Can't add pipe %d", pipes[i].pipefd1[0]);
> +			exit(1);
> +		}
> +
> +		fd = dup2(pipes[i].pipefd2[0], DUPFDNO);
> +		if (fd < 0) {
> +			pr_perror("Can't dup %d to %d", pipes[i].pipefd2[0], DUPFDNO);
> +			exit(1);
> +		}
> +		test_msg("epoll %d add %d dup'ed from %d\n", epollfd, fd, pipes[i].pipefd2[0]);
> +
> +		close(fd);
> +		test_msg("epoll source %d closed\n", fd);
> +	}
> +
> +	ret = write(efd, &v, sizeof(v));
> +	if (ret != sizeof(v)) {
> +		pr_perror("write failed");
>  		exit(1);
>  	}
>  
> -	if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd[0], &ev)) {
> -		fail("epoll_ctl");
> +	ret = write(efd, &v, sizeof(v));
> +	if (ret != sizeof(v)) {
> +		pr_perror("write failed");
>  		exit(1);
>  	}
>  
> -	test_msg("created eventfd with %"PRIu64"\n", v);
> +	test_daemon();
> +	test_waitsig();
>  
> -	ret = write(efd, &v, sizeof(v));
> +	ret = read(efd, &v, sizeof(v));
>  	if (ret != sizeof(v)) {
> -		fail("write");
> +		pr_perror("read failed");
> +		exit(1);
> +	}
> +
> +	if (v != EVENTFD_FINAL1) {
> +		fail("EVENTFD_FINAL1 mismatch (got %lld but %lld expected)\n",
> +		     (long long)v, (long long)EVENTFD_FINAL1);
>  		exit(1);
>  	}
>  
>  	ret = write(efd, &v, sizeof(v));
>  	if (ret != sizeof(v)) {
> -		fail("write");
> +		pr_perror("write failed");
>  		exit(1);
>  	}
>  
> -	test_daemon();
> -	test_waitsig();
> +	ret = write(efd, &v, sizeof(v));
> +	if (ret != sizeof(v)) {
> +		pr_perror("write failed");
> +		exit(1);
> +	}
>  
>  	ret = read(efd, &v, sizeof(v));
>  	if (ret != sizeof(v)) {
> -		fail("write");
> +		pr_perror("read failed");
>  		exit(1);
>  	}
>  
> -	if (v != EVENTFD_FINAL) {
> -		fail("EVENTFD_FINAL mismatch\n");
> +	if (v != EVENTFD_FINAL2) {
> +		fail("EVENTFD_FINAL2 mismatch (got %lld but %lld expected)\n",
> +		     (long long)v, (long long)EVENTFD_FINAL2);
>  		exit(1);
>  	}
>  
> -- 
> 2.14.4
>
From aa00fec086f016f036e6831294cd3e53128601e0 Mon Sep 17 00:00:00 2001
From: Andrei Vagin <avagin@virtuozzo.com>
Date: Sat, 30 Jun 2018 04:40:40 +0300
Subject: [PATCH] zdtm/static: add a test to check epoll file descriptors

Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
---
 test/zdtm/static/Makefile |   1 +
 test/zdtm/static/epoll.c  | 123 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 test/zdtm/static/epoll.c

Patch hide | download patch | download mbox

diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile
index d61ef33b9..4c32f991f 100644
--- a/test/zdtm/static/Makefile
+++ b/test/zdtm/static/Makefile
@@ -121,6 +121,7 @@  TST_NOFILE	:=				\
 		proc-self			\
 		proc-self01			\
 		eventfs00			\
+		epoll				\
 		signalfd00			\
 		inotify_irmap			\
 		fanotify00			\
diff --git a/test/zdtm/static/epoll.c b/test/zdtm/static/epoll.c
new file mode 100644
index 000000000..09076f118
--- /dev/null
+++ b/test/zdtm/static/epoll.c
@@ -0,0 +1,123 @@ 
+#include <unistd.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "zdtmtst.h"
+
+#ifndef F_SETSIG
+#define F_SETSIG	10	/* for sockets. */
+#define F_GETSIG	11	/* for sockets. */
+#endif
+
+const char *test_doc	= "Check for eventfs";
+const char *test_author	= "Cyrill Gorcunov <gorcunov@openvz.org>";
+
+#define EVENTFD_INITIAL	30
+#define EVENTFD_FINAL1	90
+#define EVENTFD_FINAL2	(EVENTFD_FINAL1 * 2)
+#define DUPFDNO		999
+
+int main(int argc, char *argv[])
+{
+	uint64_t v = EVENTFD_INITIAL;
+	int epollfd, epollfd2, fd;
+	struct epoll_event ev;
+	int i;
+
+	struct {
+		int	pipefd1[2];
+		int	pipefd2[2];
+	} pipes[100];
+
+	test_init(argc, argv);
+
+	epollfd = epoll_create(1);
+	if (epollfd < 0) {
+		pr_perror("epoll_create failed");
+		exit(1);
+	}
+	epollfd2 = epoll_create(1);
+	if (epollfd2 < 0) {
+		pr_perror("epoll_create failed");
+		exit(1);
+	}
+
+
+	test_msg("created eventfd with %lld\n", (long long)v);
+
+	memset(&ev, 0xff, sizeof(ev));
+	ev.events = EPOLLIN | EPOLLOUT;
+
+	for (i = 0; i < ARRAY_SIZE(pipes); i++) {
+		if (pipe(pipes[i].pipefd1) || pipe(pipes[i].pipefd2)) {
+			pr_err("Can't create pipe %d\n", i);
+			exit(1);
+		}
+
+		ev.data.ptr = (void *)(long)i;
+		fd = dup2(pipes[i].pipefd2[0], DUPFDNO);
+		if (fd < 0) {
+			pr_perror("Can't dup %d to %d", pipes[i].pipefd2[0], DUPFDNO);
+			exit(1);
+		}
+		test_msg("epoll %d add %d native\n", epollfd, pipes[i].pipefd1[0]);
+		if (epoll_ctl(epollfd, EPOLL_CTL_ADD, DUPFDNO, &ev)) {
+			pr_perror("Can't add pipe %d", pipes[i].pipefd1[0]);
+			exit(1);
+		}
+		if (epoll_ctl(epollfd2, EPOLL_CTL_ADD, pipes[i].pipefd2[0], &ev)) {
+			pr_perror("Can't add pipe %d", pipes[i].pipefd1[0]);
+			exit(1);
+		}
+
+		test_msg("epoll %d add %d dup'ed from %d\n", epollfd, fd, pipes[i].pipefd2[0]);
+
+		close(fd);
+		test_msg("epoll source %d closed\n", fd);
+	}
+
+	test_daemon();
+	test_waitsig();
+
+	for (i = 0; i < ARRAY_SIZE(pipes); i++) {
+		if (write(pipes[i].pipefd2[1], "x", 1) != 1) {
+			pr_perror("Unable to write into a pipe\n");
+			return 1;
+		}
+		if (epoll_wait(epollfd, &ev, 1, -1) != 1) {
+			pr_perror("Unable to wain events");
+			return 1;
+		}
+		if (ev.data.ptr != (void *)(long) i) {
+			pr_err("eve.data.ptr=0x%p (%d)\n", ev.data.ptr, i);
+			return 1;
+		}
+		if (epoll_wait(epollfd2, &ev, 1, -1) != 1) {
+			pr_perror("Unable to wain events");
+			return 1;
+		}
+		if (ev.data.ptr != (void *)(long) i) {
+			pr_err("eve.data.ptr=0x%p (%d)\n", ev.data.ptr, i);
+			return 1;
+		}
+	}
+
+	pass();
+	return 0;
+}