[CRIU] [PATCH cr 09/11] restore: restore content of private mappings before forking children

Andrey Vagin avagin at openvz.org
Mon Oct 15 11:32:22 EDT 2012


It's required for restoring copy-on-write regions.

The similar code will be removed from restorer.c.

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

diff --git a/cr-restore.c b/cr-restore.c
index b159124..6583425 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -232,6 +232,58 @@ static int map_private_vma(pid_t pid, struct vma_area *vma,
 	return 0;
 }
 
+static int restore_anon_vma_content(pid_t pid)
+{
+	struct vma_area *vma;
+	int fd, ret = 0;
+
+	vma = list_first_entry(&vma_list, struct vma_area, list);
+
+	fd = open_image_ro(CR_FD_PAGES, pid);
+	if (fd < 0)
+		return -1;
+
+	/*
+	 * Read page contents.
+	 */
+	while (1) {
+		u64 va;
+		char buf[PAGE_SIZE];
+		void *p;
+
+		ret = read(fd, &va, sizeof(va));
+		if (!ret)
+			break;
+
+		if (ret != sizeof(va)) {
+			pr_err("Bad mapping page size %d\n", ret);
+			return -1;
+		}
+
+		BUG_ON(va < vma->vma.start);
+
+		while (va >= vma->vma.end) {
+			BUG_ON(vma->list.next == &vma_list);
+			vma = list_entry(vma->list.next, struct vma_area, list);
+		}
+
+		ret = read(fd, buf, PAGE_SIZE);
+		if (ret != PAGE_SIZE) {
+			pr_err("Can'r read mapping page %d\n", ret);
+			return -1;
+		}
+
+		p = (void *) (va - vma->vma.start + vma->vma.shmid);
+		if (memcmp(p, buf, PAGE_SIZE) == 0)
+			continue;
+
+		memcpy(p, buf, PAGE_SIZE);
+	}
+	close(fd);
+
+	return 0;
+}
+
 static int read_vmas(int pid)
 {
 	int fd, ret = 0;
@@ -278,6 +330,8 @@ static int read_vmas(int pid)
 			break;
 	}
 
+	if (ret == 0)
+		ret = restore_anon_vma_content(pid);
 	close(fd);
 
 out:
-- 
1.7.1



More information about the CRIU mailing list