Commit 80507ee8 by Serge Hallyn

start.c: handle potential signal flood

Signalfd does not guarantee that we'll get an event for every signal. So if 3 tasks exit at the same time, we may get only one sigchld event. Therefore, in signal_handler(), always check whether init has exited. Do with with WNOWAIT so that we can still wait4 to cleanup the init after lxc_poll() exists (rather than complicating the code). Note - there is still a race in the kernel which can cause the container init to become a defunct child of the host init (!). This doesn't solve that, but is a potential (if very unlikely) race which apw pointed out while we were trying to create a reproducer for the kernel bug. Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent 48c63f8d
......@@ -162,8 +162,10 @@ static int signal_handler(int fd, void *data,
struct lxc_epoll_descr *descr)
{
struct signalfd_siginfo siginfo;
siginfo_t info;
int ret;
pid_t *pid = data;
bool init_died = false;
ret = read(fd, &siginfo, sizeof(siginfo));
if (ret < 0) {
......@@ -176,16 +178,23 @@ static int signal_handler(int fd, void *data,
return -1;
}
// check whether init is running
info.si_pid = 0;
ret = waitid(P_PID, *pid, &info, WEXITED | WNOWAIT | WNOHANG);
if (ret == 0 && info.si_pid == *pid) {
init_died = true;
}
if (siginfo.ssi_signo != SIGCHLD) {
kill(*pid, siginfo.ssi_signo);
INFO("forwarded signal %d to pid %d", siginfo.ssi_signo, *pid);
return 0;
return init_died ? 1 : 0;
}
if (siginfo.ssi_code == CLD_STOPPED ||
siginfo.ssi_code == CLD_CONTINUED) {
INFO("container init process was stopped/continued");
return 0;
return init_died ? 1 : 0;
}
/* more robustness, protect ourself from a SIGCHLD sent
......@@ -193,7 +202,7 @@ static int signal_handler(int fd, void *data,
*/
if (siginfo.ssi_pid != *pid) {
WARN("invalid pid for SIGCHLD");
return 0;
return init_died ? 1 : 0;
}
DEBUG("container init process exited");
......
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