mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 13:58:34 +00:00
restore: simplify sigchld handler
The idea is simple. Everyone has to wait its children, a restore is interrupted if we found abandoned zombie. Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
@@ -1207,54 +1207,26 @@ err:
|
||||
|
||||
static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
|
||||
{
|
||||
struct pstree_item *pi;
|
||||
pid_t pid = siginfo->si_pid;
|
||||
int status;
|
||||
int exit;
|
||||
int status, pid, exit;
|
||||
|
||||
exit = (siginfo->si_code == CLD_EXITED);
|
||||
status = siginfo->si_status;
|
||||
|
||||
/* skip scripts */
|
||||
if (!current && root_item->pid->real != pid) {
|
||||
pid = waitpid(root_item->pid->real, &status, WNOHANG);
|
||||
if (pid <= 0)
|
||||
return;
|
||||
exit = WIFEXITED(status);
|
||||
status = exit ? WEXITSTATUS(status) : WTERMSIG(status);
|
||||
}
|
||||
|
||||
if (!current && siginfo->si_code == CLD_TRAPPED &&
|
||||
siginfo->si_status == SIGCHLD) {
|
||||
/* The root task is ptraced. Allow it to handle SIGCHLD */
|
||||
ptrace(PTRACE_CONT, siginfo->si_pid, 0, SIGCHLD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current || status)
|
||||
goto err;
|
||||
|
||||
while (pid) {
|
||||
while (1) {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
if (pid <= 0)
|
||||
return;
|
||||
|
||||
if (!current && WIFSTOPPED(status) &&
|
||||
WSTOPSIG(status) == SIGCHLD) {
|
||||
/* The root task is ptraced. Allow it to handle SIGCHLD */
|
||||
ptrace(PTRACE_CONT, siginfo->si_pid, 0, SIGCHLD);
|
||||
return;
|
||||
}
|
||||
|
||||
exit = WIFEXITED(status);
|
||||
status = exit ? WEXITSTATUS(status) : WTERMSIG(status);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
/* Exited (with zero code) helpers are OK */
|
||||
list_for_each_entry(pi, ¤t->children, sibling)
|
||||
if (vpid(pi) == siginfo->si_pid)
|
||||
break;
|
||||
|
||||
BUG_ON(&pi->sibling == ¤t->children);
|
||||
if (pi->pid->state != TASK_HELPER)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
err:
|
||||
if (exit)
|
||||
pr_err("%d exited, status=%d\n", pid, status);
|
||||
else
|
||||
|
Reference in New Issue
Block a user