[6/7] infect: Add registers keeping on infect_ctx

Submitted by Pavel Emelianov on Sept. 26, 2016, 10:20 a.m.

Details

Message ID 57E8F688.7050900@virtuozzo.com
State Superseded
Series "Prepare parasite_infect_seized() for compel-ization"
Headers show

Commit Message

Pavel Emelianov Sept. 26, 2016, 10:20 a.m.
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@virtuozzo.com>
---
 criu/include/parasite-syscall.h |  8 ++++++++
 criu/parasite-syscall.c         | 17 +++++++++++++----
 2 files changed, 21 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/parasite-syscall.h b/criu/include/parasite-syscall.h
index 37bda6d..e534db4 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,13 @@  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;
 };
 
 /* parasite control block */
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index bbbcb0c..e480437 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -1424,9 +1424,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->pid.real;
+	struct infect_ctx *ictx = &ctl->ictx;
 
 	/*
 	 * Get task registers before going daemon, since the
@@ -1434,12 +1435,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))
@@ -1463,6 +1464,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)
 {
@@ -1483,6 +1489,9 @@  struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		return NULL;
 
 	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];
 
 	parasite_ensure_args_size(dump_pages_args_size(vma_area_list));
 	parasite_ensure_args_size(aio_rings_args_size(vma_area_list));
@@ -1539,7 +1548,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;