diff --git a/cr-dump.c b/cr-dump.c index 4b44bcedb..7d33e3d4e 100644 --- a/cr-dump.c +++ b/cr-dump.c @@ -1626,18 +1626,24 @@ static int dump_one_task(struct pstree_item *item) goto err_cure; } - ret = dump_task_threads(parasite_ctl, item); - if (ret) { - pr_err("Can't dump threads\n"); - goto err_cure; - } - ret = dump_task_creds(parasite_ctl, cr_imgset, &cr); if (ret) { pr_err("Dump creds (pid: %d) failed with %d\n", pid, ret); goto err; } + ret = parasite_stop_daemon(parasite_ctl); + if (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; + } + ret = parasite_cure_seized(parasite_ctl); if (ret) { pr_err("Can't cure (pid: %d) from parasite\n", pid); diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h index 05738e3b5..0a882e02e 100644 --- a/include/parasite-syscall.h +++ b/include/parasite-syscall.h @@ -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); diff --git a/parasite-syscall.c b/parasite-syscall.c index 69f89349b..063cf47b0 100644 --- a/parasite-syscall.c +++ b/parasite-syscall.c @@ -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_stop_daemon(struct parasite_ctl *ctl) +{ + 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 (parasite_fini_seized(ctl)) { + close_safe(&ctl->tsock); + return -1; + } + } + + ctl->daemonized = false; + + return 0; +} + int parasite_cure_remote(struct parasite_ctl *ctl) { int ret = 0; - if (ctl->parasite_ip) - if (parasite_fini_seized(ctl)) - return -1; - - close_safe(&ctl->tsock); + if (parasite_stop_daemon(ctl)) + return -1; if (ctl->remote_map) { struct parasite_unmap_args *args;