[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, &regs_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, &regs_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, &regs_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