[CRIU] [PATCH v5 2/8] criu: slightly refactor memory dump to support delaying it
Andrew Vagin
avagin at virtuozzo.com
Sun Jul 10 09:45:51 PDT 2016
Mike, pls take a look at this issue:
https://github.com/xemul/criu/issues/189
I think zombies are handled incorrectly here
On Wed, Jun 29, 2016 at 08:55:07AM +0300, Mike Rapoport wrote:
> * keep pointer to parasite_ctl in dmp_info to simplify pre_dump_finish
> and make pre_dump and dump interfaces the same
> * pass boolean rather than pp_ret pointer to parasite_dump_pages_seized to
> distinguish delayed and immediate dump more explicitly
>
> Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
> ---
> criu/cr-dump.c | 23 +++++++++++------------
> criu/include/mem.h | 2 +-
> criu/include/parasite-syscall.h | 1 -
> criu/include/pstree.h | 2 ++
> criu/mem.c | 33 ++++++++++++++++-----------------
> criu/parasite-syscall.c | 2 ++
> 6 files changed, 32 insertions(+), 31 deletions(-)
>
> diff --git a/criu/cr-dump.c b/criu/cr-dump.c
> index 00d28e9..33355fb 100644
> --- a/criu/cr-dump.c
> +++ b/criu/cr-dump.c
> @@ -1086,7 +1086,7 @@ err:
> return ret;
> }
>
> -static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
> +static int pre_dump_one_task(struct pstree_item *item)
> {
> pid_t pid = item->pid.real;
> struct vm_area_list vmas;
> @@ -1142,13 +1142,12 @@ static int pre_dump_one_task(struct pstree_item *item, struct list_head *ctls)
>
> parasite_ctl->pid.virt = item->pid.virt = misc.pid;
>
> - ret = parasite_dump_pages_seized(parasite_ctl, &vmas, ¶site_ctl->mem_pp);
> + ret = parasite_dump_pages_seized(parasite_ctl, &vmas, true);
> if (ret)
> goto err_cure;
>
> if (parasite_cure_remote(parasite_ctl))
> pr_err("Can't cure (pid: %d) from parasite\n", pid);
> - list_add_tail(¶site_ctl->pre_list, ctls);
> err_free:
> free_mappings(&vmas);
> err:
> @@ -1299,7 +1298,7 @@ static int dump_one_task(struct pstree_item *item)
> }
> }
>
> - ret = parasite_dump_pages_seized(parasite_ctl, &vmas, NULL);
> + ret = parasite_dump_pages_seized(parasite_ctl, &vmas, false);
> if (ret)
> goto err_cure;
>
> @@ -1408,12 +1407,11 @@ static int setup_alarm_handler()
> return 0;
> }
>
> -static int cr_pre_dump_finish(struct list_head *ctls, int ret)
> +static int cr_pre_dump_finish(int ret)
> {
> - struct parasite_ctl *ctl, *n;
> + struct pstree_item *item;
>
> pstree_switch_state(root_item, TASK_ALIVE);
> - free_pstree(root_item);
>
> timing_stop(TIME_FROZEN);
>
> @@ -1421,7 +1419,8 @@ static int cr_pre_dump_finish(struct list_head *ctls, int ret)
> goto err;
>
> pr_info("Pre-dumping tasks' memory\n");
> - list_for_each_entry_safe(ctl, n, ctls, pre_list) {
> + for_each_pstree_item(item) {
> + struct parasite_ctl *ctl = dmpi(item)->parasite_ctl;
> struct page_xfer xfer;
>
> pr_info("\tPre-dumping %d\n", ctl->pid.virt);
> @@ -1440,10 +1439,11 @@ static int cr_pre_dump_finish(struct list_head *ctls, int ret)
> timing_stop(TIME_MEMWRITE);
>
> destroy_page_pipe(ctl->mem_pp);
> - list_del(&ctl->pre_list);
> parasite_cure_local(ctl);
> }
>
> + free_pstree(root_item);
> +
> if (irmap_predump_run()) {
> ret = -1;
> goto err;
> @@ -1469,7 +1469,6 @@ int cr_pre_dump_tasks(pid_t pid)
> {
> struct pstree_item *item;
> int ret = -1;
> - LIST_HEAD(ctls);
>
> root_item = alloc_pstree_item();
> if (!root_item)
> @@ -1520,7 +1519,7 @@ int cr_pre_dump_tasks(pid_t pid)
> goto err;
>
> for_each_pstree_item(item)
> - if (pre_dump_one_task(item, &ctls))
> + if (pre_dump_one_task(item))
> goto err;
>
> if (irmap_predump_prep())
> @@ -1528,7 +1527,7 @@ int cr_pre_dump_tasks(pid_t pid)
>
> ret = 0;
> err:
> - return cr_pre_dump_finish(&ctls, ret);
> + return cr_pre_dump_finish(ret);
> }
>
> static int cr_dump_finish(int ret)
> diff --git a/criu/include/mem.h b/criu/include/mem.h
> index 9377bbc..a9750db 100644
> --- a/criu/include/mem.h
> +++ b/criu/include/mem.h
> @@ -11,7 +11,7 @@ extern int do_task_reset_dirty_track(int pid);
> extern unsigned int dump_pages_args_size(struct vm_area_list *vmas);
> extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
> struct vm_area_list *vma_area_list,
> - struct page_pipe **pp);
> + bool delayed_dump);
>
> #define PME_PRESENT (1ULL << 63)
> #define PME_SWAP (1ULL << 62)
> diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
> index 15a13a6..6c78e23 100644
> --- a/criu/include/parasite-syscall.h
> +++ b/criu/include/parasite-syscall.h
> @@ -53,7 +53,6 @@ struct parasite_ctl {
> unsigned long args_size;
> int tsock; /* transport socket for transfering fds */
>
> - struct list_head pre_list;
> struct page_pipe *mem_pp;
> };
>
> diff --git a/criu/include/pstree.h b/criu/include/pstree.h
> index 327ad49..b01cc9e 100644
> --- a/criu/include/pstree.h
> +++ b/criu/include/pstree.h
> @@ -43,6 +43,8 @@ struct dmp_info {
> * threads. Dumping tasks with different creds is not supported.
> */
> struct proc_status_creds *pi_creds;
> +
> + struct parasite_ctl *parasite_ctl;
> };
>
> static inline struct dmp_info *dmpi(struct pstree_item *i)
> diff --git a/criu/mem.c b/criu/mem.c
> index db61aed..d619a72 100644
> --- a/criu/mem.c
> +++ b/criu/mem.c
> @@ -187,7 +187,7 @@ static int generate_iovs(struct vma_area *vma, struct page_pipe *pp, u64 *map, u
> }
>
> static struct parasite_dump_pages_args *prep_dump_pages_args(struct parasite_ctl *ctl,
> - struct vm_area_list *vma_area_list, struct page_pipe **pp_ret)
> + struct vm_area_list *vma_area_list, bool delayed_dump)
> {
> struct parasite_dump_pages_args *args;
> struct parasite_vma_entry *p_vma;
> @@ -205,7 +205,7 @@ static struct parasite_dump_pages_args *prep_dump_pages_args(struct parasite_ctl
> * Kernel write to aio ring is not soft-dirty tracked,
> * so we ignore them at pre-dump.
> */
> - if (vma_entry_is(vma->e, VMA_AREA_AIORING) && pp_ret)
> + if (vma_entry_is(vma->e, VMA_AREA_AIORING) && delayed_dump)
> continue;
> if (vma->e->prot & PROT_READ)
> continue;
> @@ -266,7 +266,7 @@ static int dump_pages(struct page_pipe *pp, struct parasite_ctl *ctl,
> static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
> struct parasite_dump_pages_args *args,
> struct vm_area_list *vma_area_list,
> - struct page_pipe **pp_ret)
> + bool delayed_dump)
> {
> pmc_t pmc = PMC_INIT;
> struct page_pipe *pp;
> @@ -292,12 +292,13 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
> return -1;
>
> ret = -1;
> - pp = create_page_pipe(vma_area_list->priv_size,
> - pargs_iovs(args), pp_ret == NULL);
> +
> + ctl->mem_pp = pp = create_page_pipe(vma_area_list->priv_size,
> + pargs_iovs(args), !delayed_dump);
> if (!pp)
> goto out;
>
> - if (pp_ret == NULL) {
> + if (!delayed_dump) {
> ret = open_page_xfer(&xfer, CR_FD_PAGEMAP, ctl->pid.virt);
> if (ret < 0)
> goto out_pp;
> @@ -322,7 +323,7 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
> if (!vma_area_is_private(vma_area, kdat.task_size))
> continue;
> if (vma_entry_is(vma_area->e, VMA_AREA_AIORING)) {
> - if (pp_ret)
> + if (delayed_dump)
> continue;
> has_parent = false;
> }
> @@ -333,7 +334,7 @@ static int __parasite_dump_pages_seized(struct parasite_ctl *ctl,
> again:
> ret = generate_iovs(vma_area, pp, map, &off, has_parent);
> if (ret == -EAGAIN) {
> - BUG_ON(pp_ret);
> + BUG_ON(delayed_dump);
>
> ret = dump_pages(pp, ctl, args, &xfer);
> if (ret)
> @@ -345,25 +346,22 @@ again:
> goto out_xfer;
> }
>
> - ret = dump_pages(pp, ctl, args, pp_ret ? NULL : &xfer);
> + ret = dump_pages(pp, ctl, args, delayed_dump ? NULL : &xfer);
> if (ret)
> goto out_xfer;
>
> timing_stop(TIME_MEMDUMP);
>
> - if (pp_ret)
> - *pp_ret = pp;
> -
> /*
> * Step 4 -- clean up
> */
>
> ret = task_reset_dirty_track(ctl->pid.real);
> out_xfer:
> - if (pp_ret == NULL)
> + if (!delayed_dump)
> xfer.close(&xfer);
> out_pp:
> - if (ret || !pp_ret)
> + if (ret || !delayed_dump)
> destroy_page_pipe(pp);
> out:
> pmc_fini(&pmc);
> @@ -372,12 +370,12 @@ out:
> }
>
> int parasite_dump_pages_seized(struct parasite_ctl *ctl,
> - struct vm_area_list *vma_area_list, struct page_pipe **pp)
> + struct vm_area_list *vma_area_list, bool delayed_dump)
> {
> int ret;
> struct parasite_dump_pages_args *pargs;
>
> - pargs = prep_dump_pages_args(ctl, vma_area_list, pp);
> + pargs = prep_dump_pages_args(ctl, vma_area_list, delayed_dump);
>
> /*
> * Add PROT_READ protection for all VMAs we're about to
> @@ -399,7 +397,8 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl,
> return -1;
> }
>
> - ret = __parasite_dump_pages_seized(ctl, pargs, vma_area_list, pp);
> + ret = __parasite_dump_pages_seized(ctl, pargs, vma_area_list,
> + delayed_dump);
>
> if (ret) {
> pr_err("Can't dump page with parasite\n");
> diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
> index c2467dc..29964a9 100644
> --- a/criu/parasite-syscall.c
> +++ b/criu/parasite-syscall.c
> @@ -1434,6 +1434,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
> if (parasite_start_daemon(ctl, item))
> goto err_restore;
>
> + dmpi(item)->parasite_ctl = ctl;
> +
> return ctl;
>
> err_restore:
> --
> 1.9.1
>
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list