[CRIU] [PATCH v2] zdtm: test -- Add trivial poll() timeout test

Cyrill Gorcunov gorcunov at gmail.com
Wed Mar 18 00:32:55 PDT 2015


Andrew, take a look please on the patch attached
-------------- next part --------------
>From 7742de3b34912fb7db309d44a87c6faff6be3aba Mon Sep 17 00:00:00 2001
From: Cyrill Gorcunov <gorcunov at openvz.org>
Date: Fri, 13 Mar 2015 19:43:07 +0300
Subject: [PATCH v2] zdtm: test -- Add trivial poll() timeout test

The idea is simply make sure that timeour has not been
screwed during c/r cycle.

v2:

 - Drop unneeded early poll() call.
 - Make poll loop in cycle until caller passes c/r cycle.
 - We should not be receiving EINTR

Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 test/zdtm.sh                   |   1 +
 test/zdtm/live/static/Makefile |   1 +
 test/zdtm/live/static/poll.c   | 150 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 test/zdtm/live/static/poll.c

diff --git a/test/zdtm.sh b/test/zdtm.sh
index 878bfaefcef0..e879bfdd65c9 100755
--- a/test/zdtm.sh
+++ b/test/zdtm.sh
@@ -151,6 +151,7 @@ generate_test_list()
 		static/dumpable01
 		static/dumpable02
 		static/deleted_dev
+		static/poll
 	"
 
 	#
diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
index 418e138b3f14..824da1b49088 100644
--- a/test/zdtm/live/static/Makefile
+++ b/test/zdtm/live/static/Makefile
@@ -92,6 +92,7 @@ TST_NOFILE	=				\
 		tty00				\
 		tty02				\
 		tty03				\
+		poll				\
 		mountpoints			\
 		netns				\
 		session01			\
diff --git a/test/zdtm/live/static/poll.c b/test/zdtm/live/static/poll.c
new file mode 100644
index 000000000000..67f5f6ec5f2e
--- /dev/null
+++ b/test/zdtm/live/static/poll.c
@@ -0,0 +1,150 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <utime.h>
+#include <time.h>
+
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+
+#include "zdtmtst.h"
+#include "lock.h"
+
+const char *test_doc	= "Check poll() timeouts";
+const char *test_author	= "Cyrill Gorcunov <gorcunov at parallels.com>";
+
+static void show_timestamp(char *prefix, unsigned long tv_sec, unsigned long tv_usec)
+{
+	test_msg("%8s: sec %20lu nsec %20lu\n", prefix, tv_sec, tv_usec);
+}
+
+static void show_pollfd(struct pollfd *fds, size_t nfds)
+{
+	size_t i;
+
+	for (i = 0; i < nfds; i++) {
+		test_msg("%2zu) fd: %2d events %2x revents %2x\n",
+			 i, fds[i].fd, fds[i].events, fds[i].revents);
+	}
+}
+
+int main(int argc, char *argv[])
+{
+	struct timeval time1, time2;
+	struct timespec delay;
+	struct pollfd ufds[2];
+	int pipes[2], ret;
+	int delta, status;
+	task_waiter_t t;
+	futex_t *f;
+	pid_t pid;
+
+	test_init(argc, argv);
+
+	f = mmap(NULL, sizeof(*f), PROT_READ | PROT_WRITE,
+		     MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+	if ((void *)f == MAP_FAILED) {
+		err("Can't alloc futex");
+		exit(1);
+	}
+
+	task_waiter_init(&t);
+	futex_init(f);
+	futex_set(f, 1);
+
+	if (pipe(pipes)) {
+		err("Can't create pipes");
+		exit(1);
+	}
+
+	memset(ufds, 0, sizeof(ufds));
+	ufds[0].fd = pipes[0];
+	ufds[0].events = POLLIN;
+
+	ufds[1].fd = pipes[1];
+	ufds[1].events = POLLIN;
+
+	show_pollfd(ufds, 2);
+
+	if (gettimeofday(&time1, NULL)) {
+		err("Can't get first delta");
+		exit(1);
+	}
+	show_timestamp("Init", time1.tv_sec, time1.tv_usec);
+
+	pid = test_fork();
+	if (pid < 0) {
+		err("Fork failed");
+		exit(1);
+	} else if (pid == 0) {
+		if (gettimeofday(&time1, NULL)) {
+			err("Can't get from times");
+			exit(1);
+		}
+
+		show_timestamp("Start", time1.tv_sec, time1.tv_usec);
+
+		task_waiter_complete(&t, 1);
+		delta = 5;
+		while (futex_get(f) != 1) {
+			ret = poll(ufds, 2, delta * 1000);
+			show_pollfd(ufds, 2);
+			if (ret) {
+				err("Poll-2 returned %d (events?!)", ret);
+				exit(1);
+			}
+		}
+
+		task_waiter_wait4(&t, 2);
+
+		if (gettimeofday(&time2, NULL)) {
+			err("Can't get from times");
+			exit(1);
+		}
+
+		show_timestamp("Stop", time2.tv_sec, time2.tv_usec);
+		show_timestamp("Diff", time2.tv_sec - time1.tv_sec,
+			       time2.tv_usec - time1.tv_usec);
+		if ((time2.tv_sec - time1.tv_sec) > delta) {
+			fail("Delta is too big %lu",
+			     (unsigned long)(time2.tv_sec - time1.tv_sec));
+			exit(1);
+		}
+		exit(0);
+	}
+
+	task_waiter_wait4(&t, 1);
+
+	/* Wait to make sure we're in poll internals */
+	delay.tv_sec = 1;
+	delay.tv_nsec = 0;
+	nanosleep(&delay, NULL);
+
+	test_daemon();
+	test_waitsig();
+
+	futex_set(f, 1);
+	task_waiter_complete(&t, 2);
+
+	/* Return immediately if child run or stopped(by SIGSTOP) */
+	if (waitpid(pid, &status, 0) == -1) {
+		err("Unable to wait child");
+		exit(1);
+	}
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+		fail("Child exited with error");
+		exit(1);
+	}
+
+	pass();
+	return 0;
+}
-- 
1.9.3



More information about the CRIU mailing list