]> arthur.barton.de Git - netdata.git/blobdiff - src/daemon.c
build: migrate to autotools
[netdata.git] / src / daemon.c
index d772743fbb5a7b23c11650c1bb99fe5ddddcab25..19c7657e912b3c263c82c79c3bfb544b3ff9a1a5 100755 (executable)
@@ -1,3 +1,7 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef NETDATA_DAEMON
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
+#include <execinfo.h>
 
-#include "config.h"
-#include "log.h"
 #include "common.h"
+#include "appconfig.h"
+#include "log.h"
 #include "web_client.h"
 #include "plugins_d.h"
 #include "rrd.h"
 #include "main.h"
 #include "daemon.h"
 
+#define BACKTRACE_SIZE 4096
+
+void print_backtrace()
+{
+       void *buffer[BACKTRACE_SIZE];
+       int nptrs;
+
+       nptrs = backtrace(buffer, BACKTRACE_SIZE);
+       fprintf(stderr, "\n\nSTACK TRACE (%d addresses):\n\n", nptrs);
+       backtrace_symbols_fd(buffer, nptrs, STDERR_FILENO);
+       fprintf(stderr, "\n\n");
+}
+
 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:
+                       info("Death signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
+                       print_backtrace();
+                       signal(signo, SIG_DFL);
+                       break;
+
+               case SIGKILL:
                case SIGTERM:
                case SIGQUIT:
                case SIGINT:
                case SIGHUP:
-               case SIGFPE:
-               case SIGSEGV:
-                       debug(D_EXIT, "Signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
-                       signal(SIGCHLD, SIG_IGN);
+               case SIGUSR1:
+               case SIGUSR2:
+                       info("Signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
+                       print_backtrace();
                        signal(SIGPIPE, SIG_IGN);
                        signal(SIGTERM, SIG_IGN);
                        signal(SIGQUIT, SIG_IGN);
                        signal(SIGHUP,  SIG_IGN);
                        signal(SIGINT,  SIG_IGN);
+                       signal(SIGCHLD, SIG_IGN);
                        kill_childs();
-                       process_childs(0);
                        rrdset_free_all();
                        //unlink("/var/run/netdata.pid");
                        info("NetData exiting. Bye bye...");
@@ -46,13 +79,10 @@ void sig_handler(int signo)
                        break;
 
                case SIGPIPE:
-                       info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
-                       break;
-
-
-               case SIGCHLD:
-                       info("Received SIGCHLD (signal %d).", signo);
-                       process_childs(0);
+                       info("Signaled PIPE (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
+                       // this is received when web clients send a reset
+                       // no need to log it.
+                       // info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
                        break;
 
                default:
@@ -67,9 +97,9 @@ char pidfile[FILENAME_MAX + 1] = "";
 void prepare_rundir() {
        if(getuid() != 0) {
                mkdir("/run/user", 0775);
-               snprintf(rundir, FILENAME_MAX, "/run/user/%d", getpid());
+               snprintf(rundir, FILENAME_MAX, "/run/user/%d", getuid());
                mkdir(rundir, 0775);
-               snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getpid());
+               snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getuid());
        }
        
        snprintf(pidfile, FILENAME_MAX, "%s/netdata.pid", rundir);
@@ -112,7 +142,7 @@ int become_user(const char *username)
        return(0);
 }
 
-int become_daemon(int close_all_files, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp)
+int become_daemon(int dont_fork, int close_all_files, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp)
 {
        fflush(NULL);
 
@@ -185,31 +215,37 @@ int become_daemon(int close_all_files, const char *input, const char *output, co
        // all files opened
        // lets do it
 
-       int i = fork();
-       if(i == -1) {
-               perror("cannot fork");
-               exit(1);
-       }
-       if(i != 0) {
-               exit(0); // the parent
-       }
+       if(!dont_fork) {
+               int i = fork();
+               if(i == -1) {
+                       perror("cannot fork");
+                       exit(1);
+               }
+               if(i != 0) {
+                       exit(0); // the parent
+               }
 
-       // become session leader
-       if (setsid() < 0)
-               exit(2);
+               // become session leader
+               if (setsid() < 0) {
+                       perror("Cannot become session leader.");
+                       exit(2);
+               }
+       }
 
-       signal(SIGCHLD, SIG_IGN);
-       signal(SIGHUP, SIG_IGN);
+       signal(SIGCHLD,  SIG_IGN);
+       signal(SIGHUP,   SIG_IGN);
        signal(SIGWINCH, SIG_IGN);
 
        // fork() again
-       i = fork();
-       if(i == -1) {
-               perror("cannot fork");
-               exit(1);
-       }
-       if(i != 0) {
-               exit(0); // the parent
+       if(!dont_fork) {
+               int i = fork();
+               if(i == -1) {
+                       perror("cannot fork");
+                       exit(1);
+               }
+               if(i != 0) {
+                       exit(0); // the parent
+               }
        }
 
        // Set new file permissions
@@ -217,6 +253,7 @@ int become_daemon(int close_all_files, const char *input, const char *output, co
 
        // close all files
        if(close_all_files) {
+               int i;
                for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
                        if(   
                                ((access_fd && i != *access_fd) || !access_fd)
@@ -273,10 +310,12 @@ int become_daemon(int close_all_files, const char *input, const char *output, co
                if(fd >= 0) {
                        char b[100];
                        sprintf(b, "%d\n", getpid());
-                       i = write(fd, b, strlen(b));
+                       int i = write(fd, b, strlen(b));
+                       if(i <= 0) perror("Cannot write pid to file.");
                        close(fd);
                }
        }
 
        return(0);
 }
+#endif