mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +00:00
parasite: Pass exec start point to parasite_prep_ctl
The parasite_prep_ctl() will become compel call, so it won't have the code that scans CRIU's vma area list. For pure compel users we'll need to add simple /proc/maps scanner that'd find the entry point. Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
@@ -120,6 +120,7 @@ int cr_exec(int pid, char **opt)
|
|||||||
struct vm_area_list vmas;
|
struct vm_area_list vmas;
|
||||||
int ret, prev_state, exit_code = -1;
|
int ret, prev_state, exit_code = -1;
|
||||||
struct proc_status_creds *creds = NULL;
|
struct proc_status_creds *creds = NULL;
|
||||||
|
unsigned long p_start;
|
||||||
|
|
||||||
if (!sys_name) {
|
if (!sys_name) {
|
||||||
pr_err("Syscall name required\n");
|
pr_err("Syscall name required\n");
|
||||||
@@ -159,7 +160,13 @@ int cr_exec(int pid, char **opt)
|
|||||||
goto out_unseize;
|
goto out_unseize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctl = parasite_prep_ctl(pid, &vmas);
|
p_start = get_exec_start(&vmas);
|
||||||
|
if (!p_start) {
|
||||||
|
pr_err("No suitable VM are found\n");
|
||||||
|
goto out_unseize;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl = parasite_prep_ctl(pid, p_start);
|
||||||
if (!ctl) {
|
if (!ctl) {
|
||||||
pr_err("Can't prep ctl %d\n", pid);
|
pr_err("Can't prep ctl %d\n", pid);
|
||||||
goto out_unseize;
|
goto out_unseize;
|
||||||
|
@@ -1536,7 +1536,7 @@ static void finalize_restore(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Unmap the restorer blob */
|
/* Unmap the restorer blob */
|
||||||
ctl = parasite_prep_ctl(pid, NULL);
|
ctl = parasite_prep_ctl(pid, 0);
|
||||||
if (ctl == NULL)
|
if (ctl == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@@ -99,8 +99,8 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
|
|||||||
struct pstree_item *item,
|
struct pstree_item *item,
|
||||||
struct vm_area_list *vma_area_list);
|
struct vm_area_list *vma_area_list);
|
||||||
extern void parasite_ensure_args_size(unsigned long sz);
|
extern void parasite_ensure_args_size(unsigned long sz);
|
||||||
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid,
|
extern unsigned long get_exec_start(struct vm_area_list *);
|
||||||
struct vm_area_list *vma_area_list);
|
extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start);
|
||||||
extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
|
extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
|
||||||
|
|
||||||
extern int parasite_dump_cgroup(struct parasite_ctl *ctl, struct parasite_dump_cgroup_args *cgroup);
|
extern int parasite_dump_cgroup(struct parasite_ctl *ctl, struct parasite_dump_cgroup_args *cgroup);
|
||||||
|
@@ -44,11 +44,11 @@
|
|||||||
#define MEMFD_FNAME "CRIUMFD"
|
#define MEMFD_FNAME "CRIUMFD"
|
||||||
#define MEMFD_FNAME_SZ sizeof(MEMFD_FNAME)
|
#define MEMFD_FNAME_SZ sizeof(MEMFD_FNAME)
|
||||||
|
|
||||||
static unsigned long get_exec_start(struct list_head *vma_area_list)
|
unsigned long get_exec_start(struct vm_area_list *vmas)
|
||||||
{
|
{
|
||||||
struct vma_area *vma_area;
|
struct vma_area *vma_area;
|
||||||
|
|
||||||
list_for_each_entry(vma_area, vma_area_list, list) {
|
list_for_each_entry(vma_area, &vmas->h, list) {
|
||||||
unsigned long len;
|
unsigned long len;
|
||||||
|
|
||||||
if (vma_area->e->start >= kdat.task_size)
|
if (vma_area->e->start >= kdat.task_size)
|
||||||
@@ -1144,7 +1144,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If vma_area_list is NULL, a place for injecting syscall will not be set. */
|
/* If vma_area_list is NULL, a place for injecting syscall will not be set. */
|
||||||
struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list)
|
struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start)
|
||||||
{
|
{
|
||||||
struct parasite_ctl *ctl = NULL;
|
struct parasite_ctl *ctl = NULL;
|
||||||
|
|
||||||
@@ -1168,17 +1168,7 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_
|
|||||||
ctl->pid.real = pid;
|
ctl->pid.real = pid;
|
||||||
ctl->pid.virt = 0;
|
ctl->pid.virt = 0;
|
||||||
|
|
||||||
if (vma_area_list == NULL)
|
ctl->syscall_ip = exec_start;
|
||||||
return ctl;
|
|
||||||
|
|
||||||
/* Search a place for injecting syscall */
|
|
||||||
ctl->syscall_ip = get_exec_start(&vma_area_list->h);
|
|
||||||
if (!ctl->syscall_ip) {
|
|
||||||
pr_err("No suitable VMA found to run parasite "
|
|
||||||
"bootstrap code (pid: %d)\n", pid);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
pr_debug("Parasite syscall_ip at %p\n", (void *)ctl->syscall_ip);
|
pr_debug("Parasite syscall_ip at %p\n", (void *)ctl->syscall_ip);
|
||||||
|
|
||||||
return ctl;
|
return ctl;
|
||||||
@@ -1365,7 +1355,13 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
|
|||||||
|
|
||||||
BUG_ON(item->threads[0].real != pid);
|
BUG_ON(item->threads[0].real != pid);
|
||||||
|
|
||||||
ctl = parasite_prep_ctl(pid, vma_area_list);
|
p = get_exec_start(vma_area_list);
|
||||||
|
if (!p) {
|
||||||
|
pr_err("No suitable VM found\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctl = parasite_prep_ctl(pid, p);
|
||||||
if (!ctl)
|
if (!ctl)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user