From patchwork Mon Sep 26 10:21:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [7/7] infect: The big split From: Pavel Emelyanov X-Patchwork-Id: 1733 Message-Id: <57E8F696.60804@virtuozzo.com> To: CRIU Date: Mon, 26 Sep 2016 13:21:10 +0300 Now we can split the parasite_infect_seized() into CRIU-specific part and independent part that is to become compel code. The API to infect() is for now a bit clumsy, but I will rectify one a bit more in the next patches. Signed-off-by: Pavel Emelyanov --- criu/parasite-syscall.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index e480437..95e21aa 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -1469,12 +1469,13 @@ static int make_sigframe(void *arg, struct rt_sigframe *sf, struct rt_sigframe * return construct_sigframe(sf, rtsf, bs, (CoreEntry *)arg); } +static int infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size); + struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, struct vm_area_list *vma_area_list) { - int ret; struct parasite_ctl *ctl; - unsigned long p, map_exchange_size, parasite_size; + unsigned long p; BUG_ON(item->threads[0].real != pid); @@ -1496,6 +1497,23 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, parasite_ensure_args_size(dump_pages_args_size(vma_area_list)); parasite_ensure_args_size(aio_rings_args_size(vma_area_list)); + if (infect(ctl, item->nr_threads, parasite_args_size) < 0) { + parasite_cure_seized(ctl); + return NULL; + } + + parasite_args_size = PARASITE_ARG_SIZE_MIN; /* reset for next task */ + memcpy(&item->core[0]->tc->blk_sigset, &ctl->orig.sigmask, sizeof(k_rtsigset_t)); + dmpi(item)->parasite_ctl = ctl; + + return ctl; +} + +static int infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size) +{ + int ret; + unsigned long p, map_exchange_size, parasite_size; + /* * Inject a parasite engine. Ie allocate memory inside alien * space and copy engine code there. Then re-map the engine @@ -1510,20 +1528,17 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, parasite_size = pie_size(parasite_compat); #endif - ctl->args_size = round_up(parasite_args_size, PAGE_SIZE); - parasite_args_size = PARASITE_ARG_SIZE_MIN; /* reset for next task */ + ctl->args_size = round_up(args_size, PAGE_SIZE); parasite_size += ctl->args_size; map_exchange_size = parasite_size; map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE; - if (item->nr_threads > 1) + if (nr_threads > 1) map_exchange_size += PARASITE_STACK_SIZE; - memcpy(&item->core[0]->tc->blk_sigset, &ctl->orig.sigmask, sizeof(k_rtsigset_t)); - ret = parasite_map_exchange(ctl, map_exchange_size); if (ret) - goto err_restore; + goto err; pr_info("Putting parasite blob into %p->%p\n", ctl->local_map, ctl->remote_map); @@ -1543,21 +1558,18 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item, p += PARASITE_STACK_SIZE; ctl->rstack = ctl->remote_map + p; - if (item->nr_threads > 1) { + if (nr_threads > 1) { p += PARASITE_STACK_SIZE; ctl->r_thread_stack = ctl->remote_map + p; } if (parasite_start_daemon(ctl)) - goto err_restore; - - dmpi(item)->parasite_ctl = ctl; + goto err; - return ctl; + return 0; -err_restore: - parasite_cure_seized(ctl); - return NULL; +err: + return -1; } int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf)