diff --git a/src/lxc/start.c b/src/lxc/start.c index 57a28e87f..acdfd1b7f 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -45,9 +45,31 @@ #include #include -#ifdef HAVE_SYS_SIGNALFD_H +#ifdef HAVE_SYS_SIGNALFD_H # include #else +/* assume kernel headers are too old */ +struct signalfd_siginfo +{ + uint32_t ssi_signo; + int32_t ssi_errno; + int32_t ssi_code; + uint32_t ssi_pid; + uint32_t ssi_uid; + int32_t ssi_fd; + uint32_t ssi_tid; + uint32_t ssi_band; + uint32_t ssi_overrun; + uint32_t ssi_trapno; + int32_t ssi_status; + int32_t ssi_int; + uint64_t ssi_ptr; + uint64_t ssi_utime; + uint64_t ssi_stime; + uint64_t ssi_addr; + uint8_t __pad[48]; +}; + # ifndef __NR_signalfd4 /* assume kernel headers are too old */ # if __i386__ @@ -198,11 +220,30 @@ static int setup_sigchld_fd(sigset_t *oldmask) return fd; } -static int sigchld_handler(int fd, void *data, +static int sigchld_handler(int fd, void *data, struct lxc_epoll_descr *descr) { - DEBUG("child exited"); + struct signalfd_siginfo siginfo; + int ret; + ret = read(fd, &siginfo, sizeof(siginfo)); + if (ret < 0) { + ERROR("failed to read sigchld info"); + return -1; + } + + if (ret != sizeof(siginfo)) { + ERROR("unexpected siginfo size"); + return -1; + } + + if (siginfo.ssi_code == CLD_STOPPED || + siginfo.ssi_code == CLD_CONTINUED) { + INFO("container init process was stopped/continued"); + return 0; + } + + DEBUG("container init process exited"); return 1; }