[CRIU] [PATCH] test: inotify00 -- Rework test

Andrew Vagin avagin at parallels.com
Wed Sep 3 21:22:46 PDT 2014


On Thu, Sep 04, 2014 at 01:05:00AM +0400, Cyrill Gorcunov wrote:
> On Wed, Sep 03, 2014 at 11:32:48PM +0400, Andrew Vagin wrote:
> > On Wed, Sep 03, 2014 at 11:01:13PM +0400, Cyrill Gorcunov wrote:
> > > To show which events are coming and flush
> > > events before dump as required by new fsnotify mode.
> > > 
> 
> Update attached.

Acked-by: Andrew Vagin <avagin at parallels.com>

> From a6a184a00922fe281b209fb5130a851d3d62b51c Mon Sep 17 00:00:00 2001
> From: Cyrill Gorcunov <gorcunov at openvz.org>
> Date: Wed, 3 Sep 2014 22:59:38 +0400
> Subject: [PATCH] test: inotify00 -- Rework test, v2
> 
> To show which events are coming and flush events before dump as required by new fsnotify mode.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  test/zdtm/live/static/Makefile    |   2 +-
>  test/zdtm/live/static/inotify00.c | 193 +++++++++++++++++++++++++++++++++-----
>  2 files changed, 172 insertions(+), 23 deletions(-)
> 
> diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile
> index e96e71110e76..e07920106518 100644
> --- a/test/zdtm/live/static/Makefile
> +++ b/test/zdtm/live/static/Makefile
> @@ -77,7 +77,6 @@ TST_NOFILE	=				\
>  		proc-self			\
>  		eventfs00			\
>  		signalfd00			\
> -		inotify00			\
>  		inotify_irmap			\
>  		fanotify00			\
>  		uptime_grow			\
> @@ -166,6 +165,7 @@ TST_DIR		=				\
>  		overmount_sock			\
>  		tempfs				\
>  		bind-mount			\
> +		inotify00			\
>  		cgroup00			\
>  		rmdir_open			\
>  		cgroup01			\
> diff --git a/test/zdtm/live/static/inotify00.c b/test/zdtm/live/static/inotify00.c
> index 587408cda5bd..2e25a663b718 100644
> --- a/test/zdtm/live/static/inotify00.c
> +++ b/test/zdtm/live/static/inotify00.c
> @@ -12,63 +12,212 @@
>  #include <sys/inotify.h>
>  #include <unistd.h>
>  #include <stdlib.h>
> +#include <dirent.h>
>  
>  #include "zdtmtst.h"
>  
>  const char *test_doc	= "Check for inotify delivery";
>  const char *test_author	= "Cyrill Gorcunov <gorcunov at openvz.org>";
>  
> -const char path[] = "inotify-removed";
> +char *dirname;
> +TEST_OPTION(dirname, string, "directory name", 1);
> +
> +#define TEST_FILE	"inotify-removed"
> +#define TEST_LINK	"inotify-hardlink"
>  
>  #define BUFF_SIZE ((sizeof(struct inotify_event) + PATH_MAX))
>  
> +static void decode_event_mask(char *buf, size_t size, unsigned int mask)
> +{
> +	static const char *names[32] = {
> +		[ 0]	= "IN_ACCESS",
> +		[ 1]	= "IN_MODIFY",
> +		[ 2]	= "IN_ATTRIB",
> +		[ 3]	= "IN_CLOSE_WRITE",
> +		[ 4]	= "IN_CLOSE_NOWRITE",
> +		[ 5]	= "IN_OPEN",
> +		[ 6]	= "IN_MOVED_FROM",
> +		[ 7]	= "IN_MOVED_TO",
> +		[ 8]	= "IN_CREATE",
> +		[ 9]	= "IN_DELETE",
> +		[10]	= "IN_DELETE_SELF",
> +		[11]	= "IN_MOVE_SELF",
> +
> +		[13]	= "IN_UNMOUNT",
> +		[14]	= "IN_Q_OVERFLOW",
> +		[15]	= "IN_IGNORED",
> +
> +		[24]	= "IN_ONLYDIR",
> +		[25]	= "IN_DONT_FOLLOW",
> +		[26]	= "IN_EXCL_UNLINK",
> +
> +		[29]	= "IN_MASK_ADD",
> +		[30]	= "IN_ISDIR",
> +		[31]	= "IN_ONESHOT",
> +	};
> +
> +	size_t i, j;
> +
> +	memset(buf, 0, size);
> +	for (i = 0, j = 0; i < 32 && j < size; i++) {
> +		if (!(mask & (1u << i)))
> +			continue;
> +		if (j)
> +			j += snprintf(&buf[j], size - j, " | %s", names[i]);
> +		else
> +			j += snprintf(&buf[j], size - j, "%s", names[i]);
> +	}
> +}
> +
> +static int inotify_read_events(char *prefix, int inotify_fd, unsigned int *expected)
> +{
> +	struct inotify_event *event;
> +	char buf[BUFF_SIZE * 8];
> +	int ret, off, n = 0;
> +
> +	while (1) {
> +		ret = read(inotify_fd, buf, sizeof(buf));
> +		if (ret < 0) {
> +			if (errno != EAGAIN) {
> +				err("Can't read inotify queue");
> +				return -1;
> +			} else {
> +				ret = 0;
> +				goto out;
> +			}
> +		} else if (ret == 0)
> +			break;
> +
> +		for (off = 0; off < ret; n++, off += sizeof(*event) + event->len) {
> +			char emask[128];
> +
> +			event = (void *)(buf + off);
> +			decode_event_mask(emask, sizeof(emask), event->mask);
> +			test_msg("\t%-16s: event %#10x -> %s\n",
> +				 prefix, event->mask, emask);
> +			if (expected)
> +				*expected &= ~event->mask;
> +		}
> +	}
> +
> +out:
> +	test_msg("\t%-16s: read %2d events\n", prefix, n);
> +	return ret;
> +}
> +
>  int main (int argc, char *argv[])
>  {
> -	char buf[BUFF_SIZE];
> -	int fd, wd, deleted, wd_deleted;
> +	unsigned int mask = IN_DELETE | IN_CLOSE_WRITE | IN_DELETE_SELF;
> +	char test_link_path[PATH_MAX], test_file_path[PATH_MAX];
> +	int fd, link_fd, real_fd;
> +	unsigned int emask;
>  
>  	test_init(argc, argv);
>  
>  	fd = inotify_init1(IN_NONBLOCK);
>  	if (fd < 0) {
> -		fail("inotify_init failed");
> +		err("inotify_init failed");
>  		exit(1);
>  	}
>  
> -	wd  = 0;
> -	wd |= inotify_add_watch(fd, "/", IN_ALL_EVENTS);
> -	if (wd < 0) {
> -		fail("inotify_add_watch failed");
> +	if (mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
> +		err("Can't create directory %s", dirname);
>  		exit(1);
>  	}
>  
> -	deleted = open(path, O_CREAT | O_TRUNC);
> -	if (deleted < 0) {
> -		fail("inotify_init failed");
> +	snprintf(test_link_path, sizeof(test_link_path), "%s/%s", dirname, TEST_LINK);
> +	snprintf(test_file_path, sizeof(test_file_path), "%s/%s", dirname, TEST_FILE);
> +
> +	if (chdir(dirname)) {
> +		err("Can't step into %s", dirname);
>  		exit(1);
>  	}
>  
> -	wd_deleted = inotify_add_watch(fd, path, IN_ALL_EVENTS);
> -	if (wd_deleted < 0) {
> -		fail("inotify_add_watch failed");
> +	if (open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, 0644) < 0) {
> +		err("inotify_init failed");
>  		exit(1);
>  	}
>  
> -	if (unlink(path)) {
> -		fail("can't unlink %s\n", path);
> +	if (link(TEST_FILE, TEST_LINK)) {
> +		err("Can't link %s -> %s", TEST_FILE, TEST_LINK);
> +		exit(1);
> +	}
> +
> +	if (chdir("..")) {
> +		err("Can't step into %s", "..");
> +		exit(1);
> +	}
> +
> +	if (inotify_add_watch(fd, dirname, mask) < 0) {
> +		err("inotify_add_watch failed");
> +		exit(1);
> +	}
> +
> +	if (inotify_add_watch(fd, test_link_path, mask) < 0) {
> +		err("inotify_add_watch failed");
> +		exit(1);
> +	}
> +
> +	if (inotify_add_watch(fd, test_file_path, mask) < 0) {
> +		err("inotify_add_watch failed");
> +		exit(1);
> +	}
> +
> +	link_fd = open(test_link_path, O_RDWR);
> +	if (link_fd < 0) {
> +		err("Can't open link");
> +		exit(1);
> +	}
> +
> +	real_fd = open(test_file_path, O_RDWR);
> +	if (real_fd < 0) {
> +		err("Can't open real");
> +		exit(1);
> +	}
> +
> +	/*
> +	 * At this moment we have a file inside testing
> +	 * directory and a hardlink to it. The file and
> +	 * hardlink are opened.
> +	 */
> +
> +	if (unlink(test_link_path)) {
> +		err("can't unlink %s\n", test_link_path);
> +		exit(1);
> +	}
> +
> +	if (unlink(test_file_path)) {
> +		err("can't unlink %s\n", test_file_path);
> +		exit(1);
> +	}
> +
> +	close(link_fd);
> +
> +	emask = IN_CLOSE_WRITE | IN_DELETE_SELF;
> +	inotify_read_events("unlink 02", fd, &emask);
> +	if (emask) {
> +		char emask_bits[128];
> +		decode_event_mask(emask_bits, sizeof(emask_bits), emask);
> +		err("Unhandled events in emask %#x -> %s",
> +		    emask, emask_bits);
>  		exit(1);
>  	}
>  
>  	test_daemon();
>  	test_waitsig();
>  
> -	wd = open("/", O_RDONLY);
> -	if (read(fd, buf, sizeof(buf)) > 0) {
> +	close(real_fd);
> +
> +	emask = IN_DELETE | IN_CLOSE_WRITE;
> +	inotify_read_events("after", fd, &emask);
> +	if (emask) {
> +		char emask_bits[128];
> +		decode_event_mask(emask_bits, sizeof(emask_bits), emask);
> +		fail("Unhandled events in emask %#x -> %s",
> +		    emask, emask_bits);
> +		return 1;
> +	} else
>  		pass();
> -	} else {
> -		fail("No events in queue");
> -		exit(1);
> -	}
>  
>  	return 0;
>  }
> -- 
> 1.9.3
> 



More information about the CRIU mailing list