[v5,2/8] criu: slightly refactor memory dump to support delaying it

Submitted by Mike Rapoport on June 29, 2016, 5:55 a.m.

Details

Message ID 1467179713-14400-3-git-send-email-rppt@linux.vnet.ibm.com
State Rejected
Series "criu: make pagemap friendlier to random access"
Headers show

Commit Message

Mike Rapoport June 29, 2016, 5:55 a.m.
* 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@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(-)

Patch hide | download patch | download mbox

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, &parasite_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(&parasite_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:

Comments

Pavel Emelianov July 4, 2016, 6:30 p.m.
Mike, there recently has been merged a 32-bit C/R patchset which
messes with page-pipes (introducing compat iovs). Would you rebase
this set onto these changes, as they heavily conflict with each
other :(

-- Pavel
Pavel Emelianov July 6, 2016, 6:59 a.m.
OK, this happened to be simpler than I thought yesterday.
This one applied ... meanwhile %)
Andrey Vagin July 6, 2016, 10:50 p.m.
On Wed, Jul 06, 2016 at 09:59:27AM +0300, Pavel Emelyanov wrote:
> OK, this happened to be simpler than I thought yesterday.
> This one applied ... meanwhile %)
> 

========================== Run zdtm/static/env00 in h ==========================
Start test
./env00 --pidfile=env00.pid --outfile=env00.out --envname=ENV_00_TEST
Run criu pre-dump
################# Test zdtm/static/env00 FAIL at CRIU pre-dump #################
Wait for zdtm/static/env00 to die for 0.100000
##################################### FAIL #####################################

Program terminated with signal SIGSEGV, Segmentation fault.
#0  page_xfer_dump_pages (xfer=xfer@entry=0x7fff71e71450, pp=0x0, off=off@entry=0) at page-xfer.c:361
361		list_for_each_entry(ppb, &pp->bufs, l) {
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.23.1-8.fc24.x86_64 libnl3-3.2.27-3.fc24.x86_64 libselinux-2.5-3.fc24.x86_64 pcre-8.39-2.fc24.x86_64 protobuf-c-1.2.1-1.fc24.x86_64
(gdb) bt
#0  page_xfer_dump_pages (xfer=xfer@entry=0x7fff71e71450, pp=0x0, off=off@entry=0) at page-xfer.c:361
#1  0x00000000004357c2 in cr_pre_dump_finish (ret=0) at cr-dump.c:1458
#2  cr_pre_dump_tasks (pid=pid@entry=24) at cr-dump.c:1556
#3  0x000000000041f6b5 in main (argc=<optimized out>, argv=0x7fff71e71658, envp=<optimized out>) at crtools.c:753
Mike Rapoport July 7, 2016, 1:56 a.m.
On Thu, Jul 7, 2016 at 1:50 AM, Andrew Vagin <avagin@virtuozzo.com> wrote:
> On Wed, Jul 06, 2016 at 09:59:27AM +0300, Pavel Emelyanov wrote:
>> OK, this happened to be simpler than I thought yesterday.
>> This one applied ... meanwhile %)
>>
>
> ========================== Run zdtm/static/env00 in h ==========================
> Start test
> ./env00 --pidfile=env00.pid --outfile=env00.out --envname=ENV_00_TEST
> Run criu pre-dump
> ################# Test zdtm/static/env00 FAIL at CRIU pre-dump #################
> Wait for zdtm/static/env00 to die for 0.100000
> ##################################### FAIL #####################################

Well, apparently, there is a conflict with 32-bit :(

> Program terminated with signal SIGSEGV, Segmentation fault.
> #0  page_xfer_dump_pages (xfer=xfer@entry=0x7fff71e71450, pp=0x0, off=off@entry=0) at page-xfer.c:361
> 361             list_for_each_entry(ppb, &pp->bufs, l) {
> Missing separate debuginfos, use: dnf debuginfo-install glibc-2.23.1-8.fc24.x86_64 libnl3-3.2.27-3.fc24.x86_64 libselinux-2.5-3.fc24.x86_64 pcre-8.39-2.fc24.x86_64 protobuf-c-1.2.1-1.fc24.x86_64
> (gdb) bt
> #0  page_xfer_dump_pages (xfer=xfer@entry=0x7fff71e71450, pp=0x0, off=off@entry=0) at page-xfer.c:361
> #1  0x00000000004357c2 in cr_pre_dump_finish (ret=0) at cr-dump.c:1458
> #2  cr_pre_dump_tasks (pid=pid@entry=24) at cr-dump.c:1556
> #3  0x000000000041f6b5 in main (argc=<optimized out>, argv=0x7fff71e71658, envp=<optimized out>) at crtools.c:753
>
> _______________________________________________
>> CRIU mailing list
>> CRIU@openvz.org
>> https://lists.openvz.org/mailman/listinfo/criu
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu