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

Andrew Vagin avagin at parallels.com
Tue Mar 17 06:37:03 PDT 2015


On Tue, Mar 17, 2015 at 04:09:10PM +0300, Cyrill Gorcunov wrote:
> The idea is simply make sure that timeour has not been
> screwed during c/r cycle.
> 
> 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   | 160 +++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 162 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..1e95180fa1fe
> --- /dev/null
> +++ b/test/zdtm/live/static/poll.c
> @@ -0,0 +1,160 @@
> +#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 "zdtmtst.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 time_init, time1, time2;
> +	struct timespec delay;
> +	struct pollfd ufds[2];
> +	int pipes[2], ret;
> +	int delta, status;
> +	task_waiter_t t;
> +	pid_t pid;
> +
> +	test_init(argc, argv);
> +
> +	task_waiter_init(&t);
> +
> +	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(&time_init, NULL)) {
> +		err("Can't get init times");
> +		exit(1);
> +	}
> +
> +	show_timestamp("Init", time_init.tv_sec, time_init.tv_usec);
> +
> +	delta = 1;
> +	ret = poll(ufds, 2, delta * 1000);

Why do you call poll() here?

> +	show_pollfd(ufds, 2);
> +
> +	if (ret) {
> +		err("Poll-1 returned %d (events?!)", ret);
> +		exit(1);
> +	}
> +
> +	if (gettimeofday(&time1, NULL)) {
> +		err("Can't get first delta");
> +		exit(1);
> +	}
> +
> +	show_timestamp("First", time1.tv_sec, time1.tv_usec);
> +	show_timestamp("Diff1", time1.tv_sec - time_init.tv_sec,
> +		       time1.tv_usec - time_init.tv_usec);
> +
> +	/* We should be waiting more than 5 sec I think */
> +	if ((5 * delta) < (time1.tv_sec - time_init.tv_sec)) {
> +		err("We've been waiting for too long");
> +		exit(1);
> +	}
> +
> +	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("From", time1.tv_sec, time1.tv_usec);
> +
> +		task_waiter_complete(&t, 1);
> +		delta = 5;
> +		ret = poll(ufds, 2, delta * 1000);

Can we call poll() in a loop to be sure that the timeout isn't expired
during the test?

> +		show_pollfd(ufds, 2);
> +
> +		if (ret && errno != EINTR) {

When can we get EINTR here?

> +			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("To", 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();
> +
> +	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