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