[5/7] fanotify: Rework parse_fdinfo not to use callback

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

Details

Message ID 87c5629a-d9e2-645c-c296-056cc5065659@virtuozzo.com
State Accepted
Series "Relax fdinfo parsing code"
Headers show

Commit Message

Pavel Emelianov June 22, 2017, 5:40 p.m.
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/fsnotify.c         |  73 +++++++++++-------------------
 criu/include/fdinfo.h   |  13 ------
 criu/include/fsnotify.h |   5 ---
 criu/proc_parse.c       | 117 +++++++++++++++++++++++-------------------------
 4 files changed, 82 insertions(+), 126 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/fsnotify.c b/criu/fsnotify.c
index 7bd4411..f86fbea 100644
--- a/criu/fsnotify.c
+++ b/criu/fsnotify.c
@@ -296,12 +296,6 @@  err:
 	return -1;
 }
 
-struct watch_list {
-	struct fsnotify_params fsn_params;
-	struct list_head list;
-	int n;
-};
-
 static int check_one_wd(InotifyWdEntry *we)
 {
 	pr_info("wd: wd %#08x s_dev %#08x i_ino %#16"PRIx64" mask %#08x\n",
@@ -381,11 +375,8 @@  const struct fdtype_ops inotify_dump_ops = {
 	.pre_dump	= pre_dump_one_inotify,
 };
 
-static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
+static int check_one_mark(FanotifyMarkEntry *fme)
 {
-	struct watch_list *wd_list = (struct watch_list *) arg;
-	FanotifyMarkEntry *fme = &e->ffy.e;
-
 	if (fme->type == MARK_TYPE__INODE) {
 
 		BUG_ON(!fme->ie);
@@ -398,7 +389,7 @@  static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
 			fme->ie->f_handle->handle[0], fme->ie->f_handle->handle[1]);
 
 		if (check_open_handle(fme->s_dev, fme->ie->i_ino, fme->ie->f_handle))
-			goto out;
+			return -1;
 	}
 
 	if (fme->type == MARK_TYPE__MOUNT) {
@@ -409,7 +400,7 @@  static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
 		m = lookup_mnt_id(fme->me->mnt_id);
 		if (!m) {
 			pr_err("Can't find mnt_id 0x%x\n", fme->me->mnt_id);
-			goto out;
+			return -1;
 		}
 		if (!(root_ns_mask & CLONE_NEWNS))
 			fme->me->path = m->mountpoint + 1;
@@ -420,20 +411,12 @@  static int dump_fanotify_entry(union fdinfo_entries *e, void *arg)
 
 	}
 
-	list_add_tail(&e->ffy.node, &wd_list->list);
-	wd_list->n++;
-
 	return 0;
-out:
-	free_fanotify_mark_entry(e);
-	return -1;
 }
 
 static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
 {
-	struct watch_list wd_list = {.list = LIST_HEAD_INIT(wd_list.list), .n = 0};
 	FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
-	union fdinfo_entries *we, *tmp;
 	int ret = -1, i;
 
 	ret = fd_has_data(lfd);
@@ -447,49 +430,43 @@  static int dump_one_fanotify(int lfd, u32 id, const struct fd_parms *p)
 	fe.flags = p->flags;
 	fe.fown = (FownEntry *)&p->fown;
 
-	if (parse_fdinfo(lfd, FD_TYPES__FANOTIFY,
-			 dump_fanotify_entry, &wd_list) < 0)
+	if (parse_fdinfo(lfd, FD_TYPES__FANOTIFY, NULL, &fe) < 0)
 		goto free;
 
-	fe.mark = xmalloc(sizeof(*fe.mark) * wd_list.n);
-	if (!fe.mark)
-		goto free;
-
-	i = 0;
-	list_for_each_entry(we, &wd_list.list, ffy.node)
-		fe.mark[i++] = &we->ffy.e;
-	fe.n_mark = wd_list.n;
+	for (i = 0; i < fe.n_mark; i++)
+		if (check_one_mark(fe.mark[i]))
+			goto free;
 
 	pr_info("id %#08x flags %#08x\n", fe.id, fe.flags);
 
-	fe.faflags = wd_list.fsn_params.faflags;
-	fe.evflags = wd_list.fsn_params.evflags;
-
 	ret = pb_write_one(img_from_set(glob_imgset, CR_FD_FANOTIFY_FILE), &fe, PB_FANOTIFY_FILE);
 free:
+	for (i = 0; i < fe.n_mark; i++)
+		xfree(fe.mark[i]);
 	xfree(fe.mark);
-	list_for_each_entry_safe(we, tmp, &wd_list.list, ffy.node)
-		free_fanotify_mark_entry(we);
 	return ret;
 }
 
-static int pre_dump_fanotify_entry(union fdinfo_entries *e, void *arg)
+static int pre_dump_one_fanotify(int pid, int lfd)
 {
-	FanotifyMarkEntry *fme = &e->ffy.e;
-	int ret = 0;
+	FanotifyFileEntry fe = FANOTIFY_FILE_ENTRY__INIT;
+	int i;
 
-	if (fme->type == MARK_TYPE__INODE)
-		ret = irmap_queue_cache(fme->s_dev, fme->ie->i_ino,
-				fme->ie->f_handle);
+	if (parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, NULL, &fe))
+		return -1;
 
-	free_fanotify_mark_entry(e);
-	return ret;
-}
+	for (i = 0; i < fe.n_mark; i++) {
+		FanotifyMarkEntry *me = fe.mark[i];
 
-static int pre_dump_one_fanotify(int pid, int lfd)
-{
-	struct fsnotify_params fsn_params = { };
-	return parse_fdinfo_pid(pid, lfd, FD_TYPES__FANOTIFY, pre_dump_fanotify_entry, &fsn_params);
+		if (me->type == MARK_TYPE__INODE &&
+				irmap_queue_cache(me->s_dev, me->ie->i_ino,
+					me->ie->f_handle))
+			return -1;
+
+		xfree(me);
+	}
+	xfree(fe.mark);
+	return 0;
 }
 
 const struct fdtype_ops fanotify_dump_ops = {
diff --git a/criu/include/fdinfo.h b/criu/include/fdinfo.h
index 5977a1d..ef7c3f6 100644
--- a/criu/include/fdinfo.h
+++ b/criu/include/fdinfo.h
@@ -9,23 +9,10 @@ 
 #include "images/fsnotify.pb-c.h"
 #include "images/timerfd.pb-c.h"
 
-struct fanotify_mark_entry {
-	FanotifyMarkEntry e;
-	FhEntry f_handle;
-	struct list_head node;
-	union {
-		FanotifyInodeMarkEntry ie;
-		FanotifyMountMarkEntry me;
-	};
-};
-
 union fdinfo_entries {
-	struct fanotify_mark_entry ffy;
 	TimerfdEntry tfy;
 };
 
-extern void free_fanotify_mark_entry(union fdinfo_entries *e);
-
 struct fdinfo_common {
 	off64_t pos;
 	int flags;
diff --git a/criu/include/fsnotify.h b/criu/include/fsnotify.h
index adc0203..7bf5af4 100644
--- a/criu/include/fsnotify.h
+++ b/criu/include/fsnotify.h
@@ -8,11 +8,6 @@ 
 
 #define KERNEL_FS_EVENT_ON_CHILD 0x08000000
 
-struct fsnotify_params {
-	u32	faflags;
-	u32	evflags;
-};
-
 extern int is_inotify_link(char *link);
 extern int is_fanotify_link(char *link);
 extern const struct fdtype_ops inotify_dump_ops;
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index dfa67c2..f4de451 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -1592,27 +1592,6 @@  static char nybble(const char n)
 	return 0;
 }
 
-static int alloc_fhandle(FhEntry *fh)
-{
-	fh->n_handle = FH_ENTRY_SIZES__min_entries;
-	fh->handle = xmalloc(pb_repeated_size(fh, handle));
-
-	return fh->handle == NULL ? -1 : 0;
-}
-
-static void free_fhandle(FhEntry *fh)
-{
-	if (fh->handle)
-		xfree(fh->handle);
-}
-
-void free_fanotify_mark_entry(union fdinfo_entries *e)
-{
-	if (e->ffy.e.ie)
-		free_fhandle(e->ffy.ie.f_handle);
-	xfree(e);
-}
-
 static void parse_fhandle_encoded(char *tok, FhEntry *fh)
 {
 	char *d = (char *)fh->handle;
@@ -1846,89 +1825,107 @@  static int parse_fdinfo_pid_s(int pid, int fd, int type,
 			continue;
 		}
 		if (fdinfo_field(str, "fanotify flags")) {
-			struct fsnotify_params *p = arg;
+			FanotifyFileEntry *fe = arg;
 
 			if (type != FD_TYPES__FANOTIFY)
 				goto parse_err;
 
 			ret = sscanf(str, "fanotify flags:%x event-flags:%x",
-				     &p->faflags, &p->evflags);
+				     &fe->faflags, &fe->evflags);
 			if (ret != 2)
 				goto parse_err;
 			entry_met = true;
 			continue;
 		}
 		if (fdinfo_field(str, "fanotify ino")) {
-			union fdinfo_entries *e;
-			int hoff = 0;
+			void *buf, *ob;
+			FanotifyFileEntry *fe = arg;
+			FanotifyMarkEntry *me;
+			int hoff = 0, i;
 
 			if (type != FD_TYPES__FANOTIFY)
 				goto parse_err;
 
-			e = xmalloc(sizeof(*e));
-			if (!e)
-				goto parse_err;
+			ob = buf = xmalloc(sizeof(FanotifyMarkEntry) +
+					sizeof(FanotifyInodeMarkEntry) +
+					sizeof(FhEntry) +
+					FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
+			if (!buf)
+				goto out;
 
-			fanotify_mark_entry__init(&e->ffy.e);
-			fanotify_inode_mark_entry__init(&e->ffy.ie);
-			fh_entry__init(&e->ffy.f_handle);
-			e->ffy.e.ie = &e->ffy.ie;
-			e->ffy.ie.f_handle = &e->ffy.f_handle;
+			me = xptr_pull(&buf, FanotifyMarkEntry);
+			fanotify_mark_entry__init(me);
+			me->ie = xptr_pull(&buf, FanotifyInodeMarkEntry);
+			fanotify_inode_mark_entry__init(me->ie);
+			me->ie->f_handle = xptr_pull(&buf, FhEntry);
+			fh_entry__init(me->ie->f_handle);
+			me->ie->f_handle->n_handle = FH_ENTRY_SIZES__min_entries;
+			me->ie->f_handle->handle = xptr_pull_s(&buf,
+					FH_ENTRY_SIZES__min_entries * sizeof(uint64_t));
 
 			ret = sscanf(str,
 				     "fanotify ino:%"PRIx64" sdev:%x mflags:%x mask:%x ignored_mask:%x "
 				     "fhandle-bytes:%x fhandle-type:%x f_handle: %n",
-				     &e->ffy.ie.i_ino, &e->ffy.e.s_dev,
-				     &e->ffy.e.mflags, &e->ffy.e.mask, &e->ffy.e.ignored_mask,
-				     &e->ffy.f_handle.bytes, &e->ffy.f_handle.type,
+				     &me->ie->i_ino, &me->s_dev,
+				     &me->mflags, &me->mask, &me->ignored_mask,
+				     &me->ie->f_handle->bytes, &me->ie->f_handle->type,
 				     &hoff);
 			if (ret != 7 || hoff == 0) {
-				free_fanotify_mark_entry(e);
+				xfree(ob);
 				goto parse_err;
 			}
 
-			if (alloc_fhandle(&e->ffy.f_handle)) {
-				free_fanotify_mark_entry(e);
-				goto out;
-			}
-			parse_fhandle_encoded(str + hoff, &e->ffy.f_handle);
-
-			e->ffy.e.type = MARK_TYPE__INODE;
-			ret = cb(e, arg);
-
+			parse_fhandle_encoded(str + hoff, me->ie->f_handle);
+			me->type = MARK_TYPE__INODE;
 
-			if (ret)
+			i = fe->n_mark++;
+			if (xrealloc_safe(&fe->mark, fe->n_mark * sizeof(FanotifyMarkEntry *))) {
+				xfree(ob);
 				goto out;
+			}
 
+			fe->mark[i] = me;
 			entry_met = true;
 			continue;
 		}
 		if (fdinfo_field(str, "fanotify mnt_id")) {
-			union fdinfo_entries *e;
+			void *buf, *ob;
+			FanotifyFileEntry *fe = arg;
+			FanotifyMarkEntry *me;
+			int i;
 
 			if (type != FD_TYPES__FANOTIFY)
 				goto parse_err;
 
-			e = xmalloc(sizeof(*e));
-			if (!e)
-				goto parse_err;
 
-			fanotify_mark_entry__init(&e->ffy.e);
-			fanotify_mount_mark_entry__init(&e->ffy.me);
-			e->ffy.e.me = &e->ffy.me;
+			ob = buf = xmalloc(sizeof(FanotifyMarkEntry) +
+					sizeof(FanotifyMountMarkEntry));
+			if (!buf)
+				goto out;
+
+			me = xptr_pull(&buf, FanotifyMarkEntry);
+			fanotify_mark_entry__init(me);
+			me->me = xptr_pull(&buf, FanotifyMountMarkEntry);
+			fanotify_mount_mark_entry__init(me->me);
 
 			ret = sscanf(str,
 				     "fanotify mnt_id:%x mflags:%x mask:%x ignored_mask:%x",
-				     &e->ffy.e.me->mnt_id, &e->ffy.e.mflags,
-				     &e->ffy.e.mask, &e->ffy.e.ignored_mask);
-			if (ret != 4)
+				     &me->me->mnt_id, &me->mflags,
+				     &me->mask, &me->ignored_mask);
+			if (ret != 4) {
+				xfree(ob);
 				goto parse_err;
+			}
 
-			e->ffy.e.type = MARK_TYPE__MOUNT;
-			ret = cb(e, arg);
-			if (ret)
+			me->type = MARK_TYPE__MOUNT;
+
+			i = fe->n_mark++;
+			if (xrealloc_safe(&fe->mark, fe->n_mark * sizeof(FanotifyMarkEntry *))) {
+				xfree(ob);
 				goto out;
+			}
 
+			fe->mark[i] = me;
 			entry_met = true;
 			continue;
 		}