mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-28 20:42:49 +00:00
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: Andrey Vagin <avagin@openvz.org>
Signed-off-by: Pavel Emelyanov <xemul@parallels.com>
This commit is contained in:
parent
66f21e6b71
commit
89d8b20186
4 changed files with 42 additions and 5 deletions
28
cr-restore.c
28
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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue