[CRIU] [PATCH 12/78] infect: Add registers keeping on infect_ctx

Cyrill Gorcunov gorcunov at openvz.org
Mon Nov 7 08:35:57 PST 2016


From: Pavel Emelyanov <xemul at virtuozzo.com>

Two calls -- to keep the registers and to put them back onto
sigframe. For CRIU the keeping is performed on CoreEntry.

Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
 criu/include/parasite-syscall.h |  9 +++++++++
 criu/parasite-syscall.c         | 17 +++++++++++++----
 2 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index d0ab8c61d56f..2c9619534b2e 100644
--- a/criu/include/parasite-syscall.h
+++ b/criu/include/parasite-syscall.h
@@ -20,6 +20,7 @@ struct cr_imgset;
 struct fd_opts;
 struct pid;
 struct parasite_dump_cgroup_args;
+struct rt_sigframe;
 
 struct thread_ctx {
 	k_rtsigset_t		sigmask;
@@ -28,6 +29,14 @@ struct thread_ctx {
 
 struct infect_ctx {
 	int	*p_sock;
+
+	/*
+	 * Regs manipulation context.
+	 */
+	int (*save_regs)(void *, user_regs_struct_t *, user_fpregs_struct_t *);
+	int (*make_sigframe)(void *, struct rt_sigframe *, struct rt_sigframe *, k_rtsigset_t *);
+	void *regs_arg;
+
 	unsigned long		flags;			/* fine-tune (e.g. faults) */
 
 	void (*child_handler)(int, siginfo_t *, void *);	/* hander for SIGCHLD deaths */
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index 55ef1169d57e..3ca9b75389c8 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -1422,9 +1422,10 @@ void parasite_ensure_args_size(unsigned long sz)
 		parasite_args_size = sz;
 }
 
-static int parasite_start_daemon(struct parasite_ctl *ctl, struct pstree_item *item)
+static int parasite_start_daemon(struct parasite_ctl *ctl)
 {
 	pid_t pid = ctl->rpid;
+	struct infect_ctx *ictx = &ctl->ictx;
 
 	/*
 	 * Get task registers before going daemon, since the
@@ -1432,12 +1433,12 @@ static int parasite_start_daemon(struct parasite_ctl *ctl, struct pstree_item *i
 	 * while in daemon it is not such.
 	 */
 
-	if (get_task_regs(pid, ctl->orig.regs, save_task_regs, item->core[0])) {
+	if (get_task_regs(pid, ctl->orig.regs, ictx->save_regs, ictx->regs_arg)) {
 		pr_err("Can't obtain regs for thread %d\n", pid);
 		return -1;
 	}
 
-	if (construct_sigframe(ctl->sigframe, ctl->rsigframe, &ctl->orig.sigmask, item->core[0]))
+	if (ictx->make_sigframe(ictx->regs_arg, ctl->sigframe, ctl->rsigframe, &ctl->orig.sigmask))
 		return -1;
 
 	if (parasite_init_daemon(ctl))
@@ -1461,6 +1462,11 @@ static int parasite_start_daemon(struct parasite_ctl *ctl, struct pstree_item *i
 		__export_parasite_args);				\
 	} while (0)
 
+static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe *rtsf, k_rtsigset_t *bs)
+{
+	return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg);
+}
+
 struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		struct vm_area_list *vma_area_list)
 {
@@ -1482,6 +1488,9 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 
 	ctl->ictx.child_handler = sigchld_handler;
 	ctl->ictx.p_sock = &dmpi(item)->netns->net.seqsk;
+	ctl->ictx.save_regs = save_task_regs;
+	ctl->ictx.make_sigframe = make_sigframe;
+	ctl->ictx.regs_arg = item->core[0];
 
 	if (fault_injected(FI_NO_MEMFD))
 		ctl->ictx.flags |= INFECT_NO_MEMFD;
@@ -1545,7 +1554,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		ctl->r_thread_stack = ctl->remote_map + p;
 	}
 
-	if (parasite_start_daemon(ctl, item))
+	if (parasite_start_daemon(ctl))
 		goto err_restore;
 
 	dmpi(item)->parasite_ctl = ctl;
-- 
2.7.4



More information about the CRIU mailing list