@cryptotaxi247 / netdata-1 / commits / faebdc77e

added index in rrdset names too; fixed crash in apps.plugin

Costa Tsaousis (ktsaou) committed Mar 23, 2015 at 00:03 UTC faebdc77eef3b91b87150087dcf0293bda1515ab
9 files changed +129 -43
src/Makefile
+8
@@ -18,6 +18,10 @@ ifndef nomath
18 STORAGE_WITH_MATH = 1
19 endif
20
21 +ifdef nofork
22 +NETDATA_NO_DAEMON = 1
23 +endif
24 +
25 COMMON_FLAGS = BIN_DIR='$(BIN_DIR)' CONFIG_DIR='$(CONFIG_DIR)' LOG_DIR='$(LOG_DIR)' PLUGINS_DIR='$(PLUGINS_DIR)'
26
27 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
44 libs += -lm
45 endif
46
47 +ifdef NETDATA_NO_DAEMON
48 +CFLAGS += -DNETDATA_NO_DAEMON=1
49 +endif
50 +
51 # nfacct requires root access, so we prefer it as a plugin.d external plugin
52 ifdef INTERNAL_PLUGIN_NFACCT
53 CFLAGS += -DINTERNAL_PLUGIN_NFACCT=1
src/config.c
+1 -1
@@ -21,7 +21,7 @@ pthread_rwlock_t config_rwlock = PTHREAD_RWLOCK_INITIALIZER;
21 #define CONFIG_VALUE_CHECKED 0x08 // has been checked if the value is different from the default
22
23 struct config_value {
24 - avl avl;
24 + avl avl; // the index - this has to be first!
25
26 unsigned long hash; // a simple hash to speed up searching
27 // we first compare hashes, and only if the hashes are equal we do string comparisons
src/main.c
+2 -1
@@ -286,11 +286,12 @@ int main(int argc, char **argv)
286 fprintf(stderr, "Cannot lower my CPU priority. Error: %s.\n", strerror(errno));
287 }
288
289 +#ifndef NETDATA_NO_DAEMON
290 if(become_daemon(0, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
291 fprintf(stderr, "Cannot demonize myself (%s).", strerror(errno));
292 exit(1);
293 }
293 -
294 +#endif
295
296 if(output_log_syslog || error_log_syslog || access_log_syslog)
297 openlog("netdata", LOG_PID, LOG_DAEMON);
src/plugins.d/Makefile
+1 -1
@@ -22,7 +22,7 @@ libs :=
22 ifdef debug
23 COMMON_FLAGS += debug=1
24 # 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
25 -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
25 +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
26 #libs += -ltsan -lpie
27 else
28 CFLAGS := -Wall -Wextra -O3 -DBIN_DIR='$(BIN_DIR)' -DCONFIG_DIR='$(CONFIG_DIR)' -DLOG_DIR='$(LOG_DIR)' -DPLUGINS_DIR='$(PLUGINS_DIR)' -fomit-frame-pointer
src/plugins.d/apps_plugin.c
+19 -2
@@ -557,10 +557,13 @@ void file_descriptor_not_used(int id)
557 return;
558 }
559
560 + if(debug) fprintf(stderr, "apps.plugin: decreasing slot %d (count = %ld).\n", id, all_files[id].count);
561 +
562 if(all_files[id].count > 0) {
563 all_files[id].count--;
564
565 if(!all_files[id].count) {
566 + if(debug) fprintf(stderr, "apps.plugin: >> slot %d is empty.\n", id);
567 file_descriptor_remove(&all_files[id]);
568 all_files[id].magic = 0x00000000;
569 all_files_len--;
@@ -582,6 +585,7 @@ unsigned long file_descriptor_find_or_add(const char *name)
585 struct file_descriptor *fd = file_descriptor_find(name, hash);
586 if(fd) {
587 // found
588 + if(debug) fprintf(stderr, "apps.plugin: >> found on slot %ld\n", fd->pos);
589 fd->count++;
590 return fd->pos;
591 }
@@ -598,19 +602,28 @@ unsigned long file_descriptor_find_or_add(const char *name)
602 // if the address changed, we have to rebuild the index
603 // since all pointers are now invalid
604 if(old && old != (void *)all_files) {
601 - if(debug) fprintf(stderr, "apps.plugin: re-indexing.\n");
605 + if(debug) fprintf(stderr, "apps.plugin: >> re-indexing.\n");
606 all_files_index.root = NULL;
607 int i;
608 for(i = 0; i < all_files_size; i++) {
609 if(!all_files[i].count) continue;
610 file_descriptor_add(&all_files[i]);
611 }
612 + for(i = all_files_size; i < (all_files_size + FILE_DESCRIPTORS_INCREASE_STEP); i++) {
613 + all_files[i].count = 0;
614 + all_files[i].name = NULL;
615 + all_files[i].magic = 0x00000000;
616 + all_files[i].pos = i;
617 + }
618 + if(debug) fprintf(stderr, "apps.plugin: >> re-indexing done.\n");
619 }
620
621 if(!all_files_size) all_files_len = 1;
622 all_files_size += FILE_DESCRIPTORS_INCREASE_STEP;
623 }
624
625 + if(debug) fprintf(stderr, "apps.plugin: >> searching for empty slot.\n");
626 +
627 // search for an empty slot
628 int i, c;
629 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)
631 if(c == 0) continue;
632
633 if(!all_files[c].count) {
634 + if(debug) fprintf(stderr, "apps.plugin: >> eximining slot %d.\n", c);
635 +
636 if(all_files[c].magic == 0x0BADCAFE && all_files[c].name && file_descriptor_find(all_files[c].name, all_files[c].hash))
637 error("apps.plugin: fd on position %d is not cleared properly. It still has %s in it.\n", c, all_files[c].name);
638
624 - if(debug) fprintf(stderr, "apps.plugin: re-using fd position %d for %s (last name: %s)\n", c, name, all_files[c].name);
639 + 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);
640 if(all_files[c].name) free((void *)all_files[c].name);
641 all_files[c].name = NULL;
642 break;
@@ -631,6 +646,8 @@ unsigned long file_descriptor_find_or_add(const char *name)
646 error("We should find an empty slot, but there isn't any");
647 return 0;
648 }
649 + if(debug) fprintf(stderr, "apps.plugin: >> updating slot %d.\n", c);
650 +
651 all_files_len++;
652
653 // else we have an empty slot in 'c'
src/rrd.c
+84 -26
@@ -1,3 +1,4 @@
1 +#include <stddef.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <time.h>
@@ -57,6 +58,57 @@ static RRDSET *rrdset_index_find(const char *id, unsigned long hash) {
58 return result;
59 }
60
61 +// ----------------------------------------------------------------------------
62 +// RRDSET name index
63 +
64 +#define rrdset_from_avlname(avlname_ptr) ((RRDSET *)((avlname_ptr) - offsetof(RRDSET, avlname)))
65 +
66 +static int rrdset_iterator_name(avl *a) { if(a) {}; return 0; }
67 +
68 +static int rrdset_compare_name(void* a, void* b) {
69 + RRDSET *A = rrdset_from_avlname(a);
70 + RRDSET *B = rrdset_from_avlname(b);
71 +
72 + // fprintf(stderr, "COMPARING: %s with %s\n", A->name, B->name);
73 +
74 + if(A->hash_name < B->hash_name) return -1;
75 + else if(A->hash_name > B->hash_name) return 1;
76 + else return strcmp(A->name, B->name);
77 +}
78 +
79 +avl_tree rrdset_root_index_name = {
80 + NULL,
81 + rrdset_compare_name
82 +};
83 +
84 +int rrdset_index_add_name(RRDSET *st) {
85 + // fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
86 + return avl_insert(&rrdset_root_index_name, (avl *)(&st->avlname));
87 +}
88 +
89 +#define rrdset_index_del_name(st) avl_remove(&rrdset_root_index_name, (avl *)(&st->avlname))
90 +
91 +static RRDSET *rrdset_index_find_name(const char *name, unsigned long hash) {
92 + void *result = NULL;
93 + RRDSET tmp;
94 + tmp.name = name;
95 + tmp.hash_name = (hash)?hash:simple_hash(tmp.name);
96 +
97 + // fprintf(stderr, "SEARCHING: %s\n", name);
98 + avl_search(&(rrdset_root_index_name), (avl *)(&(tmp.avlname)), rrdset_iterator_name, (avl **)&result);
99 + if(result) {
100 + RRDSET *st = rrdset_from_avlname(result);
101 + if(strcmp(st->magic, RRDSET_MAGIC))
102 + error("Search for RRDSET %s returned an invalid RRDSET %s (name %s)", name, st->id, st->name);
103 +
104 + // fprintf(stderr, "FOUND: %s\n", name);
105 + return rrdset_from_avlname(result);
106 + }
107 + // fprintf(stderr, "NOT FOUND: %s\n", name);
108 + return NULL;
109 +}
110 +
111 +
112 // ----------------------------------------------------------------------------
113 // RRDDIM index
114
@@ -199,6 +251,10 @@ char *rrdset_strncpy_name(char *to, const char *from, int length)
251
252 void rrdset_set_name(RRDSET *st, const char *name)
253 {
254 + debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
255 +
256 + if(st->name) rrdset_index_del_name(st);
257 +
258 char b[CONFIG_MAX_VALUE + 1];
259 char n[RRD_ID_LENGTH_MAX + 1];
260
@@ -206,6 +262,8 @@ void rrdset_set_name(RRDSET *st, const char *name)
262 rrdset_strncpy_name(b, n, CONFIG_MAX_VALUE);
263 st->name = config_get(st->id, "name", b);
264 st->hash_name = simple_hash(st->name);
265 +
266 + rrdset_index_add_name(st);
267 }
268
269 // ----------------------------------------------------------------------------
@@ -239,6 +297,8 @@ char *rrdset_cache_dir(const char *id)
297
298 void rrdset_reset(RRDSET *st)
299 {
300 + debug(D_RRD_CALLS, "rrdset_reset() %s", st->name);
301 +
302 st->last_collected_time.tv_sec = 0;
303 st->last_collected_time.tv_usec = 0;
304 st->last_updated.tv_sec = 0;
@@ -347,15 +407,6 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
407 st->type = config_get(st->id, "type", type);
408 st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type)));
409
350 - if(name && *name) rrdset_set_name(st, name);
351 - else rrdset_set_name(st, id);
352 -
353 - {
354 - char varvalue[CONFIG_MAX_VALUE + 1];
355 - snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
356 - st->title = config_get(st->id, "title", varvalue);
357 - }
358 -
410 st->priority = config_get_number(st->id, "priority", priority);
411 st->enabled = enabled;
412
@@ -374,6 +425,15 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
425 pthread_rwlock_init(&st->rwlock, NULL);
426 pthread_rwlock_wrlock(&rrdset_root_rwlock);
427
428 + if(name && *name) rrdset_set_name(st, name);
429 + else rrdset_set_name(st, id);
430 +
431 + {
432 + char varvalue[CONFIG_MAX_VALUE + 1];
433 + snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
434 + st->title = config_get(st->id, "title", varvalue);
435 + }
436 +
437 st->next = rrdset_root;
438 rrdset_root = st;
439
@@ -503,6 +563,8 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
563
564 void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
565 {
566 + debug(D_RRD_CALLS, "rrddim_set_name() %s.%s", st->name, rd->name);
567 +
568 char varname[CONFIG_MAX_NAME + 1];
569 snprintf(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
570 config_get(st->id, varname, name);
@@ -510,6 +572,8 @@ void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
572
573 void rrddim_free(RRDSET *st, RRDDIM *rd)
574 {
575 + debug(D_RRD_CALLS, "rrddim_free() %s.%s", st->name, rd->name);
576 +
577 RRDDIM *i = st->dimensions, *last = NULL;
578 for(i = st->dimensions; i && i != rd ; i = i->next) last = i;
579
@@ -577,6 +641,8 @@ void rrdset_free_all(void)
641
642 void rrdset_save_all(void)
643 {
644 + debug(D_RRD_CALLS, "rrdset_save_all()");
645 +
646 RRDSET *st;
647 RRDDIM *rd;
648
@@ -604,7 +670,7 @@ void rrdset_save_all(void)
670
671 RRDSET *rrdset_find(const char *id)
672 {
607 - debug(D_RRD_CALLS, "rrd_stats_find() for chart %s", id);
673 + debug(D_RRD_CALLS, "rrdset_find() for chart %s", id);
674
675 pthread_rwlock_rdlock(&rrdset_root_rwlock);
676 RRDSET *st = rrdset_index_find(id, 0);
@@ -615,7 +681,7 @@ RRDSET *rrdset_find(const char *id)
681
682 RRDSET *rrdset_find_bytype(const char *type, const char *id)
683 {
618 - debug(D_RRD_CALLS, "rrd_stats_find_bytype() for chart %s.%s", type, id);
684 + debug(D_RRD_CALLS, "rrdset_find_bytype() for chart %s.%s", type, id);
685
686 char buf[RRD_ID_LENGTH_MAX + 1];
687
@@ -631,18 +697,10 @@ RRDSET *rrdset_find_bytype(const char *type, const char *id)
697
698 RRDSET *rrdset_find_byname(const char *name)
699 {
634 - debug(D_RRD_CALLS, "rrd_stats_find_byname() for chart %s", name);
635 -
636 - char b[CONFIG_MAX_VALUE + 1];
637 -
638 - rrdset_strncpy_name(b, name, CONFIG_MAX_VALUE);
639 - unsigned long hash = simple_hash(b);
700 + debug(D_RRD_CALLS, "rrdset_find_byname() for chart %s", name);
701
702 pthread_rwlock_rdlock(&rrdset_root_rwlock);
642 - RRDSET *st = rrdset_root;
643 - for ( ; st ; st = st->next ) {
644 - if(hash == st->hash_name && strcmp(st->name, b) == 0) break;
645 - }
703 + RRDSET *st = rrdset_index_find_name(name, 0);
704 pthread_rwlock_unlock(&rrdset_root_rwlock);
705
706 return(st);
@@ -650,14 +708,14 @@ RRDSET *rrdset_find_byname(const char *name)
708
709 RRDDIM *rrddim_find(RRDSET *st, const char *id)
710 {
653 - debug(D_RRD_CALLS, "rrd_stats_dimension_find() for chart %s, dimension %s", st->name, id);
711 + debug(D_RRD_CALLS, "rrddim_find() for chart %s, dimension %s", st->name, id);
712
713 return rrddim_index_find(st, id, 0);
714 }
715
716 int rrddim_hide(RRDSET *st, const char *id)
717 {
660 - debug(D_RRD_CALLS, "rrd_stats_dimension_hide() for chart %s, dimension %s", st->name, id);
718 + debug(D_RRD_CALLS, "rrddim_hide() for chart %s, dimension %s", st->name, id);
719
720 RRDDIM *rd = rrddim_find(st, id);
721 if(!rd) {
@@ -671,7 +729,7 @@ int rrddim_hide(RRDSET *st, const char *id)
729
730 void rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value)
731 {
674 - debug(D_RRD_CALLS, "rrd_stats_dimension_set() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
732 + debug(D_RRD_CALLS, "rrddim_set_by_pointer() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
733
734 gettimeofday(&rd->last_collected_time, NULL);
735 rd->collected_value = value;
@@ -692,7 +750,7 @@ int rrddim_set(RRDSET *st, const char *id, collected_number value)
750
751 void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
752 {
695 - debug(D_RRD_CALLS, "rrd_stats_next() for chart %s with microseconds %llu", st->name, microseconds);
753 + debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
754
755 if(st->debug) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
756 st->usec_since_last_update = microseconds;
@@ -718,7 +776,7 @@ void rrdset_next_plugins(RRDSET *st)
776
777 unsigned long long rrdset_done(RRDSET *st)
778 {
721 - debug(D_RRD_CALLS, "rrd_stats_done() for chart %s", st->name);
779 + debug(D_RRD_CALLS, "rrdset_done() for chart %s", st->name);
780
781 RRDDIM *rd, *last;
782 int oldstate, store_this_entry = 1;
src/rrd.h
+7 -7
@@ -78,10 +78,10 @@ extern const char *rrddim_algorithm_name(int chart_type);
78 // RRD DIMENSION
79
80 struct rrddim {
81 - avl avl;
81 + avl avl; // the index - this has to be first!
82
83 char magic[sizeof(RRDDIMENSION_MAGIC) + 1]; // our magic
84 - char id[RRD_ID_LENGTH_MAX + 1]; // the id of this dimension (for internal identification)
84 + char id[RRD_ID_LENGTH_MAX + 1]; // the id of this dimension (for internal identification)
85 const char *name; // the name of this dimension (as presented to user)
86 char cache_filename[FILENAME_MAX+1];
87
@@ -115,7 +115,7 @@ struct rrddim {
115 calculated_number collected_volume;
116 calculated_number stored_volume;
117
118 - struct rrddim *next; // linking of dimensions within the same data set
118 + struct rrddim *next; // linking of dimensions within the same data set
119
120 storage_number values[]; // the array of values - THIS HAS TO BE THE LAST MEMBER
121 };
@@ -126,11 +126,12 @@ typedef struct rrddim RRDDIM;
126 // RRDSET
127
128 struct rrdset {
129 - avl avl;
129 + avl avl; // the index, with key the id - this has to be first!
130 + avl avlname; // the index, with key the name
131
132 char magic[sizeof(RRDSET_MAGIC) + 1]; // our magic
133
133 - char id[RRD_ID_LENGTH_MAX + 1]; // id of the data set
134 + char id[RRD_ID_LENGTH_MAX + 1]; // id of the data set
135 const char *name; // name of the data set
136 char *cache_dir; // the directory to store dimension maps
137 char cache_filename[FILENAME_MAX+1];
@@ -176,8 +177,7 @@ struct rrdset {
177 // (the master data set should be the one that has the same family and is not detail)
178
179 RRDDIM *dimensions; // the actual data for every dimension
179 -
180 - avl_tree dimensions_index;
180 + avl_tree dimensions_index; // the root of the dimensions index
181
182 struct rrdset *next; // linking of rrdsets
183 };
src/rrd2json.c
+1 -1
@@ -47,7 +47,7 @@ unsigned long rrd_stats_one_json(RRDSET *st, char *options, struct web_buffer *w
47 , st->priority
48 , st->enabled
49 , st->units
50 - , st->name, options?options:""
50 + , st->id, options?options:""
51 , rrdset_type_name(st->chart_type)
52 , st->counter
53 , st->entries
src/web_server.c
+6 -4
@@ -275,8 +275,8 @@ int web_client_data_request(struct web_client *w, char *url, int datasource_type
275 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
276
277 // do we have such a data set?
278 - RRDSET *st = rrdset_find_byname(tok);
279 - if(!st) st = rrdset_find(tok);
278 + RRDSET *st = rrdset_find(tok);
279 + if(!st) st = rrdset_find_byname(tok);
280 if(!st) {
281 // we don't have it
282 // try to send a file with that name
@@ -490,7 +490,8 @@ void web_client_process(struct web_client *w)
490 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
491
492 // do we have such a data set?
493 - RRDSET *st = rrdset_find_byname(tok);
493 + RRDSET *st = rrdset_find(tok);
494 + if(!st) st = rrdset_find_byname(tok);
495 if(!st) {
496 // we don't have it
497 // try to send a file with that name
@@ -513,7 +514,8 @@ void web_client_process(struct web_client *w)
514 debug(D_WEB_CLIENT, "%llu: Searching for RRD data with name '%s'.", w->id, tok);
515
516 // do we have such a data set?
516 - RRDSET *st = rrdset_find_byname(tok);
517 + RRDSET *st = rrdset_find(tok);
518 + if(!st) st = rrdset_find_byname(tok);
519 if(!st) {
520 code = 404;
521 web_buffer_printf(w->data, "Chart %s is not found.\r\n", tok);