@cryptotaxi247 / netdata-1 / commits / 9d43f7980

added more error exit tracing info to trace issue 529; switched to accept4() and added SO_NONBLOCK to all sockets

Costa Tsaousis (ktsaou) committed Jun 10, 2016 at 23:16 UTC 9d43f7980c0cc89831724bc1de724cde0ab55630
9 files changed +85 -35
configure.ac
+1
@@ -34,6 +34,7 @@ AC_PROG_CC
34 AC_PROG_INSTALL
35 PKG_PROG_PKG_CONFIG
36 AC_USE_SYSTEM_EXTENSIONS
37 +AC_CHECK_FUNCS_ONCE(accept4)
38
39 AC_ARG_ENABLE(
40 [plugin-nfacct],
src/daemon.c
+4 -1
@@ -29,8 +29,11 @@ char pidfile[FILENAME_MAX + 1] = "";
29
30 void sig_handler(int signo)
31 {
32 - if(signo)
32 + if(signo) {
33 + error_log_limit_unlimited();
34 + error("Received signal %d. Exiting...", signo);
35 netdata_exit = 1;
36 + }
37 }
38
39 static void properly_chown_netdata_generated_file(int fd, uid_t uid, gid_t gid) {
src/log.h
+1
@@ -50,6 +50,7 @@ extern unsigned long error_log_errors_per_period;
50 extern int error_log_limit(int reset);
51
52 #define error_log_limit_reset() do { error_log_limit(1); } while(0)
53 +#define error_log_limit_unlimited() do { error_log_throttle_period = 0; } while(0)
54
55 #define debug(type, args...) do { if(unlikely(!silent && (debug_flags & type))) debug_int(__FILE__, __FUNCTION__, __LINE__, ##args); } while(0)
56 #define info(args...) info_int(__FILE__, __FUNCTION__, __LINE__, ##args)
src/main.c
+5 -5
@@ -40,15 +40,15 @@ extern void *cgroups_main(void *ptr);
40
41 volatile sig_atomic_t netdata_exit = 0;
42
43 -void netdata_cleanup_and_exit(int ret)
44 -{
43 +void netdata_cleanup_and_exit(int ret) {
44 netdata_exit = 1;
45 +
46 + error_log_limit_unlimited();
47 +
48 + info("Called: netdata_cleanup_and_exit()");
49 rrdset_save_all();
50 // kill_childs();
51
49 - // let it log a few more error messages
50 - error_log_limit_reset();
51 -
52 if(pidfile[0]) {
53 if(unlink(pidfile) != 0)
54 error("Cannot unlink pidfile '%s'.", pidfile);
src/popen.c
+21 -18
@@ -93,7 +93,9 @@ FILE *mypopen(const char *command, pid_t *pidptr)
93
94 // fork again to become session leader
95 pid = fork();
96 - if(pid == -1) fprintf(stderr, "Cannot fork again on pid %d\n", getpid());
96 + if(pid == -1)
97 + error("pre-execution of command '%s' on pid %d: Cannot fork 2nd time.", command, getpid());
98 +
99 if(pid != 0) {
100 // the parent
101 exit(0);
@@ -101,13 +103,13 @@ FILE *mypopen(const char *command, pid_t *pidptr)
103
104 // set a new process group id for just this child
105 if( setpgid(0, 0) != 0 )
104 - error("Cannot set a new process group for pid %d (%s)", getpid(), strerror(errno));
106 + error("pre-execution of command '%s' on pid %d: Cannot set a new process group.", command, getpid());
107
108 if( getpgid(0) != getpid() )
107 - error("Process group set is incorrect. Expected %d, found %d", getpid(), getpgid(0));
109 + 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));
110
111 if( setsid() != 0 )
110 - error("Cannot set session id for pid %d (%s)", getpid(), strerror(errno));
112 + error("pre-execution of command '%s' on pid %d: Cannot set session id.", command, getpid());
113
114 fprintf(stdout, "MYPID %d\n", getpid());
115 fflush(NULL);
@@ -118,18 +120,17 @@ FILE *mypopen(const char *command, pid_t *pidptr)
120 sigset_t sigset;
121 sigfillset(&sigset);
122
121 - if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
122 - error("Could not block signals for threads");
123 - }
123 + if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1)
124 + error("pre-execution of command '%s' on pid %d: could not unblock signals for threads.", command, getpid());
125 +
126 // We only need to reset ignored signals.
127 // Signals with signal handlers are reset by default.
128 struct sigaction sa;
129 sigemptyset(&sa.sa_mask);
130 sa.sa_handler = SIG_DFL;
131 sa.sa_flags = 0;
130 - if(sigaction(SIGPIPE, &sa, NULL) == -1) {
131 - error("Failed to change signal handler for SIGTERM");
132 - }
132 + if(sigaction(SIGPIPE, &sa, NULL) == -1)
133 + error("pre-execution of command '%s' on pid %d: failed to set default signal handler for SIGPIPE.", command, getpid());
134 }
135
136
@@ -148,41 +149,43 @@ int mypclose(FILE *fp, pid_t pid) {
149 if(waitid(P_PID, (id_t) pid, &info, WEXITED) != -1) {
150 switch(info.si_code) {
151 case CLD_EXITED:
151 - error("pid %d exited with code %d.", info.si_pid, info.si_status);
152 + error("child pid %d exited with code %d.", info.si_pid, info.si_status);
153 return(info.si_status);
154 break;
155
156 case CLD_KILLED:
156 - error("pid %d killed by signal %d.", info.si_pid, info.si_status);
157 + error("child pid %d killed by signal %d.", info.si_pid, info.si_status);
158 return(-1);
159 break;
160
161 case CLD_DUMPED:
161 - error("pid %d core dumped by signal %d.", info.si_pid, info.si_status);
162 + error("child pid %d core dumped by signal %d.", info.si_pid, info.si_status);
163 return(-2);
164 break;
165
166 case CLD_STOPPED:
166 - error("pid %d stopped by signal %d.", info.si_pid, info.si_status);
167 + error("child pid %d stopped by signal %d.", info.si_pid, info.si_status);
168 return(0);
169 break;
170
171 case CLD_TRAPPED:
171 - error("pid %d trapped by signal %d.", info.si_pid, info.si_status);
172 + error("child pid %d trapped by signal %d.", info.si_pid, info.si_status);
173 return(-4);
174 break;
175
176 case CLD_CONTINUED:
176 - error("pid %d continued by signal %d.", info.si_pid, info.si_status);
177 + error("child pid %d continued by signal %d.", info.si_pid, info.si_status);
178 return(0);
179 break;
180
181 default:
181 - error("pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
182 + error("child pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
183 return(-5);
184 break;
185 }
186 }
186 - else error("Cannot waitid() for pid %d", pid);
187 + else
188 + error("Cannot waitid() for pid %d", pid);
189 +
190 return 0;
191 }
src/rrd.c
+2 -6
@@ -661,12 +661,8 @@ void rrdset_free_all(void)
661 info("Memory cleanup completed...");
662 }
663
664 -void rrdset_save_all(void)
665 -{
666 - debug(D_RRD_CALLS, "rrdset_save_all()");
667 -
668 - // let it log a few error messages
669 - error_log_limit_reset();
664 +void rrdset_save_all(void) {
665 + info("Saving database...");
666
667 RRDSET *st;
668 RRDDIM *rd;
src/web_client.c
+5 -5
@@ -22,6 +22,7 @@
22
23 #include "common.h"
24 #include "log.h"
25 +#include "main.h"
26 #include "appconfig.h"
27 #include "url.h"
28 #include "web_buffer.h"
@@ -44,8 +45,6 @@ int web_donotrack_comply = 0;
45 int web_enable_gzip = 1, web_gzip_level = 3, web_gzip_strategy = Z_DEFAULT_STRATEGY;
46 #endif /* NETDATA_WITH_ZLIB */
47
47 -extern int netdata_exit;
48 -
48 struct web_client *web_clients = NULL;
49 unsigned long long web_clients_count = 0;
50
@@ -99,7 +98,7 @@ struct web_client *web_client_create(int listener)
98 sadr = (struct sockaddr*) &w->clientaddr;
99 addrlen = sizeof(w->clientaddr);
100
102 - w->ifd = accept(listener, sadr, &addrlen);
101 + w->ifd = accept4(listener, sadr, &addrlen, SOCK_NONBLOCK);
102 if (w->ifd == -1) {
103 error("%llu: Cannot accept new incoming connection.", w->id);
104 free(w);
@@ -141,8 +140,6 @@ struct web_client *web_client_create(int listener)
140 flag = 1;
141 if(setsockopt(w->ifd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int)) != 0)
142 error("%llu: Cannot set SO_KEEPALIVE on socket.", w->id);
144 -
145 -
143 }
144
145 w->response.data = buffer_create(INITIAL_WEB_DATA_LENGTH);
@@ -446,6 +443,8 @@ int mysendfile(struct web_client *w, char *filename)
443 return 404;
444 }
445 }
446 + if(fcntl(w->ifd, F_SETFL, O_NONBLOCK) < 0)
447 + error("%llu: Cannot set O_NONBLOCK on file '%s'.", w->id, webfilename);
448
449 // pick a Content-Type for the file
450 if(strstr(filename, ".html") != NULL) w->response.data->contenttype = CT_TEXT_HTML;
@@ -1877,6 +1876,7 @@ void web_client_process(struct web_client *w) {
1876 else
1877 buffer_strcat(w->response.data, "I am doing it already");
1878
1879 + error("web request to exit received.");
1880 netdata_exit = 1;
1881 }
1882 else if(hash == hash_debug && strcmp(tok, "debug") == 0) {
src/web_server.c
+33
@@ -51,6 +51,39 @@ static void log_allocations(void)
51 }
52 #endif
53
54 +#ifndef HAVE_ACCEPT4
55 +int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags) {
56 + int fd = accept(sock, addr, addrlen);
57 + int newflags = 0;
58 +
59 + if (fd < 0) return fd;
60 +
61 + if (flags & SOCK_NONBLOCK) {
62 + newflags |= O_NONBLOCK;
63 + flags &= ~SOCK_NONBLOCK;
64 + }
65 +
66 + if (flags & SOCK_CLOEXEC) {
67 + newflags |= O_CLOEXEC;
68 + flags &= ~SOCK_CLOEXEC;
69 + }
70 +
71 + if (flags) {
72 + errno = -EINVAL;
73 + return -1;
74 + }
75 +
76 + if (fcntl(fd, F_SETFL, newflags) < 0) {
77 + int saved_errno = errno;
78 + close(fd);
79 + errno = saved_errno;
80 + return -1;
81 + }
82 +
83 + return fd;
84 +}
85 +#endif
86 +
87 static int is_ip_anything(const char *ip)
88 {
89 if(!ip || !*ip
src/web_server.h
+13
@@ -23,4 +23,17 @@ extern void *socket_listen_main_multi_threaded(void *ptr);
23 extern void *socket_listen_main_single_threaded(void *ptr);
24 extern int create_listen_socket(void);
25
26 +#ifndef HAVE_ACCEPT4
27 +extern int accept4(int sock, struct sockaddr *addr, socklen_t *addrlen, int flags);
28 +
29 +#ifndef SOCK_NONBLOCK
30 +#define SOCK_NONBLOCK 00004000
31 +#endif /* #ifndef SOCK_NONBLOCK */
32 +
33 +#ifndef SOCK_CLOEXEC
34 +#define SOCK_CLOEXEC 02000000
35 +#endif /* #ifndef SOCK_CLOEXEC */
36 +
37 +#endif /* #ifndef HAVE_ACCEPT4 */
38 +
39 #endif /* NETDATA_WEB_SERVER_H */