summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xnetdata-installer.sh1
-rw-r--r--src/daemon.c49
-rw-r--r--src/main.c93
-rw-r--r--src/main.h4
-rw-r--r--src/popen.c20
-rw-r--r--system/netdata.service.in3
6 files changed, 77 insertions, 93 deletions
diff --git a/netdata-installer.sh b/netdata-installer.sh
index 3154247306..d8c073ae57 100755
--- a/netdata-installer.sh
+++ b/netdata-installer.sh
@@ -11,6 +11,7 @@ then
fi
LC_ALL=C
+umask 022
# you can set CFLAGS before running installer
CFLAGS="${CFLAGS--O3}"
diff --git a/src/daemon.c b/src/daemon.c
index 33af252da0..2a56ae0cce 100644
--- a/src/daemon.c
+++ b/src/daemon.c
@@ -30,49 +30,8 @@ int pidfd = -1;
void sig_handler(int signo)
{
- switch(signo) {
- case SIGILL:
- case SIGABRT:
- case SIGFPE:
- case SIGSEGV:
- case SIGBUS:
- case SIGSYS:
- case SIGTRAP:
- case SIGXCPU:
- case SIGXFSZ:
- infoerr("Death signaled exit (signal %d).", signo);
- signal(signo, SIG_DFL);
- break;
-
- case SIGKILL:
- case SIGTERM:
- case SIGQUIT:
- case SIGINT:
- case SIGHUP:
- case SIGUSR1:
- case SIGUSR2:
- infoerr("Signaled exit (signal %d).", signo);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGINT, SIG_IGN);
- signal(SIGCHLD, SIG_IGN);
- netdata_cleanup_and_exit(1);
- break;
-
- case SIGPIPE:
- infoerr("Signaled PIPE (signal %d).", signo);
- // this is received when web clients send a reset
- // no need to log it.
- // infoerr("Ignoring signal %d.", signo);
- break;
-
- default:
- info("Signal %d received. Falling back to default action for it.", signo);
- signal(signo, SIG_DFL);
- break;
- }
+ if(signo)
+ netdata_exit = 1;
}
int become_user(const char *username)
@@ -249,10 +208,6 @@ int become_daemon(int dont_fork, int close_all_files, const char *user, const ch
}
}
- signal(SIGCHLD, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGWINCH, SIG_IGN);
-
// fork() again
if(!dont_fork) {
int i = fork();
diff --git a/src/main.c b/src/main.c
index 642638bf54..50c733d32f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -40,7 +40,7 @@
extern void *cgroups_main(void *ptr);
-int netdata_exit = 0;
+volatile sig_atomic_t netdata_exit = 0;
void netdata_cleanup_and_exit(int ret)
{
@@ -123,19 +123,7 @@ int killpid(pid_t pid, int sig)
}
else {
errno = 0;
-
- void (*old)(int);
- old = signal(sig, SIG_IGN);
- if(old == SIG_ERR) {
- error("Cannot overwrite signal handler for signal %d", sig);
- old = sig_handler;
- }
-
ret = kill(pid, sig);
-
- if(signal(sig, old) == SIG_ERR)
- error("Cannot restore signal handler for signal %d", sig);
-
if(ret == -1) {
switch(errno) {
case ESRCH:
@@ -412,6 +400,41 @@ int main(int argc, char **argv)
// --------------------------------------------------------------------
+ // block signals while initializing threads.
+ // this causes the threads to block signals.
+ sigset_t sigset;
+ sigfillset(&sigset);
+
+ if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1) {
+ error("Could not block signals for threads");
+ }
+
+ // Catch signals which we want to use to quit savely
+ struct sigaction sa;
+ sigemptyset(&sa.sa_mask);
+ sigaddset(&sa.sa_mask, SIGHUP);
+ sigaddset(&sa.sa_mask, SIGINT);
+ sigaddset(&sa.sa_mask, SIGTERM);
+ sa.sa_handler = sig_handler;
+ if(sigaction(SIGHUP, &sa, NULL) == -1) {
+ error("Failed to change signal handler for SIGHUP");
+ }
+ if(sigaction(SIGINT, &sa, NULL) == -1) {
+ error("Failed to change signal handler for SIGINT");
+ }
+ if(sigaction(SIGTERM, &sa, NULL) == -1) {
+ error("Failed to change signal handler for SIGTERM");
+ }
+ // Ignore SIGPIPE completely.
+ // INFO: If we add signals here we have to unblock them
+ // at popen.c when running a external plugin.
+ sa.sa_handler = SIG_IGN;
+ if(sigaction(SIGPIPE, &sa, NULL) == -1) {
+ error("Failed to change signal handler for SIGTERM");
+ }
+
+ // --------------------------------------------------------------------
+
i = pthread_attr_init(&attr);
if(i != 0)
fatal("pthread_attr_init() failed with code %d.", i);
@@ -492,24 +515,6 @@ int main(int argc, char **argv)
info("NetData started on pid %d", getpid());
- // catch all signals
- for (i = 1 ; i < 65 ;i++) {
- switch(i) {
- case SIGKILL: // not catchable
- case SIGSTOP: // not catchable
- break;
-
- case SIGSEGV:
- case SIGFPE:
- case SIGCHLD:
- signal(i, SIG_DFL);
- break;
-
- default:
- signal(i, sig_handler);
- break;
- }
- }
// ------------------------------------------------------------------------
// get default pthread stack size
@@ -550,18 +555,22 @@ int main(int argc, char **argv)
else info("Not starting thread %s.", st->name);
}
- // for future use - the main thread
- while(1) {
- if(netdata_exit != 0) {
- netdata_exit++;
+ // ------------------------------------------------------------------------
+ // block signals while initializing threads.
+ sigset_t sigset;
+ sigfillset(&sigset);
- if(netdata_exit > 5) {
- netdata_cleanup_and_exit(0);
- exit(0);
- }
- }
- sleep(2);
+ if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
+ error("Could not unblock signals for threads");
}
- exit(0);
+ // Handle flags set in the signal handler.
+ while(1) {
+ pause();
+ if(netdata_exit) {
+ info("Exit main loop of netdata.");
+ netdata_cleanup_and_exit(0);
+ exit(0);
+ }
+ }
}
diff --git a/src/main.h b/src/main.h
index 6a90efd9d4..d9edda58e6 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,7 +1,9 @@
#ifndef NETDATA_MAIN_H
#define NETDATA_MAIN_H 1
-extern int netdata_exit;
+#include <signal.h>
+
+extern volatile sig_atomic_t netdata_exit;
extern void kill_childs(void);
extern int killpid(pid_t pid, int signal);
diff --git a/src/popen.c b/src/popen.c
index 882a4cc5a6..d4e86607bc 100644
--- a/src/popen.c
+++ b/src/popen.c
@@ -114,10 +114,26 @@ FILE *mypopen(const char *command, pid_t *pidptr)
#endif
// reset all signals
- for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
+ {
+ sigset_t sigset;
+ sigfillset(&sigset);
+
+ if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
+ error("Could not block signals for threads");
+ }
+ // We only need to reset ignored signals.
+ // Signals with signal handlers are reset by default.
+ struct sigaction sa;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = SIG_DFL;
+ if(sigaction(SIGPIPE, &sa, NULL) == -1) {
+ error("Failed to change signal handler for SIGTERM");
+ }
+ }
+
info("executing command: '%s' on pid %d.", command, getpid());
- execl("/bin/sh", "sh", "-c", command, NULL);
+ execl("/bin/sh", "sh", "-c", command, NULL);
exit(1);
}
diff --git a/system/netdata.service.in b/system/netdata.service.in
index bc26cc9dcc..91db6122d8 100644
--- a/system/netdata.service.in
+++ b/system/netdata.service.in
@@ -9,7 +9,8 @@ User=root
Group=root
PIDFile=@localstatedir_POST@/run/netdata.pid
ExecStart=@sbindir_POST@/netdata -pidfile @localstatedir_POST@/run/netdata.pid
-ExecStop=/bin/kill -SIGTERM $MAINPID
+KillMode=mixed
+KillSignal=SIGTERM
TimeoutStopSec=30
[Install]