Commit bc9b4bcc authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

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: 's avatarAndrey Vagin <avagin@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 28a140c8
......@@ -1626,15 +1626,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;
}
......
......@@ -136,6 +136,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);
......
......@@ -831,9 +831,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");
......@@ -970,15 +967,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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment