Thread (89 messages) 89 messages, 4 authors, 2021-02-22

Re: [PATCH 17/35] monitor: handle SIGCHLD for terminated child processes

From: Sagi Grimberg <sagi@grimberg.me>
Date: 2021-01-29 01:54:42

No commit message?
quoted hunk ↗ jump to hunk
Signed-off-by: Martin Wilck <redacted>
---
  monitor.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--
  1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/monitor.c b/monitor.c
index 9375a14..8db40e6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -26,6 +26,8 @@
  #include <limits.h>
  #include <syslog.h>
  #include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
  #include <sys/epoll.h>
  
  #include "common.h"
@@ -100,6 +102,13 @@ static void monitor_int_handler(int sig)
  	must_exit = 1;
  }
  
+static sig_atomic_t got_sigchld;
+
+static void monitor_chld_handler(int sig)
+{
+	got_sigchld = 1;
+}
+
  static sigset_t orig_sigmask;
  
  static int monitor_init_signals(void)
@@ -118,6 +127,9 @@ static int monitor_init_signals(void)
  		return -errno;
  	if (sigaction(SIGINT, &sa, NULL) == -1)
  		return -errno;
+	sa.sa_handler = monitor_chld_handler;
+	if (sigaction(SIGCHLD, &sa, NULL) == -1)
+		return -errno;
  	return 0;
  }
  
@@ -336,6 +348,34 @@ static void monitor_handle_uevents(struct udev_monitor *monitor)
  	}
  }
  
+static void handle_sigchld(void)
+{
+	while (true) {
+		int wstatus;
+		pid_t pid;
+
+		pid = waitpid(-1, &wstatus, WNOHANG);
+		switch(pid) {
+		case -1:
+			if (errno != ECHILD)
+				log(LOG_ERR, "error in waitpid: %m\n");
+			return;
+		case 0:
+			return;
+		default:
+			break;
+		}
+		if (!WIFEXITED(wstatus))
+			log(LOG_WARNING, "child %ld didn't exit normally\n",
+			    (long)pid);
+		else if (WEXITSTATUS(wstatus) != 0)
+			log(LOG_NOTICE, "child %ld exited with status \"%s\"\n",
+			    (long)pid, strerror(WEXITSTATUS(wstatus)));
+		else
+			log(LOG_DEBUG, "child %ld exited normally\n", (long)pid);
+	};
+}
+
  #define MAX_EVENTS 1
  static int monitor_main_loop(struct udev_monitor *monitor)
  {
@@ -357,13 +397,19 @@ static int monitor_main_loop(struct udev_monitor *monitor)
  	sigfillset(&ep_mask);
  	sigdelset(&ep_mask, SIGTERM);
  	sigdelset(&ep_mask, SIGINT);
+	sigdelset(&ep_mask, SIGCHLD);
  	while (1) {
  		int rc, i;
  
  		rc = epoll_pwait(ep_fd, events, MAX_EVENTS, -1, &ep_mask);
  		if (rc == -1 && errno == EINTR) {
-			log(LOG_NOTICE, "monitor: exit signal received\n");
-			return 0;
+			if (must_exit) {
+				log(LOG_NOTICE, "monitor: exit signal received\n");
+				return 0;
+			} else if (got_sigchld) {
+				got_sigchld = 0;
+				handle_sigchld();
+			}
  		} else if (rc == -1) {
  			log(LOG_ERR, "monitor: epoll_wait: %m\n");
  			return -errno;
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help