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) ...@@ -1362,6 +1362,7 @@ static void finalize_restore(int status)
for_each_pstree_item(item) { for_each_pstree_item(item) {
pid_t pid = item->pid.real; pid_t pid = item->pid.real;
struct parasite_ctl *ctl;
int i; int i;
if (item->state == TASK_DEAD) if (item->state == TASK_DEAD)
...@@ -1373,7 +1374,16 @@ static void finalize_restore(int status) ...@@ -1373,7 +1374,16 @@ static void finalize_restore(int status)
if (status < 0) if (status < 0)
goto detach; 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: detach:
for (i = 0; i < item->nr_threads; i++) { for (i = 0; i < item->nr_threads; i++) {
pid = item->threads[i].real; pid = item->threads[i].real;
...@@ -2206,6 +2216,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2206,6 +2216,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
long new_sp, exec_mem_hint; long new_sp, exec_mem_hint;
long ret; long ret;
void *bootstrap_start;
long restore_bootstrap_len; long restore_bootstrap_len;
struct task_restore_core_args *task_args; struct task_restore_core_args *task_args;
...@@ -2314,6 +2326,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2314,6 +2326,8 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
vdso_rt_size = vdso_rt_vma_size + vdso_rt_delta; 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 * Restorer is a blob (code + args) that will get mapped in some
* place, that should _not_ intersect with both -- current mappings * place, that should _not_ intersect with both -- current mappings
...@@ -2326,16 +2340,16 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -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, exec_mem_hint = restorer_get_vma_hint(pid, &rst_vmas.h, &self_vmas.h,
restore_bootstrap_len + restore_bootstrap_len);
vdso_rt_size); bootstrap_start = (void *) exec_mem_hint;
if (exec_mem_hint == -1) { if (exec_mem_hint == -1) {
pr_err("No suitable area for task_restore bootstrap (%ldK)\n", pr_err("No suitable area for task_restore bootstrap (%ldK)\n",
restore_bootstrap_len + vdso_rt_size); restore_bootstrap_len);
goto err; goto err;
} }
pr_info("Found bootstrap VMA hint at: 0x%lx (needs ~%ldK)\n", exec_mem_hint, 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); ret = remap_restorer_blob((void *)exec_mem_hint);
if (ret < 0) if (ret < 0)
...@@ -2347,6 +2361,7 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -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_thread_exec_start = restorer_sym(exec_mem_hint, __export_restore_thread);
restore_task_exec_start = restorer_sym(exec_mem_hint, __export_restore_task); 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; exec_mem_hint += restorer_len;
...@@ -2364,6 +2379,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core) ...@@ -2364,6 +2379,9 @@ static int sigreturn_restore(pid_t pid, CoreEntry *core)
task_args = mem; task_args = mem;
thread_args = mem + restore_task_vma_len; 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 * Get a reference to shared memory area which is
* used to signal if shmem restoration complete * used to signal if shmem restoration complete
......
...@@ -177,6 +177,8 @@ struct rst_info { ...@@ -177,6 +177,8 @@ struct rst_info {
unsigned long premmapped_len; unsigned long premmapped_len;
unsigned long clone_flags; unsigned long clone_flags;
void *munmap_restorer;
int nr_zombies; int nr_zombies;
int service_fd_id; int service_fd_id;
......
...@@ -126,6 +126,9 @@ struct task_restore_core_args { ...@@ -126,6 +126,9 @@ struct task_restore_core_args {
unsigned long premmapped_len; unsigned long premmapped_len;
rt_sigaction_t sigchld_act; rt_sigaction_t sigchld_act;
void *bootstrap_start;
unsigned long bootstrap_len;
struct itimerval itimers[3]; struct itimerval itimers[3];
int timer_n; int timer_n;
......
...@@ -511,6 +511,17 @@ static void restore_posix_timers(struct task_restore_core_args *args) ...@@ -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); 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. * The main routine to restore task via sigreturn.
...@@ -532,6 +543,9 @@ long __export_restore_task(struct task_restore_core_args *args) ...@@ -532,6 +543,9 @@ long __export_restore_task(struct task_restore_core_args *args)
pid_t my_pid = sys_getpid(); pid_t my_pid = sys_getpid();
rt_sigaction_t act; rt_sigaction_t act;
bootstrap_start = args->bootstrap_start;
bootstrap_len = args->bootstrap_len;
task_entries = args->task_entries; task_entries = args->task_entries;
ksigfillset(&act.rt_sa_mask); 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