]> arthur.barton.de Git - netdata.git/blobdiff - src/daemon.c
fixed minor issues throughout the code (mainly types); dashboard has now a watermark...
[netdata.git] / src / daemon.c
index 83e00bb30fe5c21a1037987912c83aa6bf9b22b1..268814798af9543714b30192ce23f62ff3dff0d5 100755 (executable)
@@ -1,3 +1,6 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -12,9 +15,9 @@
 #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) {
@@ -47,8 +37,7 @@ void sig_handler(int signo)
                case SIGTRAP:
                case SIGXCPU:
                case SIGXFSZ:
-                       info("Death signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
-                       print_backtrace();
+                       infoerr("Death signaled exit (signal %d).", signo);
                        signal(signo, SIG_DFL);
                        break;
 
@@ -59,26 +48,21 @@ void sig_handler(int signo)
                case SIGHUP:
                case SIGUSR1:
                case SIGUSR2:
-                       info("Signaled exit (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
-                       print_backtrace();
+                       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);
-                       kill_childs();
-                       rrdset_free_all();
-                       //unlink("/var/run/netdata.pid");
-                       info("NetData exiting. Bye bye...");
-                       exit(1);
+                       netdata_cleanup_and_exit(1);
                        break;
 
                case SIGPIPE:
-                       info("Signaled PIPE (signal %d). Errno: %d (%s)", signo, errno, strerror(errno));
+                       infoerr("Signaled PIPE (signal %d).", signo);
                        // 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));
+                       // infoerr("Ignoring signal %d.", signo);
                        break;
 
                default:
@@ -97,11 +81,11 @@ void prepare_rundir() {
                mkdir(rundir, 0775);
                snprintf(rundir, FILENAME_MAX, "/run/user/%d/netdata", getuid());
        }
-       
+
        snprintf(pidfile, FILENAME_MAX, "%s/netdata.pid", rundir);
 
        if(mkdir(rundir, 0775) != 0) {
-               if(errno != EEXIST) fprintf(stderr, "Cannot create directory '%s' (%s).", rundir, strerror(errno));
+               if(errno != EEXIST) error("Cannot create directory '%s'.", rundir);
        }
 }
 
@@ -109,52 +93,62 @@ int become_user(const char *username)
 {
        struct passwd *pw = getpwnam(username);
        if(!pw) {
-               fprintf(stderr, "User %s is not present. Error: %s\n", username, strerror(errno));
+               error("User %s is not present.", username);
                return -1;
        }
 
        if(chown(rundir, pw->pw_uid, pw->pw_gid) != 0) {
-               fprintf(stderr, "Cannot chown directory '%s' to user %s. Error: %s\n", rundir, username, strerror(errno));
+               error("Cannot chown directory '%s' to user %s.", rundir, username);
+               return -1;
+       }
+
+       if(setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) {
+               error("Cannot switch to user's %s group (gid: %d).", username, pw->pw_gid);
+               return -1;
+       }
+
+       if(setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) {
+               error("Cannot switch to user %s (uid: %d).", username, pw->pw_uid);
                return -1;
        }
 
        if(setgid(pw->pw_gid) != 0) {
-               fprintf(stderr, "Cannot switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));
+               error("Cannot switch to user's %s group (gid: %d).", username, pw->pw_gid);
                return -1;
        }
        if(setegid(pw->pw_gid) != 0) {
-               fprintf(stderr, "Cannot effectively switch to user's %s group (gid: %d). Error: %s\n", username, pw->pw_gid, strerror(errno));
+               error("Cannot effectively switch to user's %s group (gid: %d).", username, pw->pw_gid);
                return -1;
        }
        if(setuid(pw->pw_uid) != 0) {
-               fprintf(stderr, "Cannot switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));
+               error("Cannot switch to user %s (uid: %d).", username, pw->pw_uid);
                return -1;
        }
        if(seteuid(pw->pw_uid) != 0) {
-               fprintf(stderr, "Cannot effectively switch to user %s (uid: %d). Error: %s\n", username, pw->pw_uid, strerror(errno));
+               error("Cannot effectively switch to user %s (uid: %d).", username, pw->pw_uid);
                return -1;
        }
 
        return(0);
 }
 
-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)
+int become_daemon(int dont_fork, int close_all_files, const char *user, const char *input, const char *output, const char *error, const char *access, int *access_fd, FILE **access_fp)
 {
        fflush(NULL);
 
        // open the files before forking
-       int input_fd = -1, output_fd = -1, error_fd = -1, dev_null = -1;
+       int input_fd = -1, output_fd = -1, error_fd = -1, dev_null;
 
        if(input && *input) {
                if((input_fd = open(input, O_RDONLY, 0666)) == -1) {
-                       fprintf(stderr, "Cannot open input file '%s' (%s).", input, strerror(errno));
+                       error("Cannot open input file '%s'.", input);
                        return -1;
                }
        }
 
        if(output && *output) {
                if((output_fd = open(output, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
-                       fprintf(stderr, "Cannot open output log file '%s' (%s).", output, strerror(errno));
+                       error("Cannot open output log file '%s'", output);
                        if(input_fd != -1) close(input_fd);
                        return -1;
                }
@@ -162,7 +156,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
 
        if(error && *error) {
                if((error_fd = open(error, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
-                       fprintf(stderr, "Cannot open error log file '%s' (%s).", error, strerror(errno));
+                       error("Cannot open error log file '%s'.", error);
                        if(input_fd != -1) close(input_fd);
                        if(output_fd != -1) close(output_fd);
                        return -1;
@@ -171,7 +165,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
 
        if(access && *access && access_fd) {
                if((*access_fd = open(access, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {
-                       fprintf(stderr, "Cannot open access log file '%s' (%s).", access, strerror(errno));
+                       error("Cannot open access log file '%s'", access);
                        if(input_fd != -1) close(input_fd);
                        if(output_fd != -1) close(output_fd);
                        if(error_fd != -1) close(error_fd);
@@ -181,7 +175,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
                if(access_fp) {
                        *access_fp = fdopen(*access_fd, "w");
                        if(!*access_fp) {
-                               fprintf(stderr, "Cannot migrate file's '%s' fd %d (%s).\n", access, *access_fd, strerror(errno));
+                               error("Cannot migrate file's '%s' fd %d.", access, *access_fd);
                                if(input_fd != -1) close(input_fd);
                                if(output_fd != -1) close(output_fd);
                                if(error_fd != -1) close(error_fd);
@@ -191,7 +185,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
                        }
                }
        }
-       
+
        if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
                perror("Cannot open /dev/null");
                if(input_fd != -1) close(input_fd);
@@ -250,8 +244,8 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
        // close all files
        if(close_all_files) {
                int i;
-               for(i = sysconf(_SC_OPEN_MAX); i > 0; i--)
-                       if(   
+               for(i = (int) (sysconf(_SC_OPEN_MAX) - 1); i > 0; i--)
+                       if(
                                ((access_fd && i != *access_fd) || !access_fd)
                                && i != dev_null
                                && i != input_fd
@@ -276,7 +270,7 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
                input_fd = -1;
        }
        else dup2(dev_null, STDIN_FILENO);
-       
+
        if(output_fd != -1) {
                if(output_fd != STDOUT_FILENO) {
                        dup2(output_fd, STDOUT_FILENO);
@@ -306,11 +300,18 @@ int become_daemon(int dont_fork, int close_all_files, const char *input, const c
                if(fd >= 0) {
                        char b[100];
                        sprintf(b, "%d\n", getpid());
-                       int i = write(fd, b, strlen(b));
+                       ssize_t i = write(fd, b, strlen(b));
                        if(i <= 0) perror("Cannot write pid to file.");
                        close(fd);
                }
        }
 
+       if(user && *user) {
+               if(become_user(user) != 0) {
+                       error("Cannot become user '%s'. Continuing as we are.", user);
+               }
+               else info("Successfully became user '%s'.", user);
+       }
+
        return(0);
 }