[CRIU] [PATCH cr 05/16] restore: collect vma-s before creating children (v2)

Andrey Vagin avagin at openvz.org
Tue Oct 23 06:02:17 EDT 2012


A private vma's should be inherited by children for
restoring copy-on-write regions.

v2: free parent's vma-s in this patch.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-restore.c |   40 +++++++++++++++++++++++++++-------------
 1 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index f74e323..9d1fdea 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -64,6 +64,9 @@ static int restore_task_with_children(void *);
 static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *vmas, int nr_vmas);
 static int prepare_restorer_blob(void);
 
+static LIST_HEAD(vma_list);
+static int nr_vmas;
+
 static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
 {
 	void *ret;
@@ -170,17 +173,22 @@ err:
 	return ret;
 }
 
-static int read_vmas(int pid, struct list_head *vmas, int *nr_vmas)
+static int read_vmas(int pid)
 {
-	int fd, ret = -1;
+	int fd, ret = 0;
+	LIST_HEAD(old);
+	struct vma_area *vma;
+
+	list_replace_init(&vma_list, &old);
+	INIT_LIST_HEAD(&vma_list);
 
+	/* Skip errors, because a zombie doesn't have an image of vmas */
 	fd = open_image_ro(CR_FD_VMAS, pid);
 	if (fd < 0)
-		return fd;
+		goto out;
 
-	*nr_vmas = 0;
+	nr_vmas = 0;
 	while (1) {
-		struct vma_area *vma;
 		VmaEntry *e;
 
 		ret = -1;
@@ -188,8 +196,8 @@ static int read_vmas(int pid, struct list_head *vmas, int *nr_vmas)
 		if (!vma)
 			break;
 
-		(*nr_vmas)++;
-		list_add_tail(&vma->list, vmas);
+		nr_vmas++;
+		list_add_tail(&vma->list, &vma_list);
 		ret = pb_read_one_eof(fd, &e, PB_VMAS);
 		if (ret <= 0)
 			break;
@@ -206,6 +214,14 @@ static int read_vmas(int pid, struct list_head *vmas, int *nr_vmas)
 	}
 
 	close(fd);
+
+out:
+	while (!list_empty(&old)) {
+		vma = list_first_entry(&old, struct vma_area, list);
+		list_del(&vma->list);
+		xfree(vma);
+	}
+
 	return ret;
 }
 
@@ -249,12 +265,7 @@ static int open_vmas(int pid, struct list_head *vmas)
 
 static int prepare_and_sigreturn(int pid, CoreEntry *core)
 {
-	int err, nr_vmas;
-	LIST_HEAD(vma_list);
-
-	err = read_vmas(pid, &vma_list, &nr_vmas);
-	if (err)
-		return err;
+	int err;
 
 	err = open_vmas(pid, &vma_list);
 	if (err)
@@ -835,6 +846,9 @@ static int restore_task_with_children(void *_arg)
 		exit(1);
 	}
 
+	if (read_vmas(pid))
+		exit(1);
+
 	pr_info("Restoring children:\n");
 	list_for_each_entry(child, &current->children, sibling) {
 		if (!restore_before_setsid(child))
-- 
1.7.1



More information about the CRIU mailing list