[CRIU] [PATCH 7/8] restorer: unmap itself
Andrey Vagin
avagin at openvz.org
Fri Sep 13 05:53:44 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.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
cr-restore.c | 25 ++++++++++++++++++++-----
include/crtools.h | 2 ++
include/restorer.h | 3 +++
pie/restorer.c | 10 ++++++++++
4 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/cr-restore.c b/cr-restore.c
index ddfb9f9..80a8c79 100644
--- a/cr-restore.c
+++ b/cr-restore.c
@@ -1365,6 +1365,7 @@ static void finalize_restore(int status)
for_each_pstree_item(item) {
pid_t pid = item->pid.real;
+ struct parasite_ctl *ctl;
if (item->state == TASK_DEAD)
continue;
@@ -1375,7 +1376,13 @@ 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);
+ if (ctl == NULL)
+ goto detach;
+ parasite_unmap(ctl, (unsigned long) item->rst->munmap_restorer);
+
+ /* TODO restore the process state */
detach:
if (ptrace(PTRACE_DETACH, pid, NULL, 0))
pr_perror("Unable to execute %d", pid);
@@ -2212,6 +2219,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;
@@ -2320,6 +2329,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
@@ -2332,16 +2343,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)
@@ -2353,6 +2364,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;
@@ -2370,6 +2382,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 b29ce11..8c2ddd9 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -510,6 +510,13 @@ 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);
+}
/*
* The main routine to restore task via sigreturn.
@@ -530,6 +537,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