[CRIU] [PATCH 2/5] parasite: don't daemonize threads
Andrey Vagin
avagin at openvz.org
Mon May 27 08:38:50 EDT 2013
For dumping thread we need to execute only one command, so its
demonization is overload.
Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
parasite-syscall.c | 46 +++++++++++++++++++++++++++++++++++++++-------
pie/parasite.c | 44 ++++++++++++++++++++++++++++++++++++++++----
2 files changed, 79 insertions(+), 11 deletions(-)
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 612e8d1..63e8815 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -516,7 +516,43 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
args = parasite_args(ctl, struct parasite_dump_thread);
args->id = id;
- ret = parasite_execute_daemon_by_id(PARASITE_CMD_DUMP_THREAD, ctl, id);
+ if (id == 0)
+ ret = parasite_execute_daemon(PARASITE_CMD_DUMP_THREAD, ctl);
+ else {
+ pid_t pid = tid->real;
+ user_regs_struct_t regs_orig;
+
+ ret = ptrace(PTRACE_GETREGS, pid, NULL, ®s_orig);
+ if (ret) {
+ pr_perror("Can't obtain registers (pid: %d)", pid);
+ return -1;
+ }
+
+ ret = parasite_execute_trap_by_pid(PARASITE_CMD_INIT_THREAD, ctl,
+ pid, ®s_orig,
+ ctl->threads[id].rstack, false);
+ if (ret) {
+ pr_err("Can't init thread in parasite %d\n", pid);
+ return -1;
+ }
+
+ ret = get_task_regs(pid, regs_orig, core);
+ if (ret)
+ pr_err("Can't obtain regs for thread %d\n", pid);
+
+ if (parasite_execute_trap_by_pid(PARASITE_CMD_FINI_THREAD, ctl,
+ pid, ®s_orig,
+ ctl->threads[id].rstack, true)) {
+ pr_err("Can't init thread in parasite %d\n", pid);
+ return -1;
+ }
+ if (ret)
+ return -1;
+
+ memcpy(&core->thread_core->blk_sigset,
+ &args->blocked, sizeof(k_rtsigset_t));
+ core->thread_core->has_blk_sigset = true;
+ }
CORE_THREAD_ARCH_INFO(core)->clear_tid_addr = encode_pointer(args->tid_addr);
tid->virt = args->tid;
@@ -1185,12 +1221,8 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
if (parasite_daemonize(ctl, 0))
goto err_restore;
- ret = parasite_init_threads_seized(ctl, item);
- if (ret)
- goto err_restore;
-
- for (i = 0; i < item->nr_threads; i++) {
- struct parasite_thread_ctl *thread = &ctl->threads[i];
+ for (i = 0; i < 1; i++) {
+ struct parasite_thread_ctl *thread = &ctl->threads[0];
if (i == 0)
memcpy(&item->core[i]->tc->blk_sigset,
diff --git a/pie/parasite.c b/pie/parasite.c
index 3e01cc7..3dc8e73 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -192,7 +192,7 @@ static int dump_thread(struct parasite_dump_thread *args)
return 0;
}
-static int init_thread(struct parasite_init_args *args)
+static int init_daemon_thread(struct parasite_init_args *args)
{
k_rtsigset_t to_block;
int ret;
@@ -220,13 +220,47 @@ static int init_thread(struct parasite_init_args *args)
return ret;
}
+static int init_thread(struct parasite_dump_thread *args)
+{
+ k_rtsigset_t to_block;
+ pid_t tid = sys_gettid();
+ int ret;
+
+ ksigfillset(&to_block);
+ ret = sys_sigprocmask(SIG_SETMASK, &to_block,
+ &args->blocked,
+ sizeof(k_rtsigset_t));
+ if (ret)
+ return -1;
+
+ ret = sys_prctl(PR_GET_TID_ADDRESS, (unsigned long) &args->tid_addr, 0, 0, 0);
+ if (ret)
+ goto err;
+
+ args->tid = tid;
+ args->tls = arch_get_tls();
+
+
+ return ret;
+err:
+ sys_sigprocmask(SIG_SETMASK, &args->blocked,
+ NULL, sizeof(k_rtsigset_t));
+ return ret;
+}
+
+static int fini_thread(struct parasite_dump_thread *args)
+{
+ return sys_sigprocmask(SIG_SETMASK, &args->blocked,
+ NULL, sizeof(k_rtsigset_t));
+}
+
static void __parasite_daemon_thread_ack(struct tid_state_s *s, int ret)
{
s->ret = ret;
futex_set_and_wake(&s->cmd, PARASITE_CMD_IDLE);
}
-static int fini_thread(struct tid_state_s *s)
+static int fini_daemon_thread(struct tid_state_s *s)
{
unsigned long new_sp;
@@ -259,7 +293,7 @@ static int init(struct parasite_init_args *args)
nr_tid_state = args->nr_threads;
- ret = init_thread(args);
+ ret = init_daemon_thread(args);
if (ret < 0)
return ret;
@@ -494,7 +528,7 @@ __parasite_daemon_thread(void *args, struct tid_state_s *s)
ret = dump_thread(args);
break;
case PARASITE_CMD_FINI_THREAD:
- fini_thread(s);
+ fini_daemon_thread(s);
return;
default:
pr_err("Unknown command in parasite daemon thread: %d\n", cmd);
@@ -652,6 +686,8 @@ int __used parasite_service(unsigned int cmd, void *args)
return init(args);
case PARASITE_CMD_INIT_THREAD:
return init_thread(args);
+ case PARASITE_CMD_FINI_THREAD:
+ return fini_thread(args);
case PARASITE_CMD_CFG_LOG:
return parasite_cfg_log(args);
case PARASITE_CMD_DAEMONIZE:
--
1.8.2
More information about the CRIU
mailing list