[CRIU] [PATCH 4/5] parasite: remove struct parasite_thread_ctl

Andrey Vagin avagin at openvz.org
Mon May 27 08:38:52 EDT 2013


It was required for daemonized threads.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 arch/arm/crtools.c         |   4 +-
 arch/x86/crtools.c         |   4 +-
 cr-exec.c                  |   2 +-
 include/parasite-syscall.h |  30 ++++-----
 include/parasite.h         |   4 --
 parasite-syscall.c         | 159 ++++++++++++---------------------------------
 6 files changed, 60 insertions(+), 143 deletions(-)

diff --git a/arch/arm/crtools.c b/arch/arm/crtools.c
index ae92043..031fb81 100644
--- a/arch/arm/crtools.c
+++ b/arch/arm/crtools.c
@@ -65,7 +65,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 		unsigned long arg5,
 		unsigned long arg6)
 {
-	user_regs_struct_t regs = ctl->threads[0].regs_orig;
+	user_regs_struct_t regs = ctl->regs_orig;
 	int err;
 
 	regs.ARM_r7 = (unsigned long)nr;
@@ -78,7 +78,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 
 	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
 	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
-					&ctl->threads[0].regs_orig, 0);
+					&ctl->regs_orig, 0);
 	if (err)
 		return err;
 
diff --git a/arch/x86/crtools.c b/arch/x86/crtools.c
index dbcb0da..bab502a 100644
--- a/arch/x86/crtools.c
+++ b/arch/x86/crtools.c
@@ -89,7 +89,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 		unsigned long arg5,
 		unsigned long arg6)
 {
-	user_regs_struct_t regs = ctl->threads[0].regs_orig;
+	user_regs_struct_t regs = ctl->regs_orig;
 	int err;
 
 	regs.ax  = (unsigned long)nr;
@@ -102,7 +102,7 @@ int syscall_seized(struct parasite_ctl *ctl, int nr, unsigned long *ret,
 
 	parasite_setup_regs(ctl->syscall_ip, 0, &regs);
 	err = __parasite_execute_trap(ctl, ctl->pid.real, &regs,
-					&ctl->threads[0].regs_orig, 0);
+					&ctl->regs_orig, 0);
 	if (err)
 		return err;
 
diff --git a/cr-exec.c b/cr-exec.c
index c2e3bea..bfd4a5e 100644
--- a/cr-exec.c
+++ b/cr-exec.c
@@ -110,7 +110,7 @@ int cr_exec(int pid, char **opt)
 		goto out_unseize;
 	}
 
-	ctl = parasite_prep_ctl(pid, &vmas, 1);
+	ctl = parasite_prep_ctl(pid, &vmas);
 	if (!ctl) {
 		pr_err("Can't prep ctl %d\n", pid);
 		goto out_unseize;
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index bb88fa8..4a41228 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -5,19 +5,6 @@
 
 #include "pstree.h"
 
-struct parasite_thread_ctl
-{
-	pid_t			tid;
-	user_regs_struct_t	regs_orig;				/* original registers */
-
-	k_rtsigset_t		sig_blocked;
-	bool			use_sig_blocked;
-
-	void			*rstack;
-	struct rt_sigframe	*sigframe;
-	struct rt_sigframe	*rsigframe;				/* address in a parasite */
-};
-
 /* parasite control block */
 struct parasite_ctl {
 	struct pid		pid;
@@ -25,7 +12,18 @@ struct parasite_ctl {
 	void			*local_map;
 	unsigned long		map_length;
 
+	/* thread leader data */
 	bool			daemonized;
+	user_regs_struct_t	regs_orig;				/* original registers */
+
+	k_rtsigset_t		sig_blocked;
+	bool			use_sig_blocked;
+
+	void			*rstack;				/* thread leader stack*/
+	struct rt_sigframe	*sigframe;
+	struct rt_sigframe	*rsigframe;				/* address in a parasite */
+
+	void			*r_thread_stack;			/* stack for non-leader threads */
 
 	unsigned long		parasite_ip;				/* service routine start ip */
 	unsigned long		syscall_ip;				/* entry point of infection */
@@ -38,9 +36,6 @@ struct parasite_ctl {
 
 	struct list_head	pre_list;
 	struct page_pipe	*mem_pp;
-
-	int			nr_threads;
-	struct parasite_thread_ctl threads[0];
 };
 
 struct cr_fdset;
@@ -84,8 +79,7 @@ extern struct parasite_ctl *parasite_infect_seized(pid_t pid,
 						   struct vm_area_list *vma_area_list,
 						   struct parasite_drain_fd *dfds);
 extern struct parasite_ctl *parasite_prep_ctl(pid_t pid,
-					      struct vm_area_list *vma_area_list,
-					      unsigned int nr_threads);
+					      struct vm_area_list *vma_area_list);
 extern int parasite_map_exchange(struct parasite_ctl *ctl, unsigned long size);
 
 extern struct parasite_tty_args *parasite_dump_tty(struct parasite_ctl *ctl, int fd);
diff --git a/include/parasite.h b/include/parasite.h
index 8fae002..0e5720f 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -63,16 +63,12 @@ struct ctl_msg {
 	(struct ctl_msg){.cmd = _cmd, .ack = _cmd, .err = _err, }
 
 struct parasite_init_args {
-	int			id;
-
 	int			h_addr_len;
 	struct sockaddr_un	h_addr;
 
 	int			p_addr_len;
 	struct sockaddr_un	p_addr;
 
-	int			nr_threads;
-
 	k_rtsigset_t		sig_blocked;
 
 	struct rt_sigframe	*sigframe;
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 6397394..258be82 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -230,21 +230,10 @@ static int parasite_execute_trap_by_pid(unsigned int cmd,
 	return ret;
 }
 
-static int parasite_execute_trap_by_id(unsigned int cmd, struct parasite_ctl *ctl, int id)
-{
-	struct parasite_thread_ctl *thread = &ctl->threads[id];
-	pid_t pid = thread->tid;
-	int ret;
-
-	ret = parasite_execute_trap_by_pid(cmd, ctl, pid, &thread->regs_orig,
-					thread->rstack, thread->use_sig_blocked);
-
-	return ret;
-}
-
 static int parasite_execute_trap(unsigned int cmd, struct parasite_ctl *ctl)
 {
-	return parasite_execute_trap_by_id(cmd, ctl, 0);
+	return parasite_execute_trap_by_pid(cmd, ctl, ctl->pid.real, &ctl->regs_orig,
+					ctl->rstack, ctl->use_sig_blocked);
 }
 
 static int __parasite_send_cmd(int sockfd, struct ctl_msg *m)
@@ -395,9 +384,7 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
 	pr_info("Putting tsock into pid %d\n", pid);
 	args->h_addr_len = gen_parasite_saddr(&args->h_addr, getpid());
 	args->p_addr_len = gen_parasite_saddr(&args->p_addr, pid);
-	args->nr_threads = nr_threads;
-	args->sigframe = ctl->threads[0].rsigframe;
-	args->id = 0;
+	args->sigframe = ctl->rsigframe;
 
 	if (sock == -1) {
 		int rst = -1;
@@ -444,8 +431,8 @@ static int parasite_init(struct parasite_ctl *ctl, pid_t pid, int nr_threads)
 		goto err;
 	}
 
-	ctl->threads[0].sig_blocked = args->sig_blocked;
-	ctl->threads[0].use_sig_blocked = true;
+	ctl->sig_blocked = args->sig_blocked;
+	ctl->use_sig_blocked = true;
 
 	if (connect(sock, (struct sockaddr *)&args->p_addr, args->p_addr_len) < 0) {
 		pr_perror("Can't connect a transport socket");
@@ -459,21 +446,16 @@ err:
 	return -1;
 }
 
-static int parasite_daemonize(struct parasite_ctl *ctl, int id)
+static int parasite_daemonize(struct parasite_ctl *ctl)
 {
-	struct parasite_thread_ctl *thread = &ctl->threads[id];
-	pid_t pid = thread->tid;
+	pid_t pid = ctl->pid.real;
 	user_regs_struct_t regs;
 	struct ctl_msg m = { };
-	struct parasite_init_args *args;
 
 	*ctl->addr_cmd = PARASITE_CMD_DAEMONIZE;
 
-	args = parasite_args(ctl, struct parasite_init_args);
-	args->id = id;
-
-	regs = thread->regs_orig;
-	parasite_setup_regs(ctl->parasite_ip, thread->rstack, &regs);
+	regs = ctl->regs_orig;
+	parasite_setup_regs(ctl->parasite_ip, ctl->rstack, &regs);
 
 	if (ptrace(PTRACE_SETREGS, pid, NULL, &regs)) {
 		pr_perror("Can't set registers (pid: %d)", pid);
@@ -482,7 +464,7 @@ static int parasite_daemonize(struct parasite_ctl *ctl, int id)
 
 	if (ptrace(PTRACE_CONT, pid, NULL, NULL)) {
 		pr_perror("Can't continue (pid: %d)\n", pid);
-		ptrace(PTRACE_SETREGS, pid, NULL, thread->regs_orig);
+		ptrace(PTRACE_SETREGS, pid, NULL, ctl->regs_orig);
 		goto err;
 	}
 
@@ -525,7 +507,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
 
 		ret = parasite_execute_trap_by_pid(PARASITE_CMD_INIT_THREAD, ctl,
 						pid, &regs_orig,
-						ctl->threads[id].rstack, false);
+						ctl->r_thread_stack, false);
 		if (ret) {
 			pr_err("Can't init thread in parasite %d\n", pid);
 			return -1;
@@ -537,7 +519,7 @@ int parasite_dump_thread_seized(struct parasite_ctl *ctl, int id,
 
 		if (parasite_execute_trap_by_pid(PARASITE_CMD_FINI_THREAD, ctl,
 						pid, &regs_orig,
-						ctl->threads[id].rstack, true)) {
+						ctl->r_thread_stack, true)) {
 			pr_err("Can't init thread in parasite %d\n", pid);
 			return -1;
 		}
@@ -834,53 +816,6 @@ int parasite_get_proc_fd_seized(struct parasite_ctl *ctl)
 	return fd;
 }
 
-int parasite_init_threads_seized(struct parasite_ctl *ctl, struct pstree_item *item)
-{
-	struct parasite_init_args *args;
-	int ret = 0, i;
-
-	args = parasite_args(ctl, struct parasite_init_args);
-
-	for (i = 1; i < item->nr_threads; i++) {
-		pid_t tid = item->threads[i].real;
-		user_regs_struct_t *regs_orig = &ctl->threads[i].regs_orig;
-
-		ctl->threads[i].tid = tid;
-		ctl->nr_threads++;
-
-		args->id = i;
-		args->sigframe = ctl->threads[i].rsigframe;
-
-		ret = ptrace(PTRACE_GETREGS, tid, NULL, regs_orig);
-		if (ret) {
-			pr_perror("Can't obtain registers (pid: %d)", tid);
-			goto err;
-		}
-
-		ret = parasite_execute_trap_by_id(PARASITE_CMD_INIT_THREAD, ctl, i);
-		if (ret) {
-			pr_err("Can't init thread in parasite %d\n", tid);
-			goto err;
-		}
-
-		ret = get_task_regs(tid, *regs_orig, item->core[i]);
-		if (ret) {
-			pr_err("Can't obtain regs for thread %d\n", tid);
-			goto err;
-		}
-
-		ctl->threads[i].sig_blocked = args->sig_blocked;
-		ctl->threads[i].use_sig_blocked = true;
-
-		if (parasite_daemonize(ctl, i))
-			goto err;
-	}
-
-	return 0;
-err:
-	return -1 ;
-}
-
 static int parasite_fini_seized(struct parasite_ctl *ctl)
 {
 	pid_t pid = ctl->pid.real;
@@ -949,7 +884,7 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
 		}
 	}
 
-	ctl->threads[0].use_sig_blocked = false;
+	ctl->use_sig_blocked = false;
 
 	ret = ptrace(PTRACE_SYSCALL, pid, NULL, NULL);
 	if (ret) {
@@ -994,7 +929,7 @@ int parasite_cure_remote(struct parasite_ctl *ctl)
 		ret = -1;
 	}
 
-	if (ptrace(PTRACE_SETREGS, ctl->pid.real, NULL, &ctl->threads[0].regs_orig)) {
+	if (ptrace(PTRACE_SETREGS, ctl->pid.real, NULL, &ctl->regs_orig)) {
 		pr_err("Can't restore registers (pid: %d)\n", ctl->pid.real);
 		ret = -1;
 	}
@@ -1028,35 +963,31 @@ int parasite_cure_seized(struct parasite_ctl *ctl)
 	return ret;
 }
 
-struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list, unsigned int nr_threads)
+struct parasite_ctl *parasite_prep_ctl(pid_t pid, struct vm_area_list *vma_area_list)
 {
 	struct parasite_ctl *ctl = NULL;
 	struct vma_area *vma_area;
 
-	BUG_ON(nr_threads == 0);
-
 	if (!arch_can_dump_task(pid))
 		goto err;
 
 	/*
 	 * Control block early setup.
 	 */
-	ctl = xzalloc(sizeof(*ctl) + nr_threads * sizeof(ctl->threads[0]));
+	ctl = xzalloc(sizeof(*ctl));
 	if (!ctl) {
 		pr_err("Parasite control block allocation failed (pid: %d)\n", pid);
 		goto err;
 	}
 
 	ctl->tsock = -1;
-	ctl->nr_threads = 1;
-	ctl->threads[0].tid = pid;
 
-	if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->threads[0].regs_orig)) {
+	if (ptrace(PTRACE_GETREGS, pid, NULL, &ctl->regs_orig)) {
 		pr_err("Can't obtain registers (pid: %d)\n", pid);
 		goto err;
 	}
 
-	vma_area = get_vma_by_ip(&vma_area_list->h, REG_IP(ctl->threads[0].regs_orig));
+	vma_area = get_vma_by_ip(&vma_area_list->h, REG_IP(ctl->regs_orig));
 	if (!vma_area) {
 		pr_err("No suitable VMA found to run parasite "
 		       "bootstrap code (pid: %d)\n", pid);
@@ -1131,16 +1062,16 @@ static unsigned long parasite_args_size(struct vm_area_list *vmas, struct parasi
 struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		struct vm_area_list *vma_area_list, struct parasite_drain_fd *dfds)
 {
-	int ret, i;
+	int ret;
 	struct parasite_ctl *ctl;
-	unsigned long p;
+	unsigned long p, map_exchange_size;
 
 	BUG_ON(item->threads[0].real != pid);
 
 	if (pstree_alloc_cores(item))
 		return NULL;
 
-	ctl = parasite_prep_ctl(pid, vma_area_list, item->nr_threads);
+	ctl = parasite_prep_ctl(pid, vma_area_list);
 	if (!ctl)
 		return NULL;
 
@@ -1152,9 +1083,11 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	 */
 
 	ctl->args_size = parasite_args_size(vma_area_list, dfds);
-	ret = parasite_map_exchange(ctl, parasite_size + ctl->args_size +
-					 item->nr_threads * RESTORE_STACK_SIGFRAME +
-					 item->nr_threads * PARASITE_STACK_SIZE);
+	map_exchange_size = parasite_size + ctl->args_size;
+	map_exchange_size += RESTORE_STACK_SIGFRAME + PARASITE_STACK_SIZE;
+	if (item->nr_threads > 1)
+		map_exchange_size += PARASITE_STACK_SIZE;
+	ret = parasite_map_exchange(ctl, map_exchange_size);
 	if (ret)
 		goto err_restore;
 
@@ -1167,14 +1100,18 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 	ctl->addr_args		= parasite_sym(ctl->local_map, __export_parasite_args);
 
 	p = parasite_size + ctl->args_size;
-	for (i = 0; i < item->nr_threads; i++) {
-		struct parasite_thread_ctl *thread = &ctl->threads[i];
 
-		thread->rstack		= ctl->remote_map + p;
-		thread->rsigframe	= ctl->remote_map + p + PARASITE_STACK_SIZE;
-		thread->sigframe	= ctl->local_map  + p + PARASITE_STACK_SIZE;
+	ctl->rsigframe	= ctl->remote_map + p;
+	ctl->sigframe	= ctl->local_map  + p;
+
+	p += RESTORE_STACK_SIGFRAME;
+
+	ctl->rstack = ctl->remote_map + p;
+	p += PARASITE_STACK_SIZE;
 
-		p += PARASITE_STACK_SIZE + RESTORE_STACK_SIGFRAME;
+	if (item->nr_threads > 1) {
+		ctl->r_thread_stack = ctl->remote_map + p;
+		p += PARASITE_STACK_SIZE;
 	}
 
 	ret = parasite_init(ctl, pid, item->nr_threads);
@@ -1183,7 +1120,7 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		goto err_restore;
 	}
 
-	ret = get_task_regs(pid, ctl->threads[0].regs_orig, item->core[0]);
+	ret = get_task_regs(pid, ctl->regs_orig, item->core[0]);
 	if (ret) {
 		pr_err("Can't obtain regs for thread %d\n", pid);
 		goto err_restore;
@@ -1195,24 +1132,14 @@ struct parasite_ctl *parasite_infect_seized(pid_t pid, struct pstree_item *item,
 		goto err_restore;
 	}
 
-	if (parasite_daemonize(ctl, 0))
-		goto err_restore;
-
-	for (i = 0; i < 1; i++) {
-		struct parasite_thread_ctl *thread = &ctl->threads[0];
+	memcpy(&item->core[0]->tc->blk_sigset,
+		&ctl->sig_blocked, sizeof(k_rtsigset_t));
 
-		if (i == 0)
-			memcpy(&item->core[i]->tc->blk_sigset,
-				&thread->sig_blocked, sizeof(k_rtsigset_t));
-		else {
-			memcpy(&item->core[i]->thread_core->blk_sigset,
-				&thread->sig_blocked, sizeof(k_rtsigset_t));
-			item->core[i]->thread_core->has_blk_sigset = true;
-		}
+	if (construct_sigframe(ctl->sigframe, ctl->rsigframe, item->core[0]))
+		goto err_restore;
 
-		if (construct_sigframe(thread->sigframe, thread->rsigframe, item->core[i]))
-			goto err_restore;
-	}
+	if (parasite_daemonize(ctl))
+		goto err_restore;
 
 	return ctl;
 
-- 
1.8.2



More information about the CRIU mailing list