[CRIU] [PATCH 05/15] restore: collect vma-s before creating children (v2)
Andrey Vagin
avagin at openvz.org
Fri Nov 2 09:31:57 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 | 53 +++++++++++++++++++++++++++++++++--------------------
1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index 9cf0dc9..1c9da15 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -62,9 +62,12 @@
static struct pstree_item *current;
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 sigreturn_restore(pid_t pid, CoreEntry *core);
static int prepare_restorer_blob(void);
+static LIST_HEAD(rst_vma_list);
+static int rst_nr_vmas;
+
static int shmem_remap(void *old_addr, void *new_addr, unsigned long size)
{
void *ret;
@@ -176,17 +179,21 @@ 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(&rst_vma_list, &old);
+ /* 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;
+ rst_nr_vmas = 0;
while (1) {
- struct vma_area *vma;
VmaEntry *e;
ret = -1;
@@ -194,8 +201,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);
+ rst_nr_vmas++;
+ list_add_tail(&vma->list, &rst_vma_list);
ret = pb_read_one_eof(fd, &e, PB_VMAS);
if (ret <= 0)
break;
@@ -212,6 +219,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;
}
@@ -255,18 +270,13 @@ 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);
+ int err;
- err = read_vmas(pid, &vma_list, &nr_vmas);
+ err = open_vmas(pid, &rst_vma_list);
if (err)
return err;
- err = open_vmas(pid, &vma_list);
- if (err)
- return err;
-
- return sigreturn_restore(pid, core, &vma_list, nr_vmas);
+ return sigreturn_restore(pid, core);
}
static rt_sigaction_t sigchld_act;
@@ -844,6 +854,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, ¤t->children, sibling) {
if (!restore_before_setsid(child))
@@ -1355,7 +1368,7 @@ static int prep_sched_info(struct rst_sched_param *sp, ThreadCoreEntry *tc)
return 0;
}
-static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_vmas, int nr_vmas)
+static int sigreturn_restore(pid_t pid, CoreEntry *core)
{
long restore_task_vma_len;
long restore_thread_vma_len, self_vmas_len, vmas_len;
@@ -1390,7 +1403,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
mark_stack_vma((long) &self_vma_list, &self_vma_list);
self_vmas_len = round_up((ret + 1) * sizeof(VmaEntry), PAGE_SIZE);
- vmas_len = round_up((nr_vmas + 1) * sizeof(VmaEntry), PAGE_SIZE);
+ vmas_len = round_up((rst_nr_vmas + 1) * sizeof(VmaEntry), PAGE_SIZE);
/* pr_info_vma_list(&self_vma_list); */
@@ -1418,7 +1431,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
SHMEMS_SIZE + TASK_ENTRIES_SIZE +
self_vmas_len + vmas_len +
rst_tcp_socks_size;
- exec_mem_hint = restorer_get_vma_hint(pid, tgt_vmas, &self_vma_list,
+ exec_mem_hint = restorer_get_vma_hint(pid, &rst_vma_list, &self_vma_list,
restore_bootstrap_len);
if (exec_mem_hint == -1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
@@ -1492,7 +1505,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core, struct list_head *tgt_v
goto err;
mem += self_vmas_len;
- task_args->tgt_vmas = vma_list_remap(mem, vmas_len, tgt_vmas);
+ task_args->tgt_vmas = vma_list_remap(mem, vmas_len, &rst_vma_list);
if (!task_args->tgt_vmas)
goto err;
--
1.7.11.7
More information about the CRIU
mailing list