[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