AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG
AC_USE_SYSTEM_EXTENSIONS
+AC_CHECK_FUNCS_ONCE(accept4)
AC_ARG_ENABLE(
[plugin-nfacct],
void sig_handler(int signo)
{
- if(signo)
+ if(signo) {
+ error_log_limit_unlimited();
+ error("Received signal %d. Exiting...", signo);
netdata_exit = 1;
+ }
}
static void properly_chown_netdata_generated_file(int fd, uid_t uid, gid_t gid) {
extern int error_log_limit(int reset);
#define error_log_limit_reset() do { error_log_limit(1); } while(0)
+#define error_log_limit_unlimited() do { error_log_throttle_period = 0; } while(0)
#define debug(type, args...) do { if(unlikely(!silent && (debug_flags & type))) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0)
#define info(args...) info_int(__FILE__, __FUNCTION__, __LINE__, ##args)
volatile sig_atomic_t netdata_exit = 0;
-void netdata_cleanup_and_exit(int ret)
-{
+void netdata_cleanup_and_exit(int ret) {
netdata_exit = 1;
+
+ error_log_limit_unlimited();
+
+ info("Called: netdata_cleanup_and_exit()");
rrdset_save_all();
// kill_childs();
- // let it log a few more error messages
- error_log_limit_reset();
-
if(pidfile[0]) {
if(unlink(pidfile) != 0)
error("Cannot unlink pidfile '%s'.", pidfile);
// fork again to become session leader
pid = fork();
- if(pid == -1) fprintf(stderr, "Cannot fork again on pid %d\n", getpid());
+ if(pid == -1)
+ error("pre-execution of command '%s' on pid %d: Cannot fork 2nd time.", command, getpid());
+
if(pid != 0) {
// the parent
exit(0);
// set a new process group id for just this child
if( setpgid(0, 0) != 0 )
- error("Cannot set a new process group for pid %d (%s)", getpid(), strerror(errno));
+ error("pre-execution of command '%s' on pid %d: Cannot set a new process group.", command, getpid());
if( getpgid(0) != getpid() )
- error("Process group set is incorrect. Expected %d, found %d", getpid(), getpgid(0));
+ error("pre-execution of command '%s' on pid %d: Cannot set a new process group. Process group set is incorrect. Expected %d, found %d", command, getpid(), getpid(), getpgid(0));
if( setsid() != 0 )
- error("Cannot set session id for pid %d (%s)", getpid(), strerror(errno));
+ error("pre-execution of command '%s' on pid %d: Cannot set session id.", command, getpid());
fprintf(stdout, "MYPID %d\n", getpid());
fflush(NULL);
sigset_t sigset;
sigfillset(&sigset);
- if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
- error("Could not block signals for threads");
- }
+ if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1)
+ error("pre-execution of command '%s' on pid %d: could not unblock signals for threads.", command, getpid());
+
// 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;
sa.sa_flags = 0;
- if(sigaction(SIGPIPE, &sa, NULL) == -1) {
- error("Failed to change signal handler for SIGTERM");
- }
+ if(sigaction(SIGPIPE, &sa, NULL) == -1)
+ error("pre-execution of command '%s' on pid %d: failed to set default signal handler for SIGPIPE.", command, getpid());
}
if(waitid(P_PID, (id_t) pid, &info, WEXITED) != -1) {
switch(info.si_code) {
case CLD_EXITED:
- error("pid %d exited with code %d.", info.si_pid, info.si_status);
+ error("child pid %d exited with code %d.", info.si_pid, info.si_status);
return(info.si_status);
break;
case CLD_KILLED:
- error("pid %d killed by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d killed by signal %d.", info.si_pid, info.si_status);
return(-1);
break;
case CLD_DUMPED:
- error("pid %d core dumped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d core dumped by signal %d.", info.si_pid, info.si_status);
return(-2);
break;
case CLD_STOPPED:
- error("pid %d stopped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d stopped by signal %d.", info.si_pid, info.si_status);
return(0);
break;
case CLD_TRAPPED:
- error("pid %d trapped by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d trapped by signal %d.", info.si_pid, info.si_status);
return(-4);
break;
case CLD_CONTINUED:
- error("pid %d continued by signal %d.", info.si_pid, info.si_status);
+ error("child pid %d continued by signal %d.", info.si_pid, info.si_status);
return(0);
break;
default:
- error("pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
+ error("child pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
return(-5);
break;
}
}
- else error("Cannot waitid() for pid %d", pid);
+ else
+ error("Cannot waitid() for pid %d", pid);
+
return 0;
}
info("Memory cleanup completed...");
}
-void rrdset_save_all(void)
-{
- debug(D_RRD_CALLS, "rrdset_save_all()");
-
- // let it log a few error messages
- error_log_limit_reset();
+void rrdset_save_all(void) {
+ info("Saving database...");
RRDSET *st;
RRDDIM *rd;
#include "common.h"
#include "log.h"
+#include "main.h"
#include "appconfig.h"
#include "url.h"
#include "web_buffer.h"
int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
#endif /* NETDATA_WITH_ZLIB */
-extern int netdata_exit;
-
struct web_client *web_clients = NULL;
unsigned long long web_clients_count = 0;
sadr = (struct sockaddr*) &w->clientaddr;
addrlen = sizeof(w->clientaddr);
- w->ifd = accept(listener, sadr, &addrlen);
+ w->ifd = accept4(listener, sadr, &addrlen, SOCK_NONBLOCK);
if (w->ifd == -1) {
error("%llu: Cannot accept new incoming connection.", w->id);
free(w);
flag = 1;
if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0)
error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
-
-
}
w->response.data = buffer_create(INITIAL_WEB_DATA_LENGTH);
return 404;
}
}
+ if(fcntl(w->ifd, F_SETFL, O_NONBLOCK) < 0)
+ error("%llu: Cannot set O_NONBLOCK on file '%s'.", w->id, webfilename);
// pick a Content-Type for the file
if(strstr(filename, ".html") != NULL) w->response.data->contenttype = CT_TEXT_HTML;
else
buffer_strcat(w->response.data, "I am doing it already");
+ error("web request to exit received.");
netdata_exit = 1;
}
else if(hash == hash_debug && strcmp(tok, "debug") == 0) {
}
#endif
+#ifndef HAVE_ACCEPT4
+int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
+ int fd = accept(sock, addr, addrlen);
+ int newflags = 0;
+
+ if (fd < 0) return fd;
+
+ if (flags & SOCK_NONBLOCK) {
+ newflags |= O_NONBLOCK;
+ flags &= ~SOCK_NONBLOCK;
+ }
+
+ if (flags & SOCK_CLOEXEC) {
+ newflags |= O_CLOEXEC;
+ flags &= ~SOCK_CLOEXEC;
+ }
+
+ if (flags) {
+ errno = -EINVAL;
+ return -1;
+ }
+
+ if (fcntl(fd, F_SETFL, newflags) < 0) {
+ int saved_errno = errno;
+ close(fd);
+ errno = saved_errno;
+ return -1;
+ }
+
+ return fd;
+}
+#endif
+
static int is_ip_anything(const char *ip)
{
if(!ip || !*ip
extern void *socket_listen_main_single_threaded(void *ptr);
extern int create_listen_socket(void);
+#ifndef HAVE_ACCEPT4
+extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
+
+#ifndef SOCK_NONBLOCK
+#define SOCK_NONBLOCK 00004000
+#endif /* #ifndef SOCK_NONBLOCK */
+
+#ifndef SOCK_CLOEXEC
+#define SOCK_CLOEXEC 02000000
+#endif /* #ifndef SOCK_CLOEXEC */
+
+#endif /* #ifndef HAVE_ACCEPT4 */
+
#endif /* NETDATA_WEB_SERVER_H */