From a17f01e30e4ab31168fffe4ed08d59bfb3af1448 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Mon, 30 May 2016 17:52:00 +0300 Subject: [PATCH] mem: Copy vme-s to restorer later 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 --- criu/cr-restore.c | 5 ++++- criu/include/mem.h | 1 + criu/mem.c | 35 +++++++++++++++++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/criu/cr-restore.c b/criu/cr-restore.c index 5a5e287a4..baf57d1c2 100644 --- a/criu/cr-restore.c +++ b/criu/cr-restore.c @@ -502,7 +502,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)) @@ -558,6 +558,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; + return sigreturn_restore(pid, ta, args_len, core); } diff --git a/criu/include/mem.h b/criu/include/mem.h index 2e0ab9553..9377bbc27 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 f582ad207..bccf2269c 100644 --- a/criu/mem.c +++ b/criu/mem.c @@ -879,29 +879,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;