From patchwork Fri Oct 28 17:41:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [01/10] files: split collect_fd on allocate_fd and handle_fd From: Andrei Vagin X-Patchwork-Id: 2293 Message-Id: <1477676516-28669-2-git-send-email-avagin@openvz.org> To: xemul@virtuozzo.com Cc: criu@openvz.org, Andrew Vagin Date: Fri, 28 Oct 2016 20:41:47 +0300 From: Andrew Vagin We are going to open root directories for each namespace in the root task, so we need to collect all file descriptors to be able to find unused file descriptors. Signed-off-by: Andrei Vagin --- criu/cr-restore.c | 18 +++++++++++++++++ criu/files.c | 56 +++++++++++++++++++++++++++++++++++++++++++--------- criu/include/files.h | 1 + 3 files changed, 66 insertions(+), 9 deletions(-) diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 252cc91..f9eadf0 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -1322,6 +1322,21 @@ static int create_children_and_session(void) return 0; } +static int collect_fd_shared() +{ + struct pstree_item *pi; + + for_each_pstree_item(pi) { + if (pi->pid.state == TASK_HELPER) + continue; + + if (collect_fd_pid(pi)) + return -1; + } + + return 0; +} + static int restore_task_with_children(void *_arg) { struct cr_clone_arg *ca = _arg; @@ -1409,6 +1424,9 @@ static int restore_task_with_children(void *_arg) pr_info("Calling restore_sid() for init\n"); restore_sid(); + if (collect_fd_shared()) + goto err; + /* * We need non /proc proc mount for restoring pid and mount * namespaces and do not care for the rest of the cases. diff --git a/criu/files.c b/criu/files.c index 21af891..b945577 100644 --- a/criu/files.c +++ b/criu/files.c @@ -682,21 +682,30 @@ int rst_file_params(int fd, FownEntry *fown, int flags) return 0; } -static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) +static struct fdinfo_list_entry *allocate_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) { - struct fdinfo_list_entry *le, *new_le; - struct file_desc *fdesc; + struct fdinfo_list_entry *new_le; pr_info("Collect fdinfo pid=%d fd=%d id=%#x\n", pid, e->fd, e->id); new_le = shmalloc(sizeof(*new_le)); if (!new_le) - return -1; + return NULL; futex_init(&new_le->real_pid); new_le->pid = pid; new_le->fe = e; + collect_used_fd(new_le, rst_info); + + return new_le; +} + +static int handle_fd(struct fdinfo_list_entry *new_le, struct rst_info *rst_info) +{ + struct fdinfo_list_entry *le; + struct file_desc *fdesc; + FdinfoEntry *e = new_le->fe; fdesc = find_file_desc(e); if (fdesc == NULL) { @@ -713,14 +722,23 @@ static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) else collect_gen_fd(new_le, rst_info); - collect_used_fd(new_le, rst_info); - list_add_tail(&new_le->desc_list, &le->desc_list); new_le->desc = fdesc; return 0; } +static int collect_fd(int pid, FdinfoEntry *e, struct rst_info *rst_info) +{ + struct fdinfo_list_entry *le; + + le = allocate_fd(pid, e, rst_info); + if (le == NULL) + return -1; + + return handle_fd(le, rst_info); +} + FdinfoEntry *dup_fdinfo(FdinfoEntry *old, int fd, unsigned flags) { FdinfoEntry *e; @@ -777,7 +795,7 @@ int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id) return 0; } -int prepare_fd_pid(struct pstree_item *item) +int collect_fd_pid(struct pstree_item *item) { int ret = 0; struct cr_img *img; @@ -801,6 +819,7 @@ int prepare_fd_pid(struct pstree_item *item) return -1; while (1) { + struct fdinfo_list_entry *le; FdinfoEntry *e; ret = pb_read_one_eof(img, &e, PB_FDINFO); @@ -813,17 +832,36 @@ int prepare_fd_pid(struct pstree_item *item) break; } - ret = collect_fd(pid, e, rst_info); - if (ret < 0) { + le = allocate_fd(pid, e, rst_info); + if (le == NULL) { fdinfo_entry__free_unpacked(e, NULL); + ret = -1; break; } + list_add_tail(&le->ps_list, &rst_info->fds); } close_image(img); return ret; } +int prepare_fd_pid(struct pstree_item *item) +{ + struct rst_info *rst_info = rsti(item); + struct fdinfo_list_entry *le, *t; + LIST_HEAD(head); + + list_splice_init(&rst_info->fds, &head); + + list_for_each_entry_safe(le, t, &head, ps_list) { + list_del(&le->ps_list); + if (handle_fd(le, rst_info)) + return -1; + } + + return 0; +} + #define SETFL_MASK (O_APPEND | O_ASYNC | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) int set_fd_flags(int fd, int flags) { diff --git a/criu/include/files.h b/criu/include/files.h index 153e7b3..2b6d58d 100644 --- a/criu/include/files.h +++ b/criu/include/files.h @@ -155,6 +155,7 @@ extern int rst_file_params(int fd, FownEntry *fown, int flags); extern void show_saved_files(void); extern int prepare_fds(struct pstree_item *me); +extern int collect_fd_pid(struct pstree_item *me); extern int prepare_fd_pid(struct pstree_item *me); extern int prepare_ctl_tty(int pid, struct rst_info *rst_info, u32 ctl_tty_id); extern int prepare_shared_fdinfo(void);