[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