[CRIU] [PATCH] parasite: Don't handle CHLD from trapping threads

Andrew Vagin avagin at parallels.com
Tue Oct 14 05:39:34 PDT 2014


On Tue, Oct 14, 2014 at 02:20:13PM +0400, Pavel Emelyanov wrote:
> When dumping threads we do parasite-trap them, instead of running
> in daemon mode. While doing this the sigchild handler notices the
> CHLD arriving on the thread trap, emits an error
> 
> (00.020292) Error (parasite-syscall.c:387): si_code=4 si_pid=3485 si_status=5
> 
> but wait() reports -1 (task is not dead, just trapped) and handler
> just exits.
> 
> Let's not confuse the log readers and just don't notice such CHLDs
> at all.

Let's stop parasite daemon before dumping threads.

> 
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
> ---
>  parasite-syscall.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/parasite-syscall.c b/parasite-syscall.c
> index 7cc1a84..e73fe07 100644
> --- a/parasite-syscall.c
> +++ b/parasite-syscall.c
> @@ -37,6 +37,16 @@
>  #include "asm/dump.h"
>  #include "asm/restorer.h"
>  
> +/*
> + * This is to tell sigchld_handler() that we're trapping a thread.
> + * We don't run this PARASITE_CMD_DUMP_THREAD in daemon mode, instead 
> + * we make it generate the trap, so we need to tell the handler that
> + * it doesn't care about the CHLD arrived -- we will handle errors in
> + * parasite_trap() ourselves.
> + */
> +
> +static pid_t trapping_tid = 0;
> +
>  #define parasite_size		(round_up(sizeof(parasite_blob), PAGE_SIZE))
>  
>  static int can_run_syscall(unsigned long ip, unsigned long start, unsigned long end)
> @@ -249,12 +259,16 @@ static int parasite_execute_trap_by_pid(unsigned int cmd,
>  
>  	*ctl->addr_cmd = cmd;
>  
> +	trapping_tid = pid;
> +
>  	ret = parasite_run(pid, PTRACE_CONT, ctl->parasite_ip, stack, &regs, octx);
>  	if (ret == 0)
>  		ret = parasite_trap(ctl, pid, &regs, octx);
>  	if (ret == 0)
>  		ret = (int)REG_RES(regs);
>  
> +	trapping_tid = 0;
> +
>  	if (ret)
>  		pr_err("Parasite exited with %d\n", ret);
>  
> @@ -379,10 +393,14 @@ int parasite_send_fd(struct parasite_ctl *ctl, int fd)
>   * One should use the cr_system helper, that blocks sigcild and waits
>   * for the spawned program to finish.
>   */
> +
>  static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
>  {
>  	int pid, status;
>  
> +	if (trapping_tid == siginfo->si_pid)
> +		return;
> +
>  	pr_err("si_code=%d si_pid=%d si_status=%d\n",
>  		siginfo->si_code, siginfo->si_pid, siginfo->si_status);
>  
> -- 
> 1.8.4.2
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
-------------- next part --------------
>From 984334c4dbea9207fa497c56d3f11802131cffc3 Mon Sep 17 00:00:00 2001
From: Andrey Vagin <avagin at openvz.org>
Date: Tue, 14 Oct 2014 16:31:08 +0400
Subject: [PATCH] parasite: stop a parasite daemon before dumping threads

The parasite daemon set up SIGCHLD handler, but for dumping threads we
use parasite-trap. While doing this the sigchild handler notices the
CHLD arriving on the thread trap, emits an error

(00.020292) Error (parasite-syscall.c:387): si_code=4 si_pid=3485 si_status=5

but wait() reports -1 (task is not dead, just trapped) and handler just exits.

Let's stop a parasite daemon before dumping threads.

Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 cr-dump.c                  | 16 +++++++++++-----
 include/parasite-syscall.h |  1 +
 parasite-syscall.c         | 31 +++++++++++++++++++++++--------
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 65c6f9c..e7e3543 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1630,15 +1630,21 @@ static int dump_one_task(struct pstree_item *item)
 		goto err_cure;
 	}
 
-	ret = dump_task_threads(parasite_ctl, item);
+	ret = dump_task_creds(parasite_ctl, cr_imgset, &cr);
 	if (ret) {
-		pr_err("Can't dump threads\n");
-		goto err_cure;
+		pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
+		goto err;
 	}
 
-	ret = dump_task_creds(parasite_ctl, cr_imgset, &cr);
+	ret = parasite_stop_daemon(parasite_ctl);
 	if (ret) {
-		pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret);
+		pr_err("Can't cure (pid: %d) from parasite\n", pid);
+		goto err;
+	}
+
+	ret = dump_task_threads(parasite_ctl, item);
+	if (ret) {
+		pr_err("Can't dump threads\n");
 		goto err;
 	}
 
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 67840fc..95a76c6 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -137,6 +137,7 @@ enum trace_flags {
 	TRACE_EXIT,
 };
 
+extern int parasite_stop_daemon(struct parasite_ctl *ctl);
 extern int parasite_stop_on_syscall(int tasks, int sys_nr, enum trace_flags trace);
 extern int parasite_unmap(struct parasite_ctl *ctl, unsigned long addr);
 extern int ptrace_stop_pie(pid_t pid, void *addr, enum trace_flags *tf);
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 7cc1a84..b300da8 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -829,9 +829,6 @@ static int parasite_fini_seized(struct parasite_ctl *ctl)
 	if (restore_child_handler())
 		return -1;
 
-	if (!ctl->daemonized)
-		return 0;
-
 	/* Start to trace syscalls for each thread */
 	if (ptrace(PTRACE_INTERRUPT, pid, NULL, NULL)) {
 		pr_perror("Unable to interrupt the process");
@@ -968,15 +965,33 @@ goon:
 	return 0;
 }
 
-int parasite_cure_remote(struct parasite_ctl *ctl)
+int parasite_stop_daemon(struct parasite_ctl *ctl)
 {
-	int ret = 0;
+	if (ctl->daemonized) {
+		/*
+		 * Looks like a previous attempt failed, we should do
+		 * nothing in this case. parasite will try to cure itself.
+		 */
+		if (ctl->tsock < 0)
+			return -1;
 
-	if (ctl->parasite_ip)
-		if (parasite_fini_seized(ctl))
+		if (parasite_fini_seized(ctl)) {
+			close_safe(&ctl->tsock);
 			return -1;
+		}
+	}
 
-	close_safe(&ctl->tsock);
+	ctl->daemonized = false;
+
+	return 0;
+}
+
+int parasite_cure_remote(struct parasite_ctl *ctl)
+{
+	int ret = 0;
+
+	if (parasite_stop_daemon(ctl))
+		return -1;
 
 	if (ctl->remote_map) {
 		struct parasite_unmap_args *args;
-- 
1.9.3



More information about the CRIU mailing list