+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.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 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;
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:
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);
}
}
{
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;
}
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;
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);
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);
}
}
}
-
+
if((dev_null = open("/dev/null", O_RDWR, 0666)) == -1) {
perror("Cannot open /dev/null");
if(input_fd != -1) close(input_fd);
// 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
input_fd = -1;
}
else dup2(dev_null, STDIN_FILENO);
-
+
if(output_fd != -1) {
if(output_fd != STDOUT_FILENO) {
dup2(output_fd, STDOUT_FILENO);
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);
}