]> arthur.barton.de Git - netdata.git/blobdiff - src/plugins_d.c
added pthread_exit in hope it will solve the crash at exit
[netdata.git] / src / plugins_d.c
index 584268b9037aac9805bd87fd091778cc4ebc7517..b4cb57888d7c52296bb6a7af1eb610ff3ffad894 100755 (executable)
@@ -125,6 +125,8 @@ void *pluginsd_worker_thread(void *arg)
 #endif
 
        while(likely(1)) {
+               if(unlikely(netdata_exit)) break;
+
                FILE *fp = mypopen(cd->cmd, &cd->pid);
                if(unlikely(!fp)) {
                        error("Cannot popen(\"%s\", \"r\").", cd->cmd);
@@ -139,6 +141,8 @@ void *pluginsd_worker_thread(void *arg)
                uint32_t hash;
 
                while(likely(fgets(line, PLUGINSD_LINE_MAX, fp) != NULL)) {
+                       if(unlikely(netdata_exit)) break;
+
                        line[PLUGINSD_LINE_MAX] = '\0';
 
                        // debug(D_PLUGINSD, "PLUGINSD: %s: %s", cd->filename, line);
@@ -224,8 +228,12 @@ void *pluginsd_worker_thread(void *arg)
                                st = NULL;
                        }
                        else if(likely(hash == CHART_HASH && !strcmp(s, "CHART"))) {
+                               int noname = 0;
                                st = NULL;
 
+                               if((words[1]) != NULL && (words[2]) != NULL && strcmp(words[1], words[2]) == 0)
+                                       noname = 1;
+
                                char *type = words[1];
                                char *id = NULL;
                                if(likely(type)) {
@@ -258,7 +266,7 @@ void *pluginsd_worker_thread(void *arg)
                                int chart_type = RRDSET_TYPE_LINE;
                                if(unlikely(chart)) chart_type = rrdset_type_id(chart);
 
-                               if(unlikely(!name || !*name)) name = NULL;
+                               if(unlikely(noname || !name || !*name || strcasecmp(name, "NULL") == 0 || strcasecmp(name, "(NULL)") == 0)) name = NULL;
                                if(unlikely(!family || !*family)) family = id;
                                if(unlikely(!category || !*category)) category = type;
 
@@ -287,7 +295,7 @@ void *pluginsd_worker_thread(void *arg)
                                char *algorithm = words[3];
                                char *multiplier_s = words[4];
                                char *divisor_s = words[5];
-                               char *hidden = words[6];
+                               char *options = words[6];
 
                                if(unlikely(!id || !*id)) {
                                        error("PLUGINSD: '%s' is requesting a DIMENSION, without an id. Disabling it.", cd->fullfilename);
@@ -320,13 +328,18 @@ void *pluginsd_worker_thread(void *arg)
                                        , rrddim_algorithm_name(rrddim_algorithm_id(algorithm))
                                        , multiplier
                                        , divisor
-                                       , hidden?hidden:""
+                                       , options?options:""
                                        );
 
                                RRDDIM *rd = rrddim_find(st, id);
                                if(unlikely(!rd)) {
                                        rd = rrddim_add(st, id, name, multiplier, divisor, rrddim_algorithm_id(algorithm));
-                                       if(unlikely(hidden && strcmp(hidden, "hidden") == 0)) rd->hidden = 1;
+                                       rd->flags = 0x00000000;
+                                       if(options && *options) {
+                                               if(strstr(options, "hidden") != NULL) rd->flags |= RRDDIM_FLAG_HIDDEN;
+                                               if(strstr(options, "noreset") != NULL) rd->flags |= RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS;
+                                               if(strstr(options, "nooverflow") != NULL) rd->flags |= RRDDIM_FLAG_DONT_DETECT_RESETS_OR_OVERFLOWS;
+                                       }
                                }
                                else if(unlikely(st->debug)) debug(D_PLUGINSD, "PLUGINSD: dimension %s/%s already exists. Not adding it again.", st->id, id);
                        }
@@ -378,20 +391,34 @@ void *pluginsd_worker_thread(void *arg)
                info("PLUGINSD: '%s' on pid %d stopped.", cd->fullfilename, cd->pid);
 
                // fgets() failed or loop broke
-               mypclose(fp, cd->pid);
+               int code = mypclose(fp, cd->pid);
+               if(code == 1 || code == 127) {
+                       // 1 = DISABLE
+                       // 127 = cannot even run it
+                       error("PLUGINSD: '%s' (pid %d) exited with code %d. Disabling it.", cd->fullfilename, cd->pid, code);
+                       cd->enabled = 0;
+               }
+
+               if(netdata_exit) {
+                       cd->pid = 0;
+                       cd->enabled = 0;
+                       cd->obsolete = 1;
+                       pthread_exit(NULL);
+                       return NULL;
+               }
 
                if(unlikely(!count && cd->enabled)) {
                        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);
+                       sleep((unsigned int) (cd->update_every * 10));
                }
 
                cd->pid = 0;
-
-               if(likely(cd->enabled)) sleep(cd->update_every);
+               if(likely(cd->enabled)) sleep((unsigned int) cd->update_every);
                else break;
        }
 
        cd->obsolete = 1;
+       pthread_exit(NULL);
        return NULL;
 }
 
@@ -409,7 +436,7 @@ void *pluginsd_main(void *ptr)
 
        char *dir_name = config_get("plugins", "plugins directory", PLUGINS_DIR);
        int automatic_run = config_get_boolean("plugins", "enable running new plugins", 1);
-       int scan_frequency = config_get_number("plugins", "check for new plugins every", 60);
+       int scan_frequency = (int) config_get_number("plugins", "check for new plugins every", 60);
        DIR *dir = NULL;
        struct dirent *file = NULL;
        struct plugind *cd;
@@ -420,18 +447,23 @@ void *pluginsd_main(void *ptr)
        if(scan_frequency < 1) scan_frequency = 1;
 
        while(likely(1)) {
+               if(unlikely(netdata_exit)) break;
+
                dir = opendir(dir_name);
                if(unlikely(!dir)) {
                        error("Cannot open directory '%s'.", dir_name);
+                       pthread_exit(NULL);
                        return NULL;
                }
 
                while(likely((file = readdir(dir)))) {
+                       if(unlikely(netdata_exit)) break;
+
                        debug(D_PLUGINSD, "PLUGINSD: Examining file '%s'", file->d_name);
 
                        if(unlikely(strcmp(file->d_name, ".") == 0 || strcmp(file->d_name, "..") == 0)) continue;
 
-                       int len = strlen(file->d_name);
+                       int len = (int) strlen(file->d_name);
                        if(unlikely(len <= (int)PLUGINSD_FILE_SUFFIX_LEN)) continue;
                        if(unlikely(strcmp(PLUGINSD_FILE_SUFFIX, &file->d_name[len - (int)PLUGINSD_FILE_SUFFIX_LEN]) != 0)) {
                                debug(D_PLUGINSD, "PLUGINSD: File '%s' does not end in '%s'.", file->d_name, PLUGINSD_FILE_SUFFIX);
@@ -463,12 +495,12 @@ void *pluginsd_main(void *ptr)
                                if(unlikely(!cd)) fatal("Cannot allocate memory for plugin.");
 
                                snprintf(cd->id, CONFIG_MAX_NAME, "plugin:%s", pluginname);
-                               
+
                                strncpy(cd->filename, file->d_name, FILENAME_MAX);
                                snprintf(cd->fullfilename, FILENAME_MAX, "%s/%s", dir_name, cd->filename);
 
                                cd->enabled = enabled;
-                               cd->update_every = config_get_number(cd->id, "update every", rrd_update_every);
+                               cd->update_every = (int) config_get_number(cd->id, "update every", rrd_update_every);
                                cd->started_t = time(NULL);
 
                                char *def = "";
@@ -492,9 +524,10 @@ void *pluginsd_main(void *ptr)
                }
 
                closedir(dir);
-               sleep(scan_frequency);
+               sleep((unsigned int) scan_frequency);
        }
 
+       pthread_exit(NULL);
        return NULL;
 }