{NULL, NULL, NULL, 0, NULL, NULL, NULL}
};
+int killpid(pid_t pid, int sig)
+{
+ int ret = -1;
+ debug(D_EXIT, "Request to kill pid %d", pid);
+
+ errno = 0;
+ if(kill(pid, 0) == -1) {
+ switch(errno) {
+ case ESRCH:
+ error("Request to kill pid %d, but it is not running.", pid);
+ break;
+
+ case EPERM:
+ error("Request to kill pid %d, but I do not have enough permissions.", pid);
+ break;
+
+ default:
+ error("Request to kill pid %d, but I received an error.", pid);
+ break;
+ }
+ }
+ else {
+ errno = 0;
+
+ void (*old)(int);
+ old = signal(sig, SIG_IGN);
+ if(old == SIG_ERR) {
+ error("Cannot overwrite signal handler for signal %d", sig);
+ old = sig_handler;
+ }
+
+ ret = kill(pid, sig);
+
+ if(signal(sig, old) == SIG_ERR)
+ error("Cannot restore signal handler for signal %d", sig);
+
+ if(ret == -1) {
+ switch(errno) {
+ case ESRCH:
+ error("Cannot kill pid %d, but it is not running.", pid);
+ break;
+
+ case EPERM:
+ error("Cannot kill pid %d, but I do not have enough permissions.", pid);
+ break;
+
+ default:
+ error("Cannot kill pid %d, but I received an error.", pid);
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
void kill_childs()
{
siginfo_t info;
}
if(tc_child_pid) {
- if(kill(tc_child_pid, 0) != -1) {
- info("Killing tc-qos-helper procees");
- kill(tc_child_pid, SIGTERM);
+ info("Killing tc-qos-helper procees");
+ if(killpid(tc_child_pid, SIGTERM) != -1)
waitid(tc_child_pid, 0, &info, WEXITED);
- }
}
tc_child_pid = 0;
pthread_join(cd->thread, NULL);
if(cd->pid && !cd->obsolete) {
- if(kill(cd->pid, 0) != -1) {
- debug(D_EXIT, "killing %s plugin process", cd->id);
- kill(cd->pid, SIGTERM);
+ debug(D_EXIT, "killing %s plugin process", cd->id);
+ if(killpid(cd->pid, SIGTERM) != -1)
waitid(cd->pid, 0, &info, WEXITED);
- }
}
}
#include <stdlib.h>
#include <signal.h>
+#include "main.h"
#include "common.h"
#include "config.h"
#include "log.h"
break;
}
+ info("PLUGINSD: '%s' running on pid %d", cd->fullfilename, cd->pid);
+
RRDSET *st = NULL;
unsigned long long count = 0;
char *s;
if(!dimension || !*dimension) {
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>");
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!st) {
error("PLUGINSD: '%s' is requesting a SET on dimension %s with value %s, without a BEGIN. Disabling it.", cd->fullfilename, dimension, value);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!id) {
error("PLUGINSD: '%s' is requesting a BEGIN without a chart id. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!st) {
error("PLUGINSD: '%s' is requesting a BEGIN on chart '%s', which does not exist. Disabling it.", cd->fullfilename, id);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!st) {
error("PLUGINSD: '%s' is requesting an END, without a BEGIN. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!type || !*type || !id || !*id) {
error("PLUGINSD: '%s' is requesting a CHART, without a type.id. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!id || !*id) {
error("PLUGINSD: '%s' is requesting a DIMENSION, without an id. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
if(!st) {
error("PLUGINSD: '%s' is requesting a DIMENSION, without a CHART. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
else if(hash == DISABLE_HASH && !strcmp(s, "DISABLE")) {
error("PLUGINSD: '%s' called DISABLE. Disabling it.", cd->fullfilename);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
#ifdef DETACH_PLUGINS_FROM_NETDATA
error("PLUGINSD: %s sleeping for %llu. Will kill with SIGCONT pid %d to wake it up.\n", cd->fullfilename, susec, cd->pid);
usleep(susec);
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGCONT);
+ killpid(cd->pid, SIGCONT);
bcopy(&now, &last, sizeof(struct timeval));
break;
}
else {
error("PLUGINSD: '%s' is sending command '%s' which is not known by netdata. Disabling it.", cd->fullfilename, s);
cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ killpid(cd->pid, SIGTERM);
break;
}
}
+ info("PLUGINSD: '%s' on pid %d stopped.", cd->fullfilename, cd->pid);
+
// fgets() failed or loop broke
mypclose(fp, cd->pid);
- cd->pid = 0;
if(!count && cd->enabled) {
- error("PLUGINSD: '%s' does not generate usefull output. Disabling it.", cd->fullfilename);
- cd->enabled = 0;
- // test: killing an exited child kills us - lets check it exists before killing it
- if(kill(cd->pid, 0) != -1) kill(cd->pid, SIGTERM);
+ error("PLUGINSD: '%s' (pid %d) does not generate usefull output. Waiting a bit before starting it again.", cd->fullfilename, cd->pid);
+ sleep(cd->update_every * 10);
}
+ cd->pid = 0;
+
if(cd->enabled) sleep(cd->update_every);
else break;
}