[CRIU] [PATCH 2/8] compel: Introduce parasite_thread_ctl
Pavel Emelyanov
xemul at virtuozzo.com
Mon Nov 14 05:05:08 PST 2016
The structure is opaque hander for thread infection.
Signed-off-by: Pavel Emelyanov <xemul at virtuozzo.com>
---
compel/include/uapi/infect.h | 11 ++++++++---
compel/src/lib/infect.c | 42 +++++++++++++++++++++++++++++++++++++-----
criu/parasite-syscall.c | 24 +++++++++++++++---------
3 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/compel/include/uapi/infect.h b/compel/include/uapi/infect.h
index c444a6e..d7ef921 100644
--- a/compel/include/uapi/infect.h
+++ b/compel/include/uapi/infect.h
@@ -42,9 +42,14 @@ struct thread_ctx {
user_regs_struct_t regs;
};
+struct parasite_thread_ctl {
+ struct thread_ctx th;
+};
+
extern struct parasite_ctl *compel_prepare(int pid);
extern int compel_infect(struct parasite_ctl *ctl, unsigned long nr_threads, unsigned long args_size);
-extern int compel_prepare_thread(int pid, struct thread_ctx *ctx);
+extern struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid);
+extern void compel_release_thread(struct parasite_thread_ctl *);
extern int compel_stop_daemon(struct parasite_ctl *ctl);
extern int compel_cure_remote(struct parasite_ctl *ctl);
@@ -68,7 +73,7 @@ extern int compel_execute_syscall(struct parasite_ctl *ctl,
user_regs_struct_t *regs, const char *code_syscall);
extern int compel_run_in_thread(pid_t pid, unsigned int cmd,
struct parasite_ctl *ctl,
- struct thread_ctx *octx);
+ struct parasite_thread_ctl *tctl);
/*
* The PTRACE_SYSCALL will trap task twice -- on
@@ -92,7 +97,7 @@ extern int compel_unmap(struct parasite_ctl *ctl, unsigned long addr);
extern int compel_mode_native(struct parasite_ctl *ctl);
extern k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl);
-extern k_rtsigset_t *compel_thread_sigmask(struct thread_ctx *tctx);
+extern k_rtsigset_t *compel_thread_sigmask(struct parasite_thread_ctl *tctl);
struct rt_sigframe;
diff --git a/compel/src/lib/infect.c b/compel/src/lib/infect.c
index ff2140d..a3e0241 100644
--- a/compel/src/lib/infect.c
+++ b/compel/src/lib/infect.c
@@ -45,6 +45,8 @@
#define SI_EVENT(_si_code) (((_si_code) & 0xFFFF) >> 8)
+static int prepare_thread(int pid, struct thread_ctx *ctx);
+
static inline void close_safe(int *pfd)
{
if (*pfd > -1) {
@@ -836,7 +838,22 @@ err:
return -1;
}
-int compel_prepare_thread(int pid, struct thread_ctx *ctx)
+struct parasite_thread_ctl *compel_prepare_thread(struct parasite_ctl *ctl, int pid)
+{
+ struct parasite_thread_ctl *tctl;
+
+ tctl = xmalloc(sizeof(*tctl));
+ if (tctl) {
+ if (prepare_thread(pid, &tctl->th)) {
+ xfree(tctl);
+ tctl = NULL;
+ }
+ }
+
+ return tctl;
+}
+
+static int prepare_thread(int pid, struct thread_ctx *ctx)
{
if (ptrace(PTRACE_GETSIGMASK, pid, sizeof(k_rtsigset_t), &ctx->sigmask)) {
pr_perror("can't get signal blocking mask for %d", pid);
@@ -851,6 +868,15 @@ int compel_prepare_thread(int pid, struct thread_ctx *ctx)
return 0;
}
+void compel_release_thread(struct parasite_thread_ctl *tctl)
+{
+ /*
+ * No stuff to cure in thread here, all routines leave the
+ * guy intact (for now)
+ */
+ xfree(tctl);
+}
+
struct parasite_ctl *compel_prepare(int pid)
{
struct parasite_ctl *ctl = NULL;
@@ -867,7 +893,7 @@ struct parasite_ctl *compel_prepare(int pid)
ctl->tsock = -1;
ctl->ictx.log_fd = -1;
- if (compel_prepare_thread(pid, &ctl->orig))
+ if (prepare_thread(pid, &ctl->orig))
goto err;
ctl->rpid = pid;
@@ -1050,8 +1076,9 @@ void *compel_parasite_args_s(struct parasite_ctl *ctl, int args_size)
int compel_run_in_thread(pid_t pid, unsigned int cmd,
struct parasite_ctl *ctl,
- struct thread_ctx *octx)
+ struct parasite_thread_ctl *tctl)
{
+ struct thread_ctx *octx = &tctl->th;
void *stack = ctl->r_thread_stack;
user_regs_struct_t regs = octx->regs;
int ret;
@@ -1246,14 +1273,19 @@ int compel_mode_native(struct parasite_ctl *ctl)
return user_regs_native(&ctl->orig.regs);
}
-k_rtsigset_t *compel_thread_sigmask(struct thread_ctx *tctx)
+static inline k_rtsigset_t *thread_ctx_sigmask(struct thread_ctx *tctx)
{
return &tctx->sigmask;
}
+k_rtsigset_t *compel_thread_sigmask(struct parasite_thread_ctl *tctl)
+{
+ return thread_ctx_sigmask(&tctl->th);
+}
+
k_rtsigset_t *compel_task_sigmask(struct parasite_ctl *ctl)
{
- return compel_thread_sigmask(&ctl->orig);
+ return thread_ctx_sigmask(&ctl->orig);
}
struct infect_ctx *compel_infect_ctx(struct parasite_ctl *ctl)
diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c
index f35b71d..4b265f1 100644
--- a/criu/parasite-syscall.c
+++ b/criu/parasite-syscall.c
@@ -182,7 +182,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
CredsEntry *creds = tc->creds;
struct parasite_dump_creds *pc;
int ret;
- struct thread_ctx octx;
+ struct parasite_thread_ctl *tctl;
BUG_ON(id == 0); /* Leader is dumped in dump_task_core_all */
@@ -196,31 +196,33 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
pc->cap_last_cap = kdat.last_cap;
- ret = compel_prepare_thread(pid, &octx);
- if (ret)
+ tctl = compel_prepare_thread(ctl, pid);
+ if (!tctl)
return -1;
tc->has_blk_sigset = true;
- memcpy(&tc->blk_sigset, compel_thread_sigmask(&octx), sizeof(k_rtsigset_t));
+ memcpy(&tc->blk_sigset, compel_thread_sigmask(tctl), sizeof(k_rtsigset_t));
- ret = compel_run_in_thread(pid, PARASITE_CMD_DUMP_THREAD, ctl, &octx);
+ ret = compel_run_in_thread(pid, PARASITE_CMD_DUMP_THREAD, ctl, tctl);
if (ret) {
pr_err("Can't init thread in parasite %d\n", pid);
- return -1;
+ goto err_rth;
}
ret = alloc_groups_copy_creds(creds, pc);
if (ret) {
pr_err("Can't copy creds for thread %d\n", pid);
- return -1;
+ goto err_rth;
}
- ret = compel_get_task_regs(pid, octx.regs, save_task_regs, core);
+ ret = compel_get_task_regs(pid, tctl->th.regs, save_task_regs, core);
if (ret) {
pr_err("Can't obtain regs for thread %d\n", pid);
- return -1;
+ goto err_rth;
}
+ compel_release_thread(tctl);
+
if (compel_mode_native(ctl)) {
tid->virt = args->tid;
return dump_thread_core(pid, core, true, args);
@@ -228,6 +230,10 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
tid->virt = args_c->tid;
return dump_thread_core(pid, core, false, args_c);
}
+
+err_rth:
+ compel_release_thread(tctl);
+ return -1;
}
#define ASSIGN_SAS(se, args) \
--
2.5.0
More information about the CRIU
mailing list