]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Flock: Zombie children reaping
authorMaria Matejka <mq@ucw.cz>
Wed, 11 Sep 2024 11:03:02 +0000 (13:03 +0200)
committerMaria Matejka <mq@ucw.cz>
Sun, 23 Feb 2025 18:07:35 +0000 (19:07 +0100)
flock/flock.c
flock/hypervisor.c

index 24837720de0c8a6fc3a255dd77e6d975461d63d1..df043f28547bdfbe7099b19dc6370947c299b4ce 100644 (file)
@@ -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);
index 38aa1ce035b637149f498b27d59e34ac01c0c5a2..20d1564e3ff7c42c659b7d048c0e0a2fcc024f66 100644 (file)
@@ -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);
 }
 
 /**