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 */