]> arthur.barton.de Git - netdata.git/commitdiff
added index in rrdset names too; fixed crash in apps.plugin
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 22 Mar 2015 22:03:39 +0000 (00:03 +0200)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Sun, 22 Mar 2015 22:03:39 +0000 (00:03 +0200)
src/Makefile
src/config.c
src/main.c
src/plugins.d/Makefile
src/plugins.d/apps_plugin.c
src/rrd.c
src/rrd.h
src/rrd2json.c
src/web_server.c

index e282c529edfdcea41f082758d787d3b2d4af3757..644b616f421837c4609394ed93783a2f6d043549 100755 (executable)
@@ -18,6 +18,10 @@ ifndef nomath
 STORAGE_WITH_MATH = 1
 endif
 
+ifdef nofork
+NETDATA_NO_DAEMON = 1
+endif
+
 COMMON_FLAGS = BIN_DIR='$(BIN_DIR)' CONFIG_DIR='$(CONFIG_DIR)' LOG_DIR='$(LOG_DIR)' PLUGINS_DIR='$(PLUGINS_DIR)'
 
 proc_sources = proc_net_dev.c proc_net_ip_vs_stats.c proc_diskstats.c proc_meminfo.c proc_net_netstat.c proc_net_snmp.c proc_net_stat_conntrack.c proc_stat.c proc_vmstat.c proc_net_rpc_nfsd.c
@@ -40,6 +44,10 @@ CFLAGS += -DSTORAGE_WITH_MATH=1
 libs += -lm
 endif
 
+ifdef NETDATA_NO_DAEMON
+CFLAGS += -DNETDATA_NO_DAEMON=1
+endif
+
 # nfacct requires root access, so we prefer it as a plugin.d external plugin
 ifdef INTERNAL_PLUGIN_NFACCT
 CFLAGS += -DINTERNAL_PLUGIN_NFACCT=1
index 1afc0b8d26d98b63429cdd73cb6ba6c8795444e1..d8e53d919769d46dd840847665732ea368412865 100755 (executable)
@@ -21,7 +21,7 @@ pthread_rwlock_t config_rwlock = PTHREAD_RWLOCK_INITIALIZER;
 #define CONFIG_VALUE_CHECKED 0x08 // has been checked if the value is different from the default
 
 struct config_value {
-       avl avl;
+       avl avl;                                // the index - this has to be first!
 
        unsigned long hash;             // a simple hash to speed up searching
                                                        // we first compare hashes, and only if the hashes are equal we do string comparisons
index 9979b3e597c5768ab15459599728e32f91de7286..b05eceae63198c7df6ddfc80b3a95d66a6117527 100755 (executable)
@@ -286,11 +286,12 @@ int main(int argc, char **argv)
                fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
        }
 
+#ifndef NETDATA_NO_DAEMON
        if(become_daemon(0, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
                fprintf(stderr, "Cannot demonize myself (%s).", strerror(errno));
                exit(1);
        }
-
+#endif
 
        if(output_log_syslog || error_log_syslog || access_log_syslog)
                openlog("netdata", LOG_PID, LOG_DAEMON);
index bdfa3ff109823350a707752309c1031f0dc62835..f83a256c7dc32b654fe3b9f90164323aa1a9cf1c 100755 (executable)
@@ -22,7 +22,7 @@ libs :=
 ifdef debug\r
 COMMON_FLAGS += debug=1\r
 # CFLAGS = -Wall -Wextra -ggdb -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fsanitize=address -fno-omit-frame-pointer\r
-CFLAGS := -Wall -Wextra -O -g -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fsanitize=address -fno-omit-frame-pointer\r
+CFLAGS := -Wall -Wextra -O3 -ggdb -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fsanitize=address -fno-omit-frame-pointer\r
 #libs += -ltsan -lpie\r
 else\r
 CFLAGS := -Wall -Wextra -O3 -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fomit-frame-pointer\r
index e30e8b3b2827a82489aebc88f0b505f7989cba55..e62cde68b26544a20bcb031a83be9d6f7433dd02 100755 (executable)
@@ -557,10 +557,13 @@ void file_descriptor_not_used(int id)
                        return;
                }
 
+               if(debug) fprintf(stderr, "apps.plugin: decreasing slot %d (count = %ld).\n", id, all_files[id].count);
+
                if(all_files[id].count > 0) {
                        all_files[id].count--;
 
                        if(!all_files[id].count) {
+                               if(debug) fprintf(stderr, "apps.plugin:   >> slot %d is empty.\n", id);
                                file_descriptor_remove(&all_files[id]);
                                all_files[id].magic = 0x00000000;
                                all_files_len--;
@@ -582,6 +585,7 @@ unsigned long file_descriptor_find_or_add(const char *name)
        struct file_descriptor *fd = file_descriptor_find(name, hash);
        if(fd) {
                // found
+               if(debug) fprintf(stderr, "apps.plugin:   >> found on slot %ld\n", fd->pos);
                fd->count++;
                return fd->pos;
        }
@@ -598,19 +602,28 @@ unsigned long file_descriptor_find_or_add(const char *name)
                // if the address changed, we have to rebuild the index
                // since all pointers are now invalid
                if(old && old != (void *)all_files) {
-                       if(debug) fprintf(stderr, "apps.plugin: re-indexing.\n");
+                       if(debug) fprintf(stderr, "apps.plugin:   >> re-indexing.\n");
                        all_files_index.root = NULL;
                        int i;
                        for(i = 0; i < all_files_size; i++) {
                                if(!all_files[i].count) continue;
                                file_descriptor_add(&all_files[i]);
                        }
+                       for(i = all_files_size; i < (all_files_size + FILE_DESCRIPTORS_INCREASE_STEP); i++) {
+                               all_files[i].count = 0;
+                               all_files[i].name = NULL;
+                               all_files[i].magic = 0x00000000;
+                               all_files[i].pos = i;
+                       }
+                       if(debug) fprintf(stderr, "apps.plugin:   >> re-indexing done.\n");
                }
 
                if(!all_files_size) all_files_len = 1;
                all_files_size += FILE_DESCRIPTORS_INCREASE_STEP;
        }
 
+       if(debug) fprintf(stderr, "apps.plugin:   >> searching for empty slot.\n");
+
        // search for an empty slot
        int i, c;
        for(i = 0, c = last_pos ; i < all_files_size ; i++, c++) {
@@ -618,10 +631,12 @@ unsigned long file_descriptor_find_or_add(const char *name)
                if(c == 0) continue;
 
                if(!all_files[c].count) {
+                       if(debug) fprintf(stderr, "apps.plugin:   >> eximining slot %d.\n", c);
+
                        if(all_files[c].magic == 0x0BADCAFE && all_files[c].name && file_descriptor_find(all_files[c].name, all_files[c].hash))
                                error("apps.plugin: fd on position %d is not cleared properly. It still has %s in it.\n", c, all_files[c].name);
 
-                       if(debug) fprintf(stderr, "apps.plugin: re-using fd position %d for %s (last name: %s)\n", c, name, all_files[c].name);
+                       if(debug) fprintf(stderr, "apps.plugin:   >> %s fd position %d for %s (last name: %s)\n", all_files[c].name?"re-using":"using", c, name, all_files[c].name);
                        if(all_files[c].name) free((void *)all_files[c].name);
                        all_files[c].name = NULL;
                        break;
@@ -631,6 +646,8 @@ unsigned long file_descriptor_find_or_add(const char *name)
                error("We should find an empty slot, but there isn't any");
                return 0;
        }
+       if(debug) fprintf(stderr, "apps.plugin:   >> updating slot %d.\n", c);
+
        all_files_len++;
 
        // else we have an empty slot in 'c'
index 8675f84410cf39768f559534f69e385df2266988..10999e82dac3806e14836f634c8723537e13672b 100755 (executable)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -1,3 +1,4 @@
+#include <stddef.h>
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
@@ -57,6 +58,57 @@ static RRDSET *rrdset_index_find(const char *id, unsigned long hash) {
        return result;
 }
 
+// ----------------------------------------------------------------------------
+// RRDSET name index
+
+#define rrdset_from_avlname(avlname_ptr) ((RRDSET *)((avlname_ptr) - offsetof(RRDSET, avlname)))
+
+static int rrdset_iterator_name(avl *a) { if(a) {}; return 0; }
+
+static int rrdset_compare_name(void* a, void* b) {
+       RRDSET *A = rrdset_from_avlname(a);
+       RRDSET *B = rrdset_from_avlname(b);
+
+       // fprintf(stderr, "COMPARING: %s with %s\n", A->name, B->name);
+
+       if(A->hash_name < B->hash_name) return -1;
+       else if(A->hash_name > B->hash_name) return 1;
+       else return strcmp(A->name, B->name);
+}
+
+avl_tree rrdset_root_index_name = {
+               NULL,
+               rrdset_compare_name
+};
+
+int rrdset_index_add_name(RRDSET *st) {
+       // fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
+       return avl_insert(&rrdset_root_index_name, (avl *)(&st->avlname));
+}
+
+#define rrdset_index_del_name(st) avl_remove(&rrdset_root_index_name, (avl *)(&st->avlname))
+
+static RRDSET *rrdset_index_find_name(const char *name, unsigned long hash) {
+       void *result = NULL;
+       RRDSET tmp;
+       tmp.name = name;
+       tmp.hash_name = (hash)?hash:simple_hash(tmp.name);
+
+       // fprintf(stderr, "SEARCHING: %s\n", name);
+       avl_search(&(rrdset_root_index_name), (avl *)(&(tmp.avlname)), rrdset_iterator_name, (avl **)&result);
+       if(result) {
+               RRDSET *st = rrdset_from_avlname(result);
+               if(strcmp(st->magic, RRDSET_MAGIC))
+                       error("Search for RRDSET %s returned an invalid RRDSET %s (name %s)", name, st->id, st->name);
+
+               // fprintf(stderr, "FOUND: %s\n", name);
+               return rrdset_from_avlname(result);
+       }
+       // fprintf(stderr, "NOT FOUND: %s\n", name);
+       return NULL;
+}
+
+
 // ----------------------------------------------------------------------------
 // RRDDIM index
 
@@ -199,6 +251,10 @@ char *rrdset_strncpy_name(char *to, const char *from, int length)
 
 void rrdset_set_name(RRDSET *st, const char *name)
 {
+       debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
+
+       if(st->name) rrdset_index_del_name(st);
+
        char b[CONFIG_MAX_VALUE + 1];
        char n[RRD_ID_LENGTH_MAX + 1];
 
@@ -206,6 +262,8 @@ void rrdset_set_name(RRDSET *st, const char *name)
        rrdset_strncpy_name(b, n, CONFIG_MAX_VALUE);
        st->name = config_get(st->id, "name", b);
        st->hash_name = simple_hash(st->name);
+
+       rrdset_index_add_name(st);
 }
 
 // ----------------------------------------------------------------------------
@@ -239,6 +297,8 @@ char *rrdset_cache_dir(const char *id)
 
 void rrdset_reset(RRDSET *st)
 {
+       debug(D_RRD_CALLS, "rrdset_reset() %s", st->name);
+
        st->last_collected_time.tv_sec = 0;
        st->last_collected_time.tv_usec = 0;
        st->last_updated.tv_sec = 0;
@@ -347,15 +407,6 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
        st->type       = config_get(st->id, "type", type);
        st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type)));
 
-       if(name && *name) rrdset_set_name(st, name);
-       else rrdset_set_name(st, id);
-
-       {
-               char varvalue[CONFIG_MAX_VALUE + 1];
-               snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
-               st->title = config_get(st->id, "title", varvalue);
-       }
-
        st->priority = config_get_number(st->id, "priority", priority);
        st->enabled = enabled;
        
@@ -374,6 +425,15 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
        pthread_rwlock_init(&st->rwlock, NULL);
        pthread_rwlock_wrlock(&rrdset_root_rwlock);
 
+       if(name && *name) rrdset_set_name(st, name);
+       else rrdset_set_name(st, id);
+
+       {
+               char varvalue[CONFIG_MAX_VALUE + 1];
+               snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
+               st->title = config_get(st->id, "title", varvalue);
+       }
+
        st->next = rrdset_root;
        rrdset_root = st;
 
@@ -503,6 +563,8 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
 
 void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
 {
+       debug(D_RRD_CALLS, "rrddim_set_name() %s.%s", st->name, rd->name);
+
        char varname[CONFIG_MAX_NAME + 1];
        snprintf(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
        config_get(st->id, varname, name);
@@ -510,6 +572,8 @@ void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
 
 void rrddim_free(RRDSET *st, RRDDIM *rd)
 {
+       debug(D_RRD_CALLS, "rrddim_free() %s.%s", st->name, rd->name);
+
        RRDDIM *i = st->dimensions, *last = NULL;
        for(i = st->dimensions; i && i != rd ; i = i->next) last = i;
 
@@ -577,6 +641,8 @@ void rrdset_free_all(void)
 
 void rrdset_save_all(void)
 {
+       debug(D_RRD_CALLS, "rrdset_save_all()");
+
        RRDSET *st;
        RRDDIM *rd;
 
@@ -604,7 +670,7 @@ void rrdset_save_all(void)
 
 RRDSET *rrdset_find(const char *id)
 {
-       debug(D_RRD_CALLS, "rrd_stats_find() for chart %s", id);
+       debug(D_RRD_CALLS, "rrdset_find() for chart %s", id);
 
        pthread_rwlock_rdlock(&rrdset_root_rwlock);
        RRDSET *st = rrdset_index_find(id, 0);
@@ -615,7 +681,7 @@ RRDSET *rrdset_find(const char *id)
 
 RRDSET *rrdset_find_bytype(const char *type, const char *id)
 {
-       debug(D_RRD_CALLS, "rrd_stats_find_bytype() for chart %s.%s", type, id);
+       debug(D_RRD_CALLS, "rrdset_find_bytype() for chart %s.%s", type, id);
 
        char buf[RRD_ID_LENGTH_MAX + 1];
 
@@ -631,18 +697,10 @@ RRDSET *rrdset_find_bytype(const char *type, const char *id)
 
 RRDSET *rrdset_find_byname(const char *name)
 {
-       debug(D_RRD_CALLS, "rrd_stats_find_byname() for chart %s", name);
-
-       char b[CONFIG_MAX_VALUE + 1];
-
-       rrdset_strncpy_name(b, name, CONFIG_MAX_VALUE);
-       unsigned long hash = simple_hash(b);
+       debug(D_RRD_CALLS, "rrdset_find_byname() for chart %s", name);
 
        pthread_rwlock_rdlock(&rrdset_root_rwlock);
-       RRDSET *st = rrdset_root;
-       for ( ; st ; st = st->next ) {
-               if(hash == st->hash_name && strcmp(st->name, b) == 0) break;
-       }
+       RRDSET *st = rrdset_index_find_name(name, 0);
        pthread_rwlock_unlock(&rrdset_root_rwlock);
 
        return(st);
@@ -650,14 +708,14 @@ RRDSET *rrdset_find_byname(const char *name)
 
 RRDDIM *rrddim_find(RRDSET *st, const char *id)
 {
-       debug(D_RRD_CALLS, "rrd_stats_dimension_find() for chart %s, dimension %s", st->name, id);
+       debug(D_RRD_CALLS, "rrddim_find() for chart %s, dimension %s", st->name, id);
 
        return rrddim_index_find(st, id, 0);
 }
 
 int rrddim_hide(RRDSET *st, const char *id)
 {
-       debug(D_RRD_CALLS, "rrd_stats_dimension_hide() for chart %s, dimension %s", st->name, id);
+       debug(D_RRD_CALLS, "rrddim_hide() for chart %s, dimension %s", st->name, id);
 
        RRDDIM *rd = rrddim_find(st, id);
        if(!rd) {
@@ -671,7 +729,7 @@ int rrddim_hide(RRDSET *st, const char *id)
 
 void rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value)
 {
-       debug(D_RRD_CALLS, "rrd_stats_dimension_set() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
+       debug(D_RRD_CALLS, "rrddim_set_by_pointer() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
        
        gettimeofday(&rd->last_collected_time, NULL);
        rd->collected_value = value;
@@ -692,7 +750,7 @@ int rrddim_set(RRDSET *st, const char *id, collected_number value)
 
 void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
 {
-       debug(D_RRD_CALLS, "rrd_stats_next() for chart %s with microseconds %llu", st->name, microseconds);
+       debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
 
        if(st->debug) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
        st->usec_since_last_update = microseconds;
@@ -718,7 +776,7 @@ void rrdset_next_plugins(RRDSET *st)
 
 unsigned long long rrdset_done(RRDSET *st)
 {
-       debug(D_RRD_CALLS, "rrd_stats_done() for chart %s", st->name);
+       debug(D_RRD_CALLS, "rrdset_done() for chart %s", st->name);
 
        RRDDIM *rd, *last;
        int oldstate, store_this_entry = 1;
index a36f194c5aa3d98da0d385f273fde403fa885164..6db79f6d40542471852788f260cdc79483058044 100755 (executable)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -78,10 +78,10 @@ extern const char *rrddim_algorithm_name(int chart_type);
 // RRD DIMENSION
 
 struct rrddim {
-       avl avl;
+       avl avl;                                                                                // the index - this has to be first!
 
        char magic[sizeof(RRDDIMENSION_MAGIC) + 1];             // our magic
-       char id[RRD_ID_LENGTH_MAX + 1];                                         // the id of this dimension (for internal identification)
+       char id[RRD_ID_LENGTH_MAX + 1];                                 // the id of this dimension (for internal identification)
        const char *name;                                                               // the name of this dimension (as presented to user)
        char cache_filename[FILENAME_MAX+1];
        
@@ -115,7 +115,7 @@ struct rrddim {
        calculated_number collected_volume;
        calculated_number stored_volume;
 
-       struct rrddim *next;                                            // linking of dimensions within the same data set
+       struct rrddim *next;                                                    // linking of dimensions within the same data set
 
        storage_number values[];                                                // the array of values - THIS HAS TO BE THE LAST MEMBER
 };
@@ -126,11 +126,12 @@ typedef struct rrddim RRDDIM;
 // RRDSET
 
 struct rrdset {
-       avl avl;
+       avl avl;                                                                                // the index, with key the id - this has to be first!
+       avl avlname;                                                                    // the index, with key the name
 
        char magic[sizeof(RRDSET_MAGIC) + 1];                   // our magic
 
-       char id[RRD_ID_LENGTH_MAX + 1];                                         // id of the data set
+       char id[RRD_ID_LENGTH_MAX + 1];                                 // id of the data set
        const char *name;                                                               // name of the data set
        char *cache_dir;                                                                // the directory to store dimension maps
        char cache_filename[FILENAME_MAX+1];
@@ -176,8 +177,7 @@ struct rrdset {
                                                                                                        // (the master data set should be the one that has the same family and is not detail)
 
        RRDDIM *dimensions;                                                             // the actual data for every dimension
-
-       avl_tree dimensions_index;
+       avl_tree dimensions_index;                                              // the root of the dimensions index
 
        struct rrdset *next;                                                    // linking of rrdsets
 };
index 12bb5dcae4b8cc2aa0d0a010c3a2ff2b0d3637c0..01478a623ef81e4aee51cd358d71565e9d6a6230 100755 (executable)
@@ -47,7 +47,7 @@ unsigned long rrd_stats_one_json(RRDSET *st, char *options, struct web_buffer *w
                , st->priority
                , st->enabled
                , st->units
-               , st->name, options?options:""
+               , st->id, options?options:""
                , rrdset_type_name(st->chart_type)
                , st->counter
                , st->entries
index 68ababbc55ef5ad6f04568470f6ac990cbc37d42..e25644e9370c94be88493678655c706bad28ef1e 100755 (executable)
@@ -275,8 +275,8 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
        debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
        // do we have such a data set?
-       RRDSET *st = rrdset_find_byname(tok);
-       if(!st) st = rrdset_find(tok);
+       RRDSET *st = rrdset_find(tok);
+       if(!st) st = rrdset_find_byname(tok);
        if(!st) {
                // we don't have it
                // try to send a file with that name
@@ -490,7 +490,8 @@ void web_client_process(struct web_client *w)
                                debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
                                // do we have such a data set?
-                               RRDSET *st = rrdset_find_byname(tok);
+                               RRDSET *st = rrdset_find(tok);
+                               if(!st) st = rrdset_find_byname(tok);
                                if(!st) {
                                        // we don't have it
                                        // try to send a file with that name
@@ -513,7 +514,8 @@ void web_client_process(struct web_client *w)
                                debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
 
                                // do we have such a data set?
-                               RRDSET *st = rrdset_find_byname(tok);
+                               RRDSET *st = rrdset_find(tok);
+                               if(!st) st = rrdset_find_byname(tok);
                                if(!st) {
                                        code = 404;
                                        web_buffer_printf(w->data, "Chart %s is not found.\r\n", tok);