diff --git a/flock/flock.c b/flock/flock.c index 24837720..df043f28 100644 --- a/flock/flock.c +++ b/flock/flock.c @@ -41,8 +41,37 @@ poweroff_event_hook(void *data UNUSED) ev_run_list(&shutdown_event_list); } +static void +child_event_hook(void *data UNUSED) +{ + log(L_INFO "Zombie elimination routine invoked."); + while (1) { + int status; + pid_t p = waitpid(-1, &status, WNOHANG); + + if (p < 0) + { + log(L_ERR "Zombie elimination failed: %m"); + return; + } + + if (p == 0) + return; + + const char *coreinfo = WCOREDUMP(status) ? " (core dumped)" : ""; + + if (WIFEXITED(status)) + log(L_INFO "Process %d ended with status %d%s", p, WEXITSTATUS(status), coreinfo); + else if (WIFSIGNALED(status)) + log(L_INFO "Process %d exited by signal %d (%s)%s", p, WTERMSIG(status), strsignal(WTERMSIG(status)), coreinfo); + else + log(L_ERR "Process %d exited with a strange status %d", p, status); + } +} + event reboot_event = { .hook = reboot_event_hook }, - poweroff_event = { .hook = poweroff_event_hook }; + poweroff_event = { .hook = poweroff_event_hook }, + child_event = { .hook = child_event_hook }; callback shutdown_done_callback; @@ -89,6 +118,11 @@ hypervisor_fail_sighandler(int signo UNUSED) _exit(1); } +static void +hypervisor_child_sighandler(int signo UNUSED) +{ + ev_send_loop(&main_birdloop, &child_event); +} /* * The Main. @@ -236,6 +270,7 @@ main(int argc, char **argv, char **argh UNUSED) signal(SIGINT, hypervisor_poweroff_sighandler); signal(SIGHUP, hypervisor_reboot_sighandler); signal(SIGQUIT, hypervisor_fail_sighandler); + signal(SIGCHLD, hypervisor_child_sighandler); /* Unblock signals */ sigprocmask(SIG_SETMASK, &oldmask, NULL); diff --git a/flock/hypervisor.c b/flock/hypervisor.c index 38aa1ce0..20d1564e 100644 --- a/flock/hypervisor.c +++ b/flock/hypervisor.c @@ -239,7 +239,7 @@ hypervisor_exposed_child_rx(sock *sk, uint size UNUSED) } /* Only one thing is actually supported for now: opening a listening socket */ - int sfd = socket(AF_INET6, SOCK_STREAM, 0); + int sfd = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0); if (sfd < 0) { log(L_ERR "Failed to socket(): %m"); @@ -260,7 +260,6 @@ hypervisor_exposed_child_rx(sock *sk, uint size UNUSED) }, }; - int e = bind(sfd, &sin.a, sizeof sin); if (e < 0) if (errno == EADDRINUSE) @@ -317,8 +316,15 @@ hypervisor_exposed_child_rx(sock *sk, uint size UNUSED) } static void -hypervisor_exposed_child_err(sock *sk UNUSED, int e UNUSED) +hypervisor_exposed_child_err(sock *sk, int e) { + if (e == 0) + log(L_INFO "Exposed child exiting OK"); + else + log(L_ERR "Exposed child control socket failure: %s", strerror(e)); + + sk_close(sk); + exit(!!e); } /**