@cryptotaxi247 / netdata-1 / commits / 557d1c954

fix for defunct childs

Costa Tsaousis (ktsaou) committed May 5, 2015 at 23:01 UTC 557d1c9543199ed9098df800f32b920bee001674
7 files changed +75 -47
src/daemon.c
+3 -9
@@ -37,8 +37,8 @@ void sig_handler(int signo)
37 signal(SIGQUIT, SIG_IGN);
38 signal(SIGHUP, SIG_IGN);
39 signal(SIGINT, SIG_IGN);
40 + signal(SIGCHLD, SIG_IGN);
41 kill_childs();
41 - process_childs(0);
42 rrdset_free_all();
43 //unlink("/var/run/netdata.pid");
44 info("NetData exiting. Bye bye...");
@@ -51,12 +51,6 @@ void sig_handler(int signo)
51 // info("Ignoring signal %d. Errno: %d (%s)", signo, errno, strerror(errno));
52 break;
53
54 -
55 - case SIGCHLD:
56 - info("Received SIGCHLD (signal %d).", signo);
57 - process_childs(0);
58 - break;
59 -
54 default:
55 info("Signal %d received. Falling back to default action for it.", signo);
56 signal(signo, SIG_DFL);
@@ -200,8 +194,8 @@ int become_daemon(int close_all_files, const char *input, const char *output, co
194 if (setsid() < 0)
195 exit(2);
196
203 - signal(SIGCHLD, SIG_IGN);
204 - signal(SIGHUP, SIG_IGN);
197 + signal(SIGCHLD, SIG_IGN);
198 + signal(SIGHUP, SIG_IGN);
199 signal(SIGWINCH, SIG_IGN);
200
201 // fork() again
src/main.c
+16 -9
@@ -316,8 +316,20 @@ int main(int argc, char **argv)
316
317
318 // catch all signals
319 - for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV && i != SIGFPE) signal(i, sig_handler);
320 -
319 + for (i = 1 ; i < 65 ;i++) {
320 + switch(i) {
321 + case SIGSEGV:
322 + case SIGFPE:
323 + case SIGCHLD:
324 + signal(i, SIG_DFL);
325 + break;
326 +
327 + default:
328 + signal(i, sig_handler);
329 + break;
330 + }
331 + }
332 +
333 for (i = 0; static_threads[i].name != NULL ; i++) {
334 struct netdata_static_thread *st = &static_threads[i];
335
@@ -335,13 +347,8 @@ int main(int argc, char **argv)
347 else info("Not starting thread %s.", st->name);
348 }
349
338 - // the main process - the web server listener
339 - // this never ends
340 - // socket_listen_main(NULL);
341 - while(1) {
342 - process_childs(1);
343 - sleep(1);
344 - }
350 + // for future use - the main thread
351 + while(1) sleep(60);
352
353 exit(0);
354 }
src/plugin_tc.c
+2 -1
@@ -580,7 +580,8 @@ void *tc_main(void *ptr)
580 // debug(D_TC_LOOP, "IGNORED line");
581 //}
582 }
583 - mypclose(fp);
583 + mypclose(fp, tc_child_pid);
584 + tc_child_pid = 0;
585
586 if(device) {
587 // tc_device_free(device);
src/plugins_d.c
+2 -1
@@ -366,7 +366,8 @@ void *pluginsd_worker_thread(void *arg)
366 }
367
368 // fgets() failed or loop broke
369 - mypclose(fp);
369 + mypclose(fp, cd->pid);
370 + cd->pid = 0;
371
372 if(!count && cd->enabled) {
373 error("PLUGINSD: '%s' does not generate usefull output. Disabling it.", cd->fullfilename);
src/popen.c
+45 -19
@@ -6,7 +6,46 @@
6
7 #include "log.h"
8 #include "popen.h"
9 +/*
10 +struct mypopen {
11 + pid_t pid;
12 + FILE *fp;
13 + struct mypopen *next;
14 + struct mypopen *prev;
15 +};
16 +
17 +static struct mypopen *mypopen_root = NULL;
18 +
19 +static void mypopen_add(FILE *fp, pid_t *pid) {
20 + struct mypopen *mp = malloc(sizeof(struct mypopen));
21 + if(!mp) {
22 + fatal("Cannot allocate %zu bytes", sizeof(struct mypopen))
23 + return;
24 + }
25 +
26 + mp->fp = fp;
27 + mp->pid = pid;
28 + mp->next = popen_root;
29 + mp->prev = NULL;
30 + if(mypopen_root) mypopen_root->prev = mp;
31 + mypopen_root = mp;
32 +}
33 +
34 +static void mypopen_del(FILE *fp) {
35 + struct mypopen *mp;
36
37 + for(mp = mypopen_root; mp; mp = mp->next)
38 + if(mp->fd == fp) break;
39 +
40 + if(!mp) error("Cannot find mypopen() file pointer in open childs.");
41 + else {
42 + if(mp->next) mp->next->prev = mp->prev;
43 + if(mp->prev) mp->prev->next = mp->next;
44 + if(mypopen_root == mp) mypopen_root = mp->next;
45 + free(mp);
46 + }
47 +}
48 +*/
49 #define PIPE_READ 0
50 #define PIPE_WRITE 1
51
@@ -27,6 +66,7 @@ FILE *mypopen(const char *command, pid_t *pidptr)
66 *pidptr = pid;
67 close(pipefd[PIPE_WRITE]);
68 FILE *fp = fdopen(pipefd[PIPE_READ], "r");
69 + /*mypopen_add(fp, pid);*/
70 return(fp);
71 }
72 // the child
@@ -68,7 +108,7 @@ FILE *mypopen(const char *command, pid_t *pidptr)
108 fflush(NULL);
109 #endif
110
71 - // ignore all signals
111 + // reset all signals
112 for (i = 1 ; i < 65 ;i++) if(i != SIGSEGV) signal(i, SIG_DFL);
113
114 fprintf(stderr, "executing command: '%s' on pid %d.\n", command, getpid());
@@ -76,24 +116,12 @@ FILE *mypopen(const char *command, pid_t *pidptr)
116 exit(1);
117 }
118
79 -void mypclose(FILE *fp)
80 -{
81 - // this is a very poor implementation of pclose()
82 - // the caller should catch SIGCHLD and waitpid() on the exited child
83 - // otherwise the child will be a zombie forever
84 -
119 +void mypclose(FILE *fp, pid_t pid) {
120 + /*mypopen_del(fp);*/
121 fclose(fp);
86 -}
122
88 -void process_childs(int wait)
89 -{
123 siginfo_t info;
91 - int options = WEXITED;
92 - if(!wait) options |= WNOHANG;
93 -
94 - info.si_pid = 0;
95 - while(waitid(P_ALL, 0, &info, options) == 0) {
96 - if(!info.si_pid) break;
124 + if(waitid(P_PID, pid, &info, WEXITED) != -1) {
125 switch(info.si_code) {
126 case CLD_EXITED:
127 error("pid %d exited with code %d.", info.si_pid, info.si_status);
@@ -123,8 +151,6 @@ void process_childs(int wait)
151 error("pid %d gave us a SIGCHLD with code %d and status %d.", info.si_pid, info.si_code, info.si_status);
152 break;
153 }
126 -
127 - // prevent an infinite loop
128 - info.si_pid = 0;
154 }
155 + else error("Cannot waitid() for pid %d", pid);
156 }
src/popen.h
+1 -2
@@ -9,7 +9,6 @@
9 #define PIPE_WRITE 1
10
11 extern FILE *mypopen(const char *command, pid_t *pidptr);
12 -extern void mypclose(FILE *fp);
13 -extern void process_childs(int wait);
12 +extern void mypclose(FILE *fp, pid_t pid);
13
14 #endif /* NETDATA_POPEN_H */
web/index.js
+6 -6
@@ -4,13 +4,13 @@ var TARGET_THUMB_GRAPH_WIDTH = 500; // thumb charts width will range from 0.5 t
4 var MINIMUM_THUMB_GRAPH_WIDTH = 400; // thumb chart will generally try to be wider than that
5 var TARGET_THUMB_GRAPH_HEIGHT = 180; // the height of the thumb charts
6
7 -var THUMBS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
8 -var THUMBS_POINTS_DIVISOR = 4;
9 -var THUMBS_STACKED_POINTS_DIVISOR = 10;
7 +var THUMBS_MAX_TIME_TO_SHOW = 240; // how much time the thumb charts will present?
8 +var THUMBS_POINTS_DIVISOR = 3;
9 +var THUMBS_STACKED_POINTS_DIVISOR = 3;
10
11 -var GROUPS_MAX_TIME_TO_SHOW = 600; // how much time the thumb charts will present?
12 -var GROUPS_POINTS_DIVISOR = 4;
13 -var GROUPS_STACKED_POINTS_DIVISOR = 10;
11 +var GROUPS_MAX_TIME_TO_SHOW = 120; // how much time the thumb charts will present?
12 +var GROUPS_POINTS_DIVISOR = 2;
13 +var GROUPS_STACKED_POINTS_DIVISOR = 2;
14
15 var MAINCHART_MAX_TIME_TO_SHOW = 600; // how much time the main chart will present by default?
16 var MAINCHART_POINTS_DIVISOR = 5; // how much detailed will the main chart be by default? 1 = finest, higher is faster