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

Andrew Vagin avagin at parallels.com
Wed Sep 3 12:32:48 PDT 2014


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.
> 
>  | Execute zdtm/live/static/inotify00
>  | ./inotify00 --pidfile=inotify00.pid --outfile=inotify00.out
>  | Dump 8212
>  | Restore
>  | Check results 8212
>  | 23:00:09.842:  8212: 	unlink 01       : event       0x20 -> IN_OPEN
>  | 23:00:09.842:  8212: 	unlink 01       : event       0x20 -> IN_OPEN
>  | 23:00:09.842:  8212: 	unlink 01       : event       0x20 -> IN_OPEN
>  | 23:00:09.842:  8212: 	unlink 01       : event       0x20 -> IN_OPEN
>  | 23:00:09.842:  8212: 	unlink 01       : event        0x4 -> IN_ATTRIB
>  | 23:00:09.842:  8212: 	unlink 01       : event      0x200 -> IN_DELETE
>  | 23:00:09.842:  8212: 	unlink 01       : read  6 events
>  | 23:00:09.842:  8212: 	unlink 02       : event        0x4 -> IN_ATTRIB
>  | 23:00:09.842:  8212: 	unlink 02       : event      0x200 -> IN_DELETE
>  | 23:00:09.842:  8212: 	unlink 02       : event        0x8 -> IN_CLOSE_WRITE
>  | 23:00:09.842:  8212: 	unlink 02       : event        0x8 -> IN_CLOSE_WRITE
>  | 23:00:09.842:  8212: 	unlink 02       : event      0x400 -> IN_DELETE_SELF
>  | 23:00:09.842:  8212: 	unlink 02       : event     0x8000 -> IN_IGNORED
>  | 23:00:09.842:  8212: 	unlink 02       : read  6 events
>  | 23:00:09.924:  8212: 	after           : event 0x40000010 -> IN_CLOSE_NOWRITE | IN_ISDIR
>  | 23:00:09.924:  8212: 	after           : event      0x100 -> IN_CREATE
>  | 23:00:09.925:  8212: 	after           : event       0x20 -> IN_OPEN
>  | 23:00:09.925:  8212: 	after           : event      0x200 -> IN_DELETE
>  | 23:00:09.925:  8212: 	after           : event      0x100 -> IN_CREATE
>  | 23:00:09.925:  8212: 	after           : event       0x20 -> IN_OPEN
>  | 23:00:09.925:  8212: 	after           : event      0x200 -> IN_DELETE
>  | 23:00:09.925:  8212: 	after           : event      0x200 -> IN_DELETE
>  | 23:00:09.925:  8212: 	after           : event        0x8 -> IN_CLOSE_WRITE
>  | 23:00:09.925:  8212: 	after           : event 0x40000020 -> IN_OPEN | IN_ISDIR
>  | 23:00:09.925:  8212: 	after           : event 0x40000010 -> IN_CLOSE_NOWRITE | IN_ISDIR
>  | 23:00:09.925:  8212: 	after           : read 11 events
>  | 23:00:09.925:  8212: PASS
>  | Test: zdtm/live/static/inotify00, Result: PASS
>  | ZDTM tests PASS.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
> ---
>  test/zdtm/live/static/inotify00.c | 254 ++++++++++++++++++++++++++++++++++----
>  1 file changed, 232 insertions(+), 22 deletions(-)
> 
> diff --git a/test/zdtm/live/static/inotify00.c b/test/zdtm/live/static/inotify00.c
> index 587408cda5bd..9b6e9beb4301 100644
> --- a/test/zdtm/live/static/inotify00.c
> +++ b/test/zdtm/live/static/inotify00.c
> @@ -12,63 +12,273 @@
>  #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";
> +#define TEST_DIR	"inotify-test"

Could you use the --dirname option? Look at static/cwd00.
 
> +#define TEST_FILE	"inotify-removed"
> +#define TEST_LINK	"inotify-hardlink"
> +#define TEST_FILE_PATH	TEST_DIR "/" TEST_FILE
> +#define TEST_LINK_PATH	TEST_DIR "/" TEST_LINK
>  
>  #define BUFF_SIZE ((sizeof(struct inotify_event) + PATH_MAX))
>  
> +static int rmdir_force(const char *directory)

I don't like this function. Can we just unlink all expected files in the
test directory?

> +{
> +	DIR *dir = opendir(directory);
> +	char path[PATH_MAX];
> +	struct dirent *d;
> +
> +	if (!dir) {
> +		if (errno == ENOENT)
> +			return 0;
> +		err("Can't open %s", directory);
> +		return -1;
> +	}
> +
> +	while ((d = readdir(dir))) {
> +		struct stat st;
> +
> +		if(!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
> +			continue;
> +
> +		snprintf(path, sizeof(path), "%s/%s", directory, d->d_name);
> +		if (stat(path, &st)) {
> +			if (unlink(path)) {
> +				err("Can't stat/unlink %s", path);
> +				goto err;
> +			}
> +			continue;
> +		} else {
> +			if (S_ISDIR(st.st_mode)) {
> +				if (rmdir_force(path)) {
> +					err("Can't remove subdir %s", path);
> +					goto err;
> +				}
> +			}
> +		}
> +
> +		if (unlink(path)) {
> +			err("Can't unlink %s", path);
> +			goto err;
> +		}
> +	}
> +
> +	closedir(dir);
> +	if (rmdir(directory)) {
> +		err("Can't unlink %s", directory);
> +		return -1;
> +	}
> +	return 0;
> +err:
> +	closedir(dir);
> +	return -1;
> +}
> +
> +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[sizeof(*event) * 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;
> +	int fd, link_fd, real_fd;
> +	unsigned int emask;
>  
>  	test_init(argc, argv);
>  
> +	if (rmdir_force(TEST_DIR))
> +		exit(1);
> +
> +	if (mkdir(TEST_DIR, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
> +		err("Can't create directory %s", TEST_DIR);
> +		exit(1);
> +	}
> +
>  	fd = inotify_init1(IN_NONBLOCK);
>  	if (fd < 0) {
> -		fail("inotify_init failed");
> +		err("inotify_init failed");
> +		exit(1);
> +	}
> +
> +	if (open(TEST_FILE_PATH, O_CREAT | O_TRUNC) < 0) {

man 2 open:

mode specifies the permissions to use in case a new file is created.
This argument must be supplied when O_CREAT

And I think you need to set O_WRONLY or O_RDWR



More information about the CRIU mailing list