[CRIU] [PATCH 3/3] eventpoll: merge eventpoll tfd into eventpoll image

Andrey Vagin avagin at openvz.org
Tue Sep 2 07:49:32 PDT 2014


All marks are collected in a list and then they are written in
the eventpoll image as a repeated field.

This images merge reduces the amount of image files criu
generates and may simplify the fix of mentioned above issue

v2: save the original order of entries
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 eventpoll.c              | 76 +++++++++++++++++++++++++++++++++++-------------
 include/image-desc.h     |  2 +-
 protobuf/eventpoll.proto |  1 +
 3 files changed, 57 insertions(+), 22 deletions(-)

diff --git a/eventpoll.c b/eventpoll.c
index da40e92..12a6f2f 100644
--- a/eventpoll.c
+++ b/eventpoll.c
@@ -57,34 +57,55 @@ static void pr_info_eventpoll(char *action, EventpollFileEntry *e)
 	pr_info("%seventpoll: id %#08x flags %#04x\n", action, e->id, e->flags);
 }
 
+struct eventpoll_list {
+	struct list_head list;
+	int n;
+};
+
 static int dump_eventpoll_entry(union fdinfo_entries *e, void *arg)
 {
+	struct eventpoll_list *ep_list = (struct eventpoll_list *) arg;
 	EventpollTfdEntry *efd = &e->epl.e;
-	int ret;
 
-	efd->id = *(u32 *)arg;
 	pr_info_eventpoll_tfd("Dumping: ", efd);
-	ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_EVENTPOLL_TFD),
-			efd, PB_EVENTPOLL_TFD);
 
-	free_event_poll_entry(e);
-	return ret;
+	list_add_tail(&e->epl.node, &ep_list->list);
+	ep_list->n++;
+
+	return 0;
 }
 
 static int dump_one_eventpoll(int lfd, u32 id, const struct fd_parms *p)
 {
 	EventpollFileEntry e = EVENTPOLL_FILE_ENTRY__INIT;
+	struct eventpoll_list ep_list = {LIST_HEAD_INIT(ep_list.list), 0};
+	union fdinfo_entries *te, *tmp;
+	int i, ret = -1;
 
 	e.id = id;
 	e.flags = p->flags;
 	e.fown = (FownEntry *)&p->fown;
 
+	if (parse_fdinfo(lfd, FD_TYPES__EVENTPOLL, dump_eventpoll_entry, &ep_list))
+		goto out;
+
+	e.tfd = xmalloc(sizeof(struct EventpollTfdEntry *) * ep_list.n);
+	if (!e.tfd)
+		goto out;
+
+	i = 0;
+	list_for_each_entry(te, &ep_list.list, epl.node)
+		e.tfd[i++] = &te->epl.e;
+	e.n_tfd = ep_list.n;
+
 	pr_info_eventpoll("Dumping ", &e);
-	if (pb_write_one(fdset_fd(glob_fdset, CR_FD_EVENTPOLL_FILE),
-		     &e, PB_EVENTPOLL_FILE))
-		return -1;
+	ret = pb_write_one(fdset_fd(glob_fdset, CR_FD_EVENTPOLL_FILE),
+		     &e, PB_EVENTPOLL_FILE);
+out:
+	list_for_each_entry_safe(te, tmp, &ep_list.list, epl.node)
+		free_event_poll_entry(te);
 
-	return parse_fdinfo(lfd, FD_TYPES__EVENTPOLL, dump_eventpoll_entry, &id);
+	return ret;
 }
 
 const struct fdtype_ops eventpoll_dump_ops = {
@@ -119,30 +140,42 @@ err_close:
 	close(tmp);
 	return -1;
 }
+static int eventpoll_retore_tfd(int fd, int id, EventpollTfdEntry *tdefe)
+{
+	struct epoll_event event;
+
+	pr_info_eventpoll_tfd("Restore ", tdefe);
+
+	event.events	= tdefe->events;
+	event.data.u64	= tdefe->data;
+	if (epoll_ctl(fd, EPOLL_CTL_ADD, tdefe->tfd, &event)) {
+		pr_perror("Can't add event on %#08x", id);
+		return -1;
+	}
+
+	return 0;
+}
 
 static int eventpoll_post_open(struct file_desc *d, int fd)
 {
-	int ret;
 	struct eventpoll_tfd_file_info *td_info;
 	struct eventpoll_file_info *info;
+	int i;
 
 	info = container_of(d, struct eventpoll_file_info, d);
 
-	list_for_each_entry(td_info, &eventpoll_tfds, list) {
-		struct epoll_event event;
+	for (i = 0; i < info->efe->n_tfd; i++) {
+		if (eventpoll_retore_tfd(fd, info->efe->id, info->efe->tfd[i]))
+			return -1;
+	}
 
+	list_for_each_entry(td_info, &eventpoll_tfds, list) {
 		if (td_info->tdefe->id != info->efe->id)
 			continue;
 
-		pr_info_eventpoll_tfd("Restore ", td_info->tdefe);
-
-		event.events	= td_info->tdefe->events;
-		event.data.u64	= td_info->tdefe->data;
-		ret = epoll_ctl(fd, EPOLL_CTL_ADD, td_info->tdefe->tfd, &event);
-		if (ret) {
-			pr_perror("Can't add event on %#08x", info->efe->id);
+		if (eventpoll_retore_tfd(fd, info->efe->id, td_info->tdefe))
 			return -1;
-		}
+
 	}
 
 	return 0;
@@ -177,6 +210,7 @@ struct collect_image_info epoll_tfd_cinfo = {
 	.pb_type = PB_EVENTPOLL_TFD,
 	.priv_size = sizeof(struct eventpoll_tfd_file_info),
 	.collect = collect_one_epoll_tfd,
+	.flags		= COLLECT_OPTIONAL,
 };
 
 static int collect_one_epoll(void *o, ProtobufCMessage *msg)
diff --git a/include/image-desc.h b/include/image-desc.h
index 20afa42..9cfca29 100644
--- a/include/image-desc.h
+++ b/include/image-desc.h
@@ -65,7 +65,6 @@ enum {
 	CR_FD_REMAP_FPATH,
 	CR_FD_EVENTFD_FILE,
 	CR_FD_EVENTPOLL_FILE,
-	CR_FD_EVENTPOLL_TFD,
 	CR_FD_SIGNALFD,
 	CR_FD_INOTIFY_FILE,
 	CR_FD_FANOTIFY_FILE,
@@ -93,6 +92,7 @@ enum {
 	CR_FD_PSIGNAL,
 	CR_FD_INOTIFY_WD,
 	CR_FD_FANOTIFY_MARK,
+	CR_FD_EVENTPOLL_TFD,
 
 	CR_FD_MAX
 };
diff --git a/protobuf/eventpoll.proto b/protobuf/eventpoll.proto
index 5da242d..c406755 100644
--- a/protobuf/eventpoll.proto
+++ b/protobuf/eventpoll.proto
@@ -11,4 +11,5 @@ message eventpoll_file_entry {
 	required uint32		id	= 1;
 	required uint32		flags	= 2;
 	required fown_entry	fown	= 3;
+	repeated eventpoll_tfd_entry tfd = 4;
 }
-- 
1.9.3



More information about the CRIU mailing list