[CRIU] [PATCH 13/78] infect: Keep entry point for first syscall on ictx
Cyrill Gorcunov
gorcunov at openvz.org
Mon Nov 7 08:35:58 PST 2016
From: Pavel Emelyanov <xemul at virtuozzo.com>
This is the address of an executable VMA. To get one
we need to parse /proc/pid/maps, compel will do it, but
since criu already parses this file (to dump task vmas),
we can provide the address via ictx.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
criu/cr-exec.c | 4 +++-
criu/cr-restore.c | 2 +-
criu/include/parasite-syscall.h | 4 ++--
criu/parasite-syscall.c | 17 ++++++++---------
4 files changed, 14 insertions(+), 13 deletions(-)
diff --git a/criu/cr-exec.c b/criu/cr-exec.c
index b00c35cbffe3..fc279f70d499 100644
--- a/criu/cr-exec.c
+++ b/criu/cr-exec.c
@@ -164,12 +164,14 @@ int cr_exec(int pid, char **opt)
goto out_unseize;
}
- ctl = parasite_prep_ctl(pid, p_start);
+ ctl = parasite_prep_ctl(pid);
if (!ctl) {
pr_err("Can't prep ctl %d\n", pid);
goto out_unseize;
}
+ ctl->ictx.syscall_ip = p_start;
+
si = find_syscall(sys_name, ctl);
if (!si) {
pr_err("Unknown syscall [%s]\n", sys_name);
diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index 4bf61a6e71de..218851b95c8f 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1646,7 +1646,7 @@ static void finalize_restore(void)
continue;
/* Unmap the restorer blob */
- ctl = parasite_prep_ctl(pid, 0);
+ ctl = parasite_prep_ctl(pid);
if (ctl == NULL)
continue;
diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 2c9619534b2e..b70282fc205a 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -37,6 +37,7 @@ struct infect_ctx {
int (*make_sigframe)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
void *regs_arg;
+ unsigned long syscall_ip; /* entry point of infection */
unsigned long flags; /* fine-tune (e.g. faults) */
void (*child_handler)(int, siginfo_t *, void *); /* hander for SIGCHLD deaths */
@@ -67,7 +68,6 @@ struct parasite_ctl {
void *r_thread_stack; /* stack for non-leader threads */
unsigned long parasite_ip; /* service routine start ip */
- unsigned long syscall_ip; /* entry point of infection */
unsigned int *addr_cmd; /* addr for command */
void *addr_args; /* address for arguments */
@@ -122,7 +122,7 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
struct vm_area_list *vma_area_list);
extern void parasite_ensure_args_size(unsigned long sz);
extern unsigned long get_exec_start(struct vm_area_list *);
-extern struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start);
+extern struct parasite_ctl *parasite_prep_ctl(pid_t pid);
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);
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 3ca9b75389c8..6f61badded94 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -224,18 +224,18 @@ int __parasite_execute_syscall(struct parasite_ctl *ctl,
* we will need it to restore original program content.
*/
memcpy(code_orig, code_syscall, sizeof(code_orig));
- if (ptrace_swap_area(pid, (void *)ctl->syscall_ip,
+ if (ptrace_swap_area(pid, (void *)ctl->ictx.syscall_ip,
(void *)code_orig, sizeof(code_orig))) {
pr_err("Can't inject syscall blob (pid: %d)\n", pid);
return -1;
}
- err = parasite_run(pid, PTRACE_CONT, ctl->syscall_ip, 0, regs, &ctl->orig);
+ err = parasite_run(pid, PTRACE_CONT, ctl->ictx.syscall_ip, 0, regs, &ctl->orig);
if (!err)
err = parasite_trap(ctl, pid, regs, &ctl->orig);
if (ptrace_poke_area(pid, (void *)code_orig,
- (void *)ctl->syscall_ip, sizeof(code_orig))) {
+ (void *)ctl->ictx.syscall_ip, sizeof(code_orig))) {
pr_err("Can't restore syscall blob (pid: %d)\n", ctl->rpid);
err = -1;
}
@@ -1244,7 +1244,7 @@ err:
}
/* If vma_area_list is NULL, a place for injecting syscall will not be set. */
-struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start)
+struct parasite_ctl *parasite_prep_ctl(pid_t pid)
{
struct parasite_ctl *ctl = NULL;
@@ -1266,9 +1266,6 @@ struct parasite_ctl *parasite_prep_ctl(pid_t pid, unsigned long exec_start)
BUILD_BUG_ON(PARASITE_START_AREA_MIN < BUILTIN_SYSCALL_SIZE + MEMFD_FNAME_SZ);
- ctl->syscall_ip = exec_start;
- pr_debug("Parasite syscall_ip at %p\n", (void *)ctl->syscall_ip);
-
return ctl;
err:
@@ -1310,7 +1307,7 @@ static int parasite_mmap_exchange(struct parasite_ctl *ctl, unsigned long size)
static int parasite_memfd_exchange(struct parasite_ctl *ctl, unsigned long size)
{
- void *where = (void *)ctl->syscall_ip + BUILTIN_SYSCALL_SIZE;
+ void *where = (void *)ctl->ictx.syscall_ip + BUILTIN_SYSCALL_SIZE;
u8 orig_code[MEMFD_FNAME_SZ] = MEMFD_FNAME;
pid_t pid = ctl->rpid;
unsigned long sret = -ENOSYS;
@@ -1482,7 +1479,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
return NULL;
}
- ctl = parasite_prep_ctl(pid, p);
+ ctl = parasite_prep_ctl(pid);
if (!ctl)
return NULL;
@@ -1491,6 +1488,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
ctl->ictx.save_regs = save_task_regs;
ctl->ictx.make_sigframe = make_sigframe;
ctl->ictx.regs_arg = item->core[0];
+ ctl->ictx.syscall_ip = p;
+ pr_debug("Parasite syscall_ip at %#lx\n", p);
if (fault_injected(FI_NO_MEMFD))
ctl->ictx.flags |= INFECT_NO_MEMFD;
--
2.7.4
More information about the CRIU
mailing list