[CRIU] [PATCH 6/6] eventpoll: merge eventpoll tfd into eventpoll image
Andrey Vagin
avagin at openvz.org
Mon Aug 25 12:19:59 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
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-check.c | 2 +-
eventpoll.c | 77 +++++++++++++++++++++++++++++++++++-------------
include/image-desc.h | 2 +-
include/proc_parse.h | 2 +-
proc_parse.c | 4 +--
protobuf/eventpoll.proto | 1 +
6 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/cr-check.c b/cr-check.c
index 7647cac..731f624 100644
--- a/cr-check.c
+++ b/cr-check.c
@@ -300,7 +300,7 @@ static int check_fdinfo_signalfd(void)
static int check_one_epoll(union fdinfo_entries *e, void *arg)
{
*(int *)arg = e->epl.e.tfd;
- free_event_poll_entry(e);
+ free_eventpoll_entry(e);
return 0;
}
diff --git a/eventpoll.c b/eventpoll.c
index da40e92..8c80234 100644
--- a/eventpoll.c
+++ b/eventpoll.c
@@ -57,34 +57,56 @@ 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(&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_eventpoll_entry(te);
- return parse_fdinfo(lfd, FD_TYPES__EVENTPOLL, dump_eventpoll_entry, &id);
+ return ret;
}
const struct fdtype_ops eventpoll_dump_ops = {
@@ -119,30 +141,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 +211,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/include/proc_parse.h b/include/proc_parse.h
index 4607492..df5cdd9 100644
--- a/include/proc_parse.h
+++ b/include/proc_parse.h
@@ -198,7 +198,7 @@ union fdinfo_entries {
extern void free_inotify_wd_entry(union fdinfo_entries *e);
extern void free_fanotify_mark_entry(union fdinfo_entries *e);
-extern void free_event_poll_entry(union fdinfo_entries *e);
+extern void free_eventpoll_entry(union fdinfo_entries *e);
struct fdinfo_common {
off64_t pos;
diff --git a/proc_parse.c b/proc_parse.c
index 42c95cb..b1376aa 100644
--- a/proc_parse.c
+++ b/proc_parse.c
@@ -1032,7 +1032,7 @@ void free_fanotify_mark_entry(union fdinfo_entries *e) {
xfree(e);
}
-void free_event_poll_entry(union fdinfo_entries *e) {
+void free_eventpoll_entry(union fdinfo_entries *e) {
xfree(e);
}
@@ -1194,7 +1194,7 @@ static int parse_fdinfo_pid_s(char *pid, int fd, int type,
ret = sscanf(str, "tfd: %d events: %x data: %"PRIx64,
&e->epl.e.tfd, &e->epl.e.events, &e->epl.e.data);
if (ret != 3) {
- free_event_poll_entry(e);
+ free_eventpoll_entry(e);
goto parse_err;
}
ret = cb(e, arg);
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