Commit 78a3670b authored by Pavel Emelyanov's avatar Pavel Emelyanov

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: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent c158ccdf
...@@ -120,6 +120,7 @@ int cr_exec(int pid, char **opt) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 @@ ...@@ -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: ...@@ -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_ ...@@ -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, ...@@ -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;
......
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