summaryrefslogtreecommitdiffstats
path: root/daemon
diff options
context:
space:
mode:
authorMarkos Fountoulakis <44345837+mfundul@users.noreply.github.com>2020-05-20 17:25:35 +0300
committerGitHub <noreply@github.com>2020-05-20 17:25:35 +0300
commitae0d6007f1b2caf32202c95bd47a3e5ccfe80fa0 (patch)
tree4fde2d37f8f597be93896477474934b72cc9e682 /daemon
parentfeba2d1c80a95684e7da03475566cb3bc4172405 (diff)
Restore SIGCHLD signal handler after being replaced by libuv (#9107)
Diffstat (limited to 'daemon')
-rw-r--r--daemon/main.c8
-rw-r--r--daemon/signals.c15
-rw-r--r--daemon/signals.h1
3 files changed, 24 insertions, 0 deletions
diff --git a/daemon/main.c b/daemon/main.c
index d921f83a86..dd556af640 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -1384,6 +1384,14 @@ int main(int argc, char **argv) {
// fork the spawn server
spawn_init();
+ /*
+ * Libuv uv_spawn() uses SIGCHLD internally:
+ * https://github.com/libuv/libuv/blob/cc51217a317e96510fbb284721d5e6bc2af31e33/src/unix/process.c#L485
+ * and inadvertently replaces the netdata signal handler which was setup during initialization.
+ * Thusly, we must explicitly restore the signal handler for SIGCHLD.
+ * Warning: extreme care is needed when mixing and matching POSIX and libuv.
+ */
+ signals_restore_SIGCHLD();
// ------------------------------------------------------------------------
// initialize rrd, registry, health, rrdpush, etc.
diff --git a/daemon/signals.c b/daemon/signals.c
index d4e74614f7..9e30bf19d7 100644
--- a/daemon/signals.c
+++ b/daemon/signals.c
@@ -111,6 +111,21 @@ void signals_init(void) {
}
}
+void signals_restore_SIGCHLD(void)
+{
+ struct sigaction sa;
+
+ if (reaper_enabled == 0)
+ return;
+
+ sa.sa_flags = 0;
+ sigfillset(&sa.sa_mask);
+ sa.sa_handler = signal_handler;
+
+ if(sigaction(SIGCHLD, &sa, NULL) == -1)
+ error("SIGNAL: Failed to change signal handler for: SIGCHLD");
+}
+
void signals_reset(void) {
struct sigaction sa;
sigemptyset(&sa.sa_mask);
diff --git a/daemon/signals.h b/daemon/signals.h
index e7e64365dc..3fa2b0f43f 100644
--- a/daemon/signals.h
+++ b/daemon/signals.h
@@ -6,6 +6,7 @@
extern void signals_init(void);
extern void signals_block(void);
extern void signals_unblock(void);
+extern void signals_restore_SIGCHLD(void);
extern void signals_reset(void);
extern void signals_handle(void) NORETURN;