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);