[CRIU] [PATCH 12/15] restorer: unmap itself (v2)
Andrey Vagin
avagin at openvz.org
Mon Sep 23 06:33:35 EDT 2013
This patch adds a function for removing the restorer blob. This function
never returns and the process must be trapped on the exit from the
munmap syscall.
v2: * release parasite_ctl sturcture and use the new interface of
parasite_prep_ctl
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 28 +++++++++++++++++++++++-----
include/crtools.h | 2 ++
include/restorer.h | 3 +++
pie/restorer.c | 14 ++++++++++++++
4 files changed, 42 insertions(+), 5 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index a0b442f..67fd15e 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1362,6 +1362,7 @@ static void finalize_restore(int status)
for_each_pstree_item(item) {
pid_t pid = item->pid.real;
+ struct parasite_ctl *ctl;
int i;
if (item->state == TASK_DEAD)
@@ -1373,7 +1374,16 @@ static void finalize_restore(int status)
if (status < 0)
goto detach;
- /* TODO Unmap the restorer blob and restore the process state */
+ /* Unmap the restorer blob */
+ ctl = parasite_prep_ctl(pid, NULL);
+ if (ctl == NULL)
+ goto detach;
+
+ parasite_unmap(ctl, (unsigned long) item->rst->munmap_restorer);
+
+ xfree(ctl);
+
+ /* TODO restore the process state */
detach:
for (i = 0; i < item->nr_threads; i++) {
pid = item->threads[i].real;
@@ -2206,6 +2216,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
long new_sp, exec_mem_hint;
long ret;
+
+ void *bootstrap_start;
long restore_bootstrap_len;
struct task_restore_core_args *task_args;
@@ -2314,6 +2326,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
vdso_rt_size = vdso_rt_vma_size + vdso_rt_delta;
}
+ restore_bootstrap_len += vdso_rt_size;
+
/*
* Restorer is a blob (code + args) that will get mapped in some
* place, that should _not_ intersect with both -- current mappings
@@ -2326,16 +2340,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
*/
exec_mem_hint = restorer_get_vma_hint(pid, &rst_vmas.h, &self_vmas.h,
- restore_bootstrap_len +
- vdso_rt_size);
+ restore_bootstrap_len);
+ bootstrap_start = (void *) exec_mem_hint;
if (exec_mem_hint == -1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
- restore_bootstrap_len + vdso_rt_size);
+ restore_bootstrap_len);
goto err;
}
pr_info("Found bootstrap VMA hint at: 0x%lx (needs ~%ldK)\n", exec_mem_hint,
- KBYTES(restore_bootstrap_len + vdso_rt_size));
+ KBYTES(restore_bootstrap_len));
ret = remap_restorer_blob((void *)exec_mem_hint);
if (ret < 0)
@@ -2347,6 +2361,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
*/
restore_thread_exec_start = restorer_sym(exec_mem_hint, __export_restore_thread);
restore_task_exec_start = restorer_sym(exec_mem_hint, __export_restore_task);
+ current->rst->munmap_restorer = restorer_sym(exec_mem_hint, __export_unmap);
exec_mem_hint += restorer_len;
@@ -2364,6 +2379,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args = mem;
thread_args = mem + restore_task_vma_len;
+ task_args->bootstrap_start = bootstrap_start;
+ task_args->bootstrap_len = restore_bootstrap_len;
+
/*
* Get a reference to shared memory area which is
* used to signal if shmem restoration complete
diff --git a/include/crtools.h b/include/crtools.h
index a574b46..02c6bd3 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -177,6 +177,8 @@ struct rst_info {
unsigned long premmapped_len;
unsigned long clone_flags;
+ void *munmap_restorer;
+
int nr_zombies;
int service_fd_id;
diff --git a/include/restorer.h b/include/restorer.h
index 1ed1d81..ae762d7 100644
--- a/include/restorer.h
+++ b/include/restorer.h
@@ -126,6 +126,9 @@ struct task_restore_core_args {
unsigned long premmapped_len;
rt_sigaction_t sigchld_act;
+ void *bootstrap_start;
+ unsigned long bootstrap_len;
+
struct itimerval itimers[3];
int timer_n;
diff --git a/pie/restorer.c b/pie/restorer.c
index a9ab178..8e43609 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -511,6 +511,17 @@ static void restore_posix_timers(struct task_restore_core_args *args)
sys_timer_settime((timer_t)rt->spt.it_id, 0, &rt->val, NULL);
}
}
+static void *bootstrap_start;
+static unsigned int bootstrap_len;
+
+void __export_unmap(void)
+{
+ sys_munmap(bootstrap_start, bootstrap_len);
+ /*
+ * sys_munmap must not return here. The controll process must
+ * trap us on the exit from sys_munmap.
+ */
+}
/*
* The main routine to restore task via sigreturn.
@@ -532,6 +543,9 @@ long __export_restore_task(struct task_restore_core_args *args)
pid_t my_pid = sys_getpid();
rt_sigaction_t act;
+ bootstrap_start = args->bootstrap_start;
+ bootstrap_len = args->bootstrap_len;
+
task_entries = args->task_entries;
ksigfillset(&act.rt_sa_mask);
--
1.8.3.1
More information about the CRIU
mailing list