mem: Copy vme-s to restorer later

Submitted by Pavel Emelianov on May 30, 2016, 2:52 p.m.

Details

Message ID 574C53A8.4000808@virtuozzo.com
State Accepted
Series "mem: Copy vme-s to restorer later"
Commit adb81bc0009925fc5ed931144360903c2c627aba
Headers show

Commit Message

Pavel Emelianov May 30, 2016, 2:52 p.m.
An interference of sigreturn_restore rework patches and vm_open callback ones
has lead to the situation when vme for restorer has already been copied to
rst-mem, but sysv shmem vm_open tried to modify previously seen vmes.

Fix this by copying vme-s to restorer late, but still before sigreturn_restore.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/cr-restore.c  |  5 ++++-
 criu/include/mem.h |  1 +
 criu/mem.c         | 35 +++++++++++++++++++++++------------
 3 files changed, 28 insertions(+), 13 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 0594d4d..a1959e8 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -504,7 +504,7 @@  static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (prepare_file_locks(pid))
 		return -1;
 
-	if (prepare_vmas(current, ta))
+	if (open_vmas(current))
 		return -1;
 
 	if (prepare_aios(current, ta))
@@ -560,6 +560,9 @@  static int restore_one_alive_task(int pid, CoreEntry *core)
 	if (prepare_mm(pid, ta))
 		return -1;
 
+	if (prepare_vmas(current, ta))
+		return -1;
+
 	if (setup_uffd(pid, ta))
 		return -1;
 
diff --git a/criu/include/mem.h b/criu/include/mem.h
index 2e0ab95..9377bbc 100644
--- a/criu/include/mem.h
+++ b/criu/include/mem.h
@@ -25,6 +25,7 @@  extern int parasite_dump_pages_seized(struct parasite_ctl *ctl,
 #define PME_PFRAME(x)		((x) & PME_PFRAME_MASK)
 
 struct task_restore_args;
+int open_vmas(struct pstree_item *t);
 int prepare_vmas(struct pstree_item *t, struct task_restore_args *ta);
 int unmap_guard_pages(struct pstree_item *t);
 int prepare_mappings(struct pstree_item *t);
diff --git a/criu/mem.c b/criu/mem.c
index eea4903..fbcc77d 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -892,29 +892,40 @@  int unmap_guard_pages(struct pstree_item *t)
 	return 0;
 }
 
-int prepare_vmas(struct pstree_item *t, struct task_restore_args *ta)
+int open_vmas(struct pstree_item *t)
 {
 	int pid = t->pid.virt;
 	struct vma_area *vma;
 	struct vm_area_list *vmas = &rsti(t)->vmas;
 
+	list_for_each_entry(vma, &vmas->h, list) {
+		if (!vma_area_is(vma, VMA_AREA_REGULAR) || !vma->vm_open)
+			continue;
+
+		pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" (%x) vma\n",
+				vma->e->start, vma->e->end,
+				vma->e->pgoff, vma->e->status);
+
+		if (vma->vm_open(pid, vma)) {
+			pr_err("`- Can't open vma\n");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+int prepare_vmas(struct pstree_item *t, struct task_restore_args *ta)
+{
+	struct vma_area *vma;
+	struct vm_area_list *vmas = &rsti(t)->vmas;
+
 	ta->vmas = (VmaEntry *)rst_mem_align_cpos(RM_PRIVATE);
 	ta->vmas_n = vmas->nr;
 
 	list_for_each_entry(vma, &vmas->h, list) {
 		VmaEntry *vme;
 
-		if (vma_area_is(vma, VMA_AREA_REGULAR)) {
-			pr_info("Opening 0x%016"PRIx64"-0x%016"PRIx64" 0x%016"PRIx64" (%x) vma\n",
-					vma->e->start, vma->e->end,
-					vma->e->pgoff, vma->e->status);
-
-			if (vma->vm_open && vma->vm_open(pid, vma)) {
-				pr_err("`- Can't open vma\n");
-				return -1;
-			}
-		}
-
 		vme = rst_mem_alloc(sizeof(*vme), RM_PRIVATE);
 		if (!vme)
 			return -1;