[CRIU] [PATCH 13/14] restore: restore pocesses which share one fdtable (v4)
Pavel Emelyanov
xemul at parallels.com
Fri Jan 11 05:55:42 EST 2013
On 01/11/2013 01:22 PM, Andrey Vagin wrote:
> Currenly crtools supports a case when a child shared a fd table
> with parent.
>
> Here is only two interesting things.
> * Service descriptors should be cloned for each process
> who shared one fd table.
> * One task should restore files and other tasks should sleep in this
> * time.
>
> v2: * allocate fdt_lock from shared memory
> * don't wait a child, if it doesn't share fdtable
> v3: * don't move ids on the pstree image
> v4: * save ids in a separate image
> * save fdinfo per id instead of pid
>
> Signed-off-by: Andrey Vagin <avagin at openvz.org>
> ---
> cr-dump.c | 12 +++++++-----
> cr-restore.c | 17 ++++++++++++++---
> files.c | 28 ++++++++++++++++++++++------
> include/crtools.h | 1 +
> pstree.c | 1 +
> 5 files changed, 45 insertions(+), 14 deletions(-)
>
> diff --git a/cr-dump.c b/cr-dump.c
> index fb81bc4..7384a56 100644
> --- a/cr-dump.c
> +++ b/cr-dump.c
> @@ -692,7 +692,7 @@ static int dump_task_kobj_ids(struct pstree_item *item)
>
> new = 0;
> ids->files_id = kid_generate_gen(&files_tree, &elem, &new);
> - if (!ids->files_id || !new) {
> + if (!ids->files_id || (!new && !shared_fdtable(item))) {
> pr_err("Can't make FILES id for %d\n", pid);
> return -1;
> }
> @@ -1434,10 +1434,12 @@ static int dump_one_task(struct pstree_item *item)
> goto err_cure;
> }
>
> - ret = dump_task_files_seized(parasite_ctl, item, dfds);
> - if (ret) {
> - pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
> - goto err_cure;
> + if (!shared_fdtable(item)) {
> + ret = dump_task_files_seized(parasite_ctl, item, dfds);
> + if (ret) {
> + pr_err("Dump files (pid: %d) failed with %d\n", pid, ret);
> + goto err_cure;
> + }
> }
>
> ret = parasite_dump_pages_seized(parasite_ctl, &vma_area_list, cr_fdset);
> diff --git a/cr-restore.c b/cr-restore.c
> index ccc404d..9b69eff 100644
> --- a/cr-restore.c
> +++ b/cr-restore.c
> @@ -808,6 +808,9 @@ static inline int fork_with_pid(struct pstree_item *item, unsigned long ns_clone
> ca.item = item;
> ca.clone_flags = ns_clone_flags;
>
> + if (shared_fdtable(item))
> + ca.clone_flags |= CLONE_FILES;
> +
> if (!(ca.clone_flags & CLONE_NEWPID)) {
> char buf[32];
>
> @@ -995,11 +998,19 @@ static int restore_task_with_children(void *_arg)
> int ret;
> sigset_t blockmask;
>
> - close_safe(&ca->fd);
> - close_old_fds(current);
> -
> current = ca->item;
Huh? Was current uninitialized before this patch?
>
> + if ( !(ca->clone_flags & CLONE_FILES)) {
> + close_safe(&ca->fd);
> + close_old_fds(current);
> + }
> +
> + if (current->state != TASK_HELPER) {
> + ret = clone_service_fd(current->rst->service_fd_id);
> + if (ret)
> + exit(1);
> + }
> +
> pid = getpid();
> if (current->pid.virt != pid) {
> pr_err("Pid %d do not match expected %d\n", pid, current->pid.virt);
> diff --git a/files.c b/files.c
> index 2a22c3a..681ff47 100644
> --- a/files.c
> +++ b/files.c
> @@ -541,15 +541,29 @@ int close_old_fds(struct pstree_item *me)
>
> int prepare_fds(struct pstree_item *me)
> {
> - u32 ret;
> + u32 ret = 0;
> int state;
>
> - ret = close_old_fds(me);
> - if (ret)
> - goto err;
> -
> pr_info("Opening fdinfo-s\n");
>
> + if (me->rst->fdt) {
> + struct fdt *fdt = me->rst->fdt;
> +
> + /*
> + * Wait all tasks, who share a current fd table.
> + * We should be sure, that nobody use any file
> + * descriptor while fdtable is being restored.
> + */
> + futex_inc_and_wake(&fdt->fdt_lock);
> + futex_wait_while_lt(&fdt->fdt_lock, fdt->nr);
> +
> + if (fdt->pid != me->pid.virt) {
> + pr_info("File descriptor talbe is shared with %d\n", fdt->pid);
> + futex_wait_until(&fdt->fdt_lock, fdt->nr + 1);
> + goto out;
> + }
> + }
> +
> for (state = 0; state < ARRAY_SIZE(states); state++) {
> ret = open_fdinfos(me->pid.virt, &me->rst->fds, state);
> if (ret)
> @@ -573,7 +587,9 @@ int prepare_fds(struct pstree_item *me)
> break;
> }
>
> -err:
> + if (me->rst->fdt)
> + futex_inc_and_wake(&me->rst->fdt->fdt_lock);
> +out:
> tty_fini_fds();
> return ret;
> }
> diff --git a/include/crtools.h b/include/crtools.h
> index 00c917d..7a7f101 100644
> --- a/include/crtools.h
> +++ b/include/crtools.h
> @@ -244,6 +244,7 @@ struct rst_info {
> void *premmapped_addr;
> unsigned long premmapped_len;
>
> + int service_fd_id;
Alignment.
> struct fdt *fdt;
> };
>
> diff --git a/pstree.c b/pstree.c
> index 85371d7..a9987f9 100644
> --- a/pstree.c
> +++ b/pstree.c
> @@ -463,6 +463,7 @@ static int prepare_pstree_ids(void)
> fdt = parent->rst->fdt;
>
> item->rst->fdt = fdt;
> + item->rst->service_fd_id = fdt->nr;
> fdt->nr++;
> if (fdt->pid > item->pid.virt)
> fdt->pid = item->pid.virt;
>
More information about the CRIU
mailing list