Commit 89d8b201 authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

restorer: unmap itself (v2)

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 66f21e6b
......@@ -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
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment