mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +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)
|
static void sigchld_handler(int signal, siginfo_t *siginfo, void *data)
|
||||||
{
|
{
|
||||||
struct pstree_item *pi;
|
int status, pid, exit;
|
||||||
pid_t pid = siginfo->si_pid;
|
|
||||||
int status;
|
|
||||||
int exit;
|
|
||||||
|
|
||||||
exit = (siginfo->si_code == CLD_EXITED);
|
while (1) {
|
||||||
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) {
|
|
||||||
pid = waitpid(-1, &status, WNOHANG);
|
pid = waitpid(-1, &status, WNOHANG);
|
||||||
if (pid <= 0)
|
if (pid <= 0)
|
||||||
return;
|
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);
|
exit = WIFEXITED(status);
|
||||||
status = exit ? WEXITSTATUS(status) : WTERMSIG(status);
|
status = exit ? WEXITSTATUS(status) : WTERMSIG(status);
|
||||||
if (status)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Exited (with zero code) helpers are OK */
|
break;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err:
|
|
||||||
if (exit)
|
if (exit)
|
||||||
pr_err("%d exited, status=%d\n", pid, status);
|
pr_err("%d exited, status=%d\n", pid, status);
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user