[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