[4/7] inotify: Rework parse_fdinfo not to use callback

Submitted by Pavel Emelianov on June 22, 2017, 5:39 p.m.

Details

Message ID 8f3d204c-4fb4-bebf-417c-ce67725fe8a3@virtuozzo.com
State Accepted
Series "Relax fdinfo parsing code"
Headers show

Commit Message

Pavel Emelianov June 22, 2017, 5:39 p.m.
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/cr-check.c       | 18 ++++++-----------
 criu/fsnotify.c       | 56 ++++++++++++++++++++-------------------------------
 criu/include/fdinfo.h |  8 --------
 criu/proc_parse.c     | 41 +++++++++++++++++--------------------
 4 files changed, 47 insertions(+), 76 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-check.c b/criu/cr-check.c
index 8c4a50c..d5463c3 100644
--- a/criu/cr-check.c
+++ b/criu/cr-check.c
@@ -393,16 +393,10 @@  pipe_err:
 	return ret;
 }
 
-static int check_one_inotify(union fdinfo_entries *e, void *arg)
-{
-	*(int *)arg = e->ify.e.wd;
-	free_inotify_wd_entry(e);
-	return 0;
-}
-
 static int check_fdinfo_inotify(void)
 {
-	int ifd, wd, proc_wd = -1, ret;
+	int ifd, wd, ret;
+	InotifyFileEntry ify = INOTIFY_FILE_ENTRY__INIT;
 
 	ifd = inotify_init1(0);
 	if (ifd < 0) {
@@ -417,7 +411,7 @@  static int check_fdinfo_inotify(void)
 		return -1;
 	}
 
-	ret = parse_fdinfo(ifd, FD_TYPES__INOTIFY, check_one_inotify, &proc_wd);
+	ret = parse_fdinfo(ifd, FD_TYPES__INOTIFY, NULL, &ify);
 	close(ifd);
 
 	if (ret < 0) {
@@ -425,12 +419,12 @@  static int check_fdinfo_inotify(void)
 		return -1;
 	}
 
-	if (wd != proc_wd) {
-		pr_err("WD mismatch (or not met) %d want %d\n", proc_wd, wd);
+	if (ify.n_wd != 1 || ify.wd[0]->wd != wd) {
+		pr_err("WD mismatch (or not met)\n");
 		return -1;
 	}
 
-	pr_info("Inotify fdinfo works OK (%d vs %d)\n", wd, proc_wd);
+	pr_info("Inotify fdinfo works OK\n");
 	return 0;
 }
 
diff --git a/criu/fsnotify.c b/criu/fsnotify.c
index 3c71bf3..7bd4411 100644
--- a/criu/fsnotify.c
+++ b/criu/fsnotify.c
@@ -302,12 +302,8 @@  struct watch_list {
 	int n;
 };
 
-static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
+static int check_one_wd(InotifyWdEntry *we)
 {
-	struct watch_list *wd_list = (struct watch_list *) arg;
-	struct inotify_wd_entry *wd_entry = (struct inotify_wd_entry *) e;
-	InotifyWdEntry *we = &wd_entry->e;
-
 	pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n",
 			we->wd, we->s_dev, we->i_ino, we->mask);
 	pr_info("\t[fhandle] bytes %#08x type %#08x __handle %#016"PRIx64":%#016"PRIx64"\n",
@@ -318,22 +314,15 @@  static int dump_inotify_entry(union fdinfo_entries *e, void *arg)
 		pr_warn_once("\t\tDetected FS_EVENT_ON_CHILD bit "
 			     "in mask (will be ignored on restore)\n");
 
-	if (check_open_handle(we->s_dev, we->i_ino, we->f_handle)) {
-		free_inotify_wd_entry(e);
+	if (check_open_handle(we->s_dev, we->i_ino, we->f_handle))
 		return -1;
-	}
-
-	list_add_tail(&wd_entry->node, &wd_list->list);
-	wd_list->n++;
 
 	return 0;
 }
 
 static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
 {
-	struct watch_list wd_list = {.list = LIST_HEAD_INIT(wd_list.list), .n = 0};
 	InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT;
-	union fdinfo_entries *we, *tmp;
 	int exit_code = -1, i, ret;
 
 	ret = fd_has_data(lfd);
@@ -346,17 +335,12 @@  static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
 	ie.flags = p->flags;
 	ie.fown = (FownEntry *)&p->fown;
 
-	if (parse_fdinfo(lfd, FD_TYPES__INOTIFY, dump_inotify_entry, &wd_list))
-		goto free;
-
-	ie.wd = xmalloc(sizeof(*ie.wd) * wd_list.n);
-	if (!ie.wd)
+	if (parse_fdinfo(lfd, FD_TYPES__INOTIFY, NULL, &ie))
 		goto free;
 
-	i = 0;
-	list_for_each_entry(we, &wd_list.list, ify.node)
-		ie.wd[i++] = &we->ify.e;
-	ie.n_wd = wd_list.n;
+	for (i = 0; i < ie.n_wd; i++)
+		if (check_one_wd(ie.wd[i]))
+			goto free;
 
 	pr_info("id %#08x flags %#08x\n", ie.id, ie.flags);
 	if (pb_write_one(img_from_set(glob_imgset, CR_FD_INOTIFY_FILE), &ie, PB_INOTIFY_FILE))
@@ -364,27 +348,31 @@  static int dump_one_inotify(int lfd, u32 id, const struct fd_parms *p)
 
 	exit_code = 0;
 free:
+	for (i = 0; i < ie.n_wd; i++)
+		xfree(ie.wd[i]);
 	xfree(ie.wd);
-	list_for_each_entry_safe(we, tmp, &wd_list.list, ify.node)
-		free_inotify_wd_entry(we);
 
 	return exit_code;
 }
 
-static int pre_dump_inotify_entry(union fdinfo_entries *e, void *arg)
+static int pre_dump_one_inotify(int pid, int lfd)
 {
-	InotifyWdEntry *we = &e->ify.e;
-	int ret;
+	InotifyFileEntry ie = INOTIFY_FILE_ENTRY__INIT;
+	int i;
 
-	ret = irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle);
-	free_inotify_wd_entry(e);
+	if (parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, NULL, &ie))
+		return -1;
 
-	return ret;
-}
+	for (i = 0; i < ie.n_wd; i++) {
+		InotifyWdEntry *we = ie.wd[i];
 
-static int pre_dump_one_inotify(int pid, int lfd)
-{
-	return parse_fdinfo_pid(pid, lfd, FD_TYPES__INOTIFY, pre_dump_inotify_entry, NULL);
+		if (irmap_queue_cache(we->s_dev, we->i_ino, we->f_handle))
+			return -1;
+
+		xfree(we);
+	}
+
+	return 0;
 }
 
 const struct fdtype_ops inotify_dump_ops = {
diff --git a/criu/include/fdinfo.h b/criu/include/fdinfo.h
index 45f5746..5977a1d 100644
--- a/criu/include/fdinfo.h
+++ b/criu/include/fdinfo.h
@@ -9,12 +9,6 @@ 
 #include "images/fsnotify.pb-c.h"
 #include "images/timerfd.pb-c.h"
 
-struct inotify_wd_entry {
-	InotifyWdEntry e;
-	FhEntry f_handle;
-	struct list_head node;
-};
-
 struct fanotify_mark_entry {
 	FanotifyMarkEntry e;
 	FhEntry f_handle;
@@ -26,12 +20,10 @@  struct fanotify_mark_entry {
 };
 
 union fdinfo_entries {
-	struct inotify_wd_entry ify;
 	struct fanotify_mark_entry ffy;
 	TimerfdEntry tfy;
 };
 
-extern void free_inotify_wd_entry(union fdinfo_entries *e);
 extern void free_fanotify_mark_entry(union fdinfo_entries *e);
 
 struct fdinfo_common {
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 813614d..dfa67c2 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1606,12 +1606,6 @@  static void free_fhandle(FhEntry *fh)
 		xfree(fh->handle);
 }
 
-void free_inotify_wd_entry(union fdinfo_entries *e)
-{
-	free_fhandle(e->ify.e.f_handle);
-	xfree(e);
-}
-
 void free_fanotify_mark_entry(union fdinfo_entries *e)
 {
 	if (e->ffy.e.ie)
@@ -1939,21 +1933,27 @@  static int parse_fdinfo_pid_s(int pid, int fd, int type,
 			continue;
 		}
 		if (fdinfo_field(str, "inotify wd")) {
+			void *buf, *ob;
+			InotifyFileEntry *ie = arg;
 			InotifyWdEntry *ify;
-			union fdinfo_entries *e;
-			int hoff;
+			int hoff, i;
 
 			if (type != FD_TYPES__INOTIFY)
 				goto parse_err;
 
-			e = xmalloc(sizeof(*e));
-			if (!e)
-				goto parse_err;
-			ify = &e->ify.e;
+			ob = buf = xmalloc(sizeof(InotifyWdEntry) +
+					sizeof(FhEntry) +
+					FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
+			if (!buf)
+				goto out;
 
+			ify = xptr_pull(&buf, InotifyWdEntry);
 			inotify_wd_entry__init(ify);
-			ify->f_handle = &e->ify.f_handle;
+			ify->f_handle = xptr_pull(&buf, FhEntry);
 			fh_entry__init(ify->f_handle);
+			ify->f_handle->n_handle = FH_ENTRY_SIZES__min_entries;
+			ify->f_handle->handle = xptr_pull_s(&buf,
+					FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
 
 			ret = sscanf(str,
 					"inotify wd:%x ino:%"PRIx64" sdev:%x "
@@ -1965,22 +1965,19 @@  static int parse_fdinfo_pid_s(int pid, int fd, int type,
 					&ify->f_handle->bytes, &ify->f_handle->type,
 					&hoff);
 			if (ret != 7) {
-				free_inotify_wd_entry(e);
+				xfree(ob);
 				goto parse_err;
 			}
 
-			if (alloc_fhandle(ify->f_handle)) {
-				free_inotify_wd_entry(e);
-				goto out;
-			}
-
 			parse_fhandle_encoded(str + hoff, ify->f_handle);
 
-			ret = cb(e, arg);
-
-			if (ret)
+			i = ie->n_wd++;
+			if (xrealloc_safe(&ie->wd, ie->n_wd * sizeof(InotifyWdEntry *))) {
+				xfree(ob);
 				goto out;
+			}
 
+			ie->wd[i] = ify;
 			entry_met = true;
 			continue;
 		}