@cryptotaxi247 / netdata-1 / commits / ed321f3f3

fix for self-kill

Costa Tsaousis (ktsaou) committed Sep 14, 2015 at 21:26 UTC ed321f3f375edd6154f895a434682c006b27a1c2
4 files changed +83 -35
src/main.c
+60 -8
@@ -60,6 +60,62 @@ struct netdata_static_thread static_threads[] = {
60 {NULL, NULL, NULL, 0, NULL, NULL, NULL}
61 };
62
63 +int killpid(pid_t pid, int sig)
64 +{
65 + int ret = -1;
66 + debug(D_EXIT, "Request to kill pid %d", pid);
67 +
68 + errno = 0;
69 + if(kill(pid, 0) == -1) {
70 + switch(errno) {
71 + case ESRCH:
72 + error("Request to kill pid %d, but it is not running.", pid);
73 + break;
74 +
75 + case EPERM:
76 + error("Request to kill pid %d, but I do not have enough permissions.", pid);
77 + break;
78 +
79 + default:
80 + error("Request to kill pid %d, but I received an error.", pid);
81 + break;
82 + }
83 + }
84 + else {
85 + errno = 0;
86 +
87 + void (*old)(int);
88 + old = signal(sig, SIG_IGN);
89 + if(old == SIG_ERR) {
90 + error("Cannot overwrite signal handler for signal %d", sig);
91 + old = sig_handler;
92 + }
93 +
94 + ret = kill(pid, sig);
95 +
96 + if(signal(sig, old) == SIG_ERR)
97 + error("Cannot restore signal handler for signal %d", sig);
98 +
99 + if(ret == -1) {
100 + switch(errno) {
101 + case ESRCH:
102 + error("Cannot kill pid %d, but it is not running.", pid);
103 + break;
104 +
105 + case EPERM:
106 + error("Cannot kill pid %d, but I do not have enough permissions.", pid);
107 + break;
108 +
109 + default:
110 + error("Cannot kill pid %d, but I received an error.", pid);
111 + break;
112 + }
113 + }
114 + }
115 +
116 + return ret;
117 +}
118 +
119 void kill_childs()
120 {
121 siginfo_t info;
@@ -82,11 +138,9 @@ void kill_childs()
138 }
139
140 if(tc_child_pid) {
85 - if(kill(tc_child_pid, 0) != -1) {
86 - info("Killing tc-qos-helper procees");
87 - kill(tc_child_pid, SIGTERM);
141 + info("Killing tc-qos-helper procees");
142 + if(killpid(tc_child_pid, SIGTERM) != -1)
143 waitid(tc_child_pid, 0, &info, WEXITED);
89 - }
144 }
145 tc_child_pid = 0;
146
@@ -97,11 +151,9 @@ void kill_childs()
151 pthread_join(cd->thread, NULL);
152
153 if(cd->pid && !cd->obsolete) {
100 - if(kill(cd->pid, 0) != -1) {
101 - debug(D_EXIT, "killing %s plugin process", cd->id);
102 - kill(cd->pid, SIGTERM);
154 + debug(D_EXIT, "killing %s plugin process", cd->id);
155 + if(killpid(cd->pid, SIGTERM) != -1)
156 waitid(cd->pid, 0, &info, WEXITED);
104 - }
157 }
158 }
159
src/main.h
+1
@@ -2,5 +2,6 @@
2 #define NETDATA_MAIN_H 1
3
4 extern void kill_childs(void);
5 +extern int killpid(pid_t pid, int signal);
6
7 #endif /* NETDATA_MAIN_H */
src/plugins_d.c
+20 -27
@@ -6,6 +6,7 @@
6 #include <stdlib.h>
7 #include <signal.h>
8
9 +#include "main.h"
10 #include "common.h"
11 #include "config.h"
12 #include "log.h"
@@ -124,6 +125,8 @@ void *pluginsd_worker_thread(void *arg)
125 break;
126 }
127
128 + info("PLUGINSD: '%s' running on pid %d", cd->fullfilename, cd->pid);
129 +
130 RRDSET *st = NULL;
131 unsigned long long count = 0;
132 char *s;
@@ -152,8 +155,7 @@ void *pluginsd_worker_thread(void *arg)
155 if(!dimension || !*dimension) {
156 error("PLUGINSD: '%s' is requesting a SET on chart '%s', like this: 'SET %s = %s'. Disabling it.", cd->fullfilename, st->id, dimension?dimension:"<nothing>", value?value:"<nothing>");
157 cd->enabled = 0;
155 - // test: killing an exited child kills us - lets check it exists before killing it
156 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
158 + killpid(cd->pid, SIGTERM);
159 break;
160 }
161
@@ -162,8 +164,7 @@ void *pluginsd_worker_thread(void *arg)
164 if(!st) {
165 error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value);
166 cd->enabled = 0;
165 - // test: killing an exited child kills us - lets check it exists before killing it
166 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
167 + killpid(cd->pid, SIGTERM);
168 break;
169 }
170
@@ -179,8 +180,7 @@ void *pluginsd_worker_thread(void *arg)
180 if(!id) {
181 error("PLUGINSD: '%s' is requesting a BEGIN without a chart id. Disabling it.", cd->fullfilename);
182 cd->enabled = 0;
182 - // test: killing an exited child kills us - lets check it exists before killing it
183 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
183 + killpid(cd->pid, SIGTERM);
184 break;
185 }
186
@@ -188,8 +188,7 @@ void *pluginsd_worker_thread(void *arg)
188 if(!st) {
189 error("PLUGINSD: '%s' is requesting a BEGIN on chart '%s', which does not exist. Disabling it.", cd->fullfilename, id);
190 cd->enabled = 0;
191 - // test: killing an exited child kills us - lets check it exists before killing it
192 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
191 + killpid(cd->pid, SIGTERM);
192 break;
193 }
194
@@ -204,8 +203,7 @@ void *pluginsd_worker_thread(void *arg)
203 if(!st) {
204 error("PLUGINSD: '%s' is requesting an END, without a BEGIN. Disabling it.", cd->fullfilename);
205 cd->enabled = 0;
207 - // test: killing an exited child kills us - lets check it exists before killing it
208 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
206 + killpid(cd->pid, SIGTERM);
207 break;
208 }
209
@@ -239,8 +237,7 @@ void *pluginsd_worker_thread(void *arg)
237 if(!type || !*type || !id || !*id) {
238 error("PLUGINSD: '%s' is requesting a CHART, without a type.id. Disabling it.", cd->fullfilename);
239 cd->enabled = 0;
242 - // test: killing an exited child kills us - lets check it exists before killing it
243 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
240 + killpid(cd->pid, SIGTERM);
241 break;
242 }
243
@@ -288,16 +285,14 @@ void *pluginsd_worker_thread(void *arg)
285 if(!id || !*id) {
286 error("PLUGINSD: '%s' is requesting a DIMENSION, without an id. Disabling it.", cd->fullfilename);
287 cd->enabled = 0;
291 - // test: killing an exited child kills us - lets check it exists before killing it
292 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
288 + killpid(cd->pid, SIGTERM);
289 break;
290 }
291
292 if(!st) {
293 error("PLUGINSD: '%s' is requesting a DIMENSION, without a CHART. Disabling it.", cd->fullfilename);
294 cd->enabled = 0;
299 - // test: killing an exited child kills us - lets check it exists before killing it
300 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
295 + killpid(cd->pid, SIGTERM);
296 break;
297 }
298
@@ -331,8 +326,7 @@ void *pluginsd_worker_thread(void *arg)
326 else if(hash == DISABLE_HASH && !strcmp(s, "DISABLE")) {
327 error("PLUGINSD: '%s' called DISABLE. Disabling it.", cd->fullfilename);
328 cd->enabled = 0;
334 - // test: killing an exited child kills us - lets check it exists before killing it
335 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
329 + killpid(cd->pid, SIGTERM);
330 break;
331 }
332 #ifdef DETACH_PLUGINS_FROM_NETDATA
@@ -361,8 +355,7 @@ void *pluginsd_worker_thread(void *arg)
355
356 error("PLUGINSD: %s sleeping for %llu. Will kill with SIGCONT pid %d to wake it up.\n", cd->fullfilename, susec, cd->pid);
357 usleep(susec);
364 - // test: killing an exited child kills us - lets check it exists before killing it
365 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGCONT);
358 + killpid(cd->pid, SIGCONT);
359 bcopy(&now, &last, sizeof(struct timeval));
360 break;
361 }
@@ -370,23 +363,23 @@ void *pluginsd_worker_thread(void *arg)
363 else {
364 error("PLUGINSD: '%s' is sending command '%s' which is not known by netdata. Disabling it.", cd->fullfilename, s);
365 cd->enabled = 0;
373 - // test: killing an exited child kills us - lets check it exists before killing it
374 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
366 + killpid(cd->pid, SIGTERM);
367 break;
368 }
369 }
370
371 + info("PLUGINSD: '%s' on pid %d stopped.", cd->fullfilename, cd->pid);
372 +
373 // fgets() failed or loop broke
374 mypclose(fp, cd->pid);
381 - cd->pid = 0;
375
376 if(!count && cd->enabled) {
384 - error("PLUGINSD: '%s' does not generate usefull output. Disabling it.", cd->fullfilename);
385 - cd->enabled = 0;
386 - // test: killing an exited child kills us - lets check it exists before killing it
387 - if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
377 + error("PLUGINSD: '%s' (pid %d) does not generate usefull output. Waiting a bit before starting it again.", cd->fullfilename, cd->pid);
378 + sleep(cd->update_every * 10);
379 }
380
381 + cd->pid = 0;
382 +
383 if(cd->enabled) sleep(cd->update_every);
384 else break;
385 }
src/popen.c
+2
@@ -117,6 +117,8 @@ FILE *mypopen(const char *command, pid_t *pidptr)
117 }
118
119 void mypclose(FILE *fp, pid_t pid) {
120 + debug(D_EXIT, "Request to mypclose() on pid %d", pid);
121 +
122 /*mypopen_del(fp);*/
123 fclose(fp);
124