From 649baf8ebebdc5460ddd5990f591db1ef8f009cd Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Fri, 4 May 2012 16:31:00 +0400 Subject: [PATCH] files: Handle eventpoll files deferred Since event polling depends on other files to be opened we split main files list into two parst -- event poll files and all other files, thus defer the creation of eventpoll files in prepare_fds(). Signed-off-by: Cyrill Gorcunov Signed-off-by: Pavel Emelyanov --- files.c | 25 +++++++++++++++++++++---- include/crtools.h | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/files.c b/files.c index 2b0ac1cf2..043b7e4fd 100644 --- a/files.c +++ b/files.c @@ -335,7 +335,7 @@ int collect_reg_files(void) return collect_remaps(); } -static int collect_fd(int pid, struct fdinfo_entry *e, struct list_head *fds) +static int collect_fd(int pid, struct fdinfo_entry *e, struct rst_info *rst_info) { int i; struct fdinfo_list_entry *l, *le = &fdinfo_list[nr_fdinfo_list]; @@ -365,7 +365,11 @@ static int collect_fd(int pid, struct fdinfo_entry *e, struct list_head *fds) break; list_add_tail(&le->desc_list, &l->desc_list); - list_add_tail(&le->ps_list, fds); + + if (unlikely(le->fe.type == FDINFO_EVENTPOLL)) + list_add_tail(&le->ps_list, &rst_info->eventpoll); + else + list_add_tail(&le->ps_list, &rst_info->fds); return 0; } @@ -375,6 +379,7 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info) u32 type = 0; INIT_LIST_HEAD(&rst_info->fds); + INIT_LIST_HEAD(&rst_info->eventpoll); fdinfo_fd = open_image_ro(CR_FD_FDINFO, pid); if (fdinfo_fd < 0) { @@ -391,7 +396,7 @@ int prepare_fd_pid(int pid, struct rst_info *rst_info) if (ret <= 0) break; - ret = collect_fd(pid, &e, &rst_info->fds); + ret = collect_fd(pid, &e, rst_info); if (ret < 0) break; } @@ -653,13 +658,25 @@ int prepare_fds(struct pstree_item *me) pr_info("Opening fdinfo-s\n"); - for (state = 0; state < FD_STATE_MAX; state++) + for (state = 0; state < FD_STATE_MAX; state++) { list_for_each_entry(fle, &me->rst->fds, ps_list) { ret = open_fdinfo(me->pid, &fle->fe, state); if (ret) goto done; } + /* + * The eventpoll descriptors require all the other ones + * to be already restored, thus we store them in a separate + * list and restore at the very end. + */ + list_for_each_entry(fle, &me->rst->eventpoll, ps_list) { + ret = open_fdinfo(me->pid, &fle->fe, state); + if (ret) + goto done; + } + } + ret = run_unix_connections(); done: return ret; diff --git a/include/crtools.h b/include/crtools.h index 9fce868e0..52f48cf26 100644 --- a/include/crtools.h +++ b/include/crtools.h @@ -203,6 +203,7 @@ struct vma_area { struct rst_info { struct list_head fds; + struct list_head eventpoll; }; struct pstree_item {