+#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...");
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:
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);
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);
// 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
// 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)
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