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

Andrey Vagin avagin at openvz.org
Tue Oct 23 06:02:23 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 |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/cr-restore.c b/cr-restore.c
index 4ff552a..0f76cc1 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -262,6 +262,59 @@ static int unmap_priv_guard_pages()
 	return 0;
 }
 
+static int restore_priv_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_premmaped_start(&vma->vma));
+		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;
@@ -342,6 +395,8 @@ static int read_vmas(int pid)
 		addr += vma_area_len(vma);
 	}
 
+	if (ret == 0)
+		ret = restore_priv_vma_content(pid);
 	close(fd);
 
 out:
-- 
1.7.1



More information about the CRIU mailing list