chart local variables use the same structures RRDSET variables use, so they appear as family and host variables too
Costa Tsaousis (ktsaou) committed
Oct 17, 2017 at 23:24 UTC
e2389840cc5ff6de71e4d57b0f2bd1034912d50d
9 files changed
+156
-109
src/health.h
+9
-6
@@ -11,7 +11,8 @@ typedef enum rrdvar_type {
11
RRDVAR_TYPE_COLLECTED = 3,
12
RRDVAR_TYPE_TOTAL = 4,
13
RRDVAR_TYPE_INT = 5,
14
- RRDVAR_TYPE_CALCULATED_ALLOCATED = 6 // a custom variable, allocate on purpose (ie. not inherited from charts)
14
+ RRDVAR_TYPE_CALCULATED_ALLOCATED = 6 // a custom variable, allocated on purpose (ie. not inherited from charts)
15
+ // used only for custom host global variables
16
} RRDVAR_TYPE;
17
18
// the variables as stored in the variables indexes
@@ -38,14 +39,17 @@ typedef struct rrdvar {
39
// these variables
40
41
typedef enum rrdvar_options {
41
- RRDVAR_OPTION_DEFAULT = (0 << 0)
42
+ RRDVAR_OPTION_DEFAULT = (0 << 0),
43
+ RRDVAR_OPTION_ALLOCATED = (1 << 0) // the value ptr is allocated (not a reference)
44
// future use
45
} RRDVAR_OPTIONS;
46
47
typedef struct rrdsetvar {
48
+ char *variable; // variable name
49
+ uint32_t hash; // variable name hash
50
+
51
char *key_fullid; // chart type.chart id.variable
52
char *key_fullname; // chart type.chart name.variable
48
- char *variable; // variable
53
54
RRDVAR_TYPE type;
55
void *value;
@@ -365,8 +369,8 @@ void health_api_v1_chart_variables2json(RRDSET *st, BUFFER *buf);
369
extern RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name);
370
extern void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value);
371
368
-extern RRDVAR *rrdvar_custom_chart_variable_create(RRDSET *st, const char *name);
369
-extern void rrdvar_custom_chart_variable_set(RRDSET *st, RRDVAR *rv, calculated_number value);
372
+extern RRDSETVAR *rrdsetvar_custom_chart_variable_create(RRDSET *st, const char *name);
373
+extern void rrdsetvar_custom_chart_variable_set(RRDSETVAR *rv, calculated_number value);
374
375
extern void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock);
376
@@ -413,7 +417,6 @@ extern void rrdcalctemplate_free(RRDCALCTEMPLATE *rt);
417
extern void rrdcalctemplate_unlink_and_free(RRDHOST *host, RRDCALCTEMPLATE *rt);
418
419
extern int rrdvar_callback_for_all_host_variables(RRDHOST *host, int (*callback)(void *rrdvar, void *data), void *data);
416
-extern int rrdvar_callback_for_all_chart_variables(RRDSET *st, int (*callback)(void *rrdvar, void *data), void *data);
420
421
#ifdef NETDATA_HEALTH_INTERNALS
422
#define RRDVAR_MAX_LENGTH 1024
src/ipc.c
+8
-10
@@ -163,10 +163,10 @@ static inline int ipc_sem_get_status(struct ipc_status *st) {
163
int do_ipc(int update_every, usec_t dt) {
164
(void)dt;
165
166
- static int initialized = 0, read_limits_next = 0;
166
+ static int initialized = 0, read_limits_next = -1;
167
static struct ipc_limits limits;
168
static struct ipc_status status;
169
- static RRDVAR *arrays_max = NULL, *semaphores_max = NULL;
169
+ static RRDSETVAR *arrays_max = NULL, *semaphores_max = NULL;
170
static RRDSET *st_semaphores = NULL, *st_arrays = NULL;
171
static RRDDIM *rd_semaphores = NULL, *rd_arrays = NULL;
172
@@ -185,12 +185,6 @@ int do_ipc(int update_every, usec_t dt) {
185
return 1;
186
}
187
188
- arrays_max = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.arrays.max");
189
- semaphores_max = rrdvar_custom_host_variable_create(localhost, "ipc.semaphores.max");
190
-
191
- if(arrays_max) rrdvar_custom_host_variable_set(localhost, arrays_max, limits.semmni);
192
- if(semaphores_max) rrdvar_custom_host_variable_set(localhost, semaphores_max, limits.semmns);
193
-
188
// create the charts
189
if(unlikely(!st_semaphores)) {
190
st_semaphores = rrdset_create_localhost(
@@ -227,6 +221,10 @@ int do_ipc(int update_every, usec_t dt) {
221
);
222
rd_arrays = rrddim_add(st_arrays, "arrays", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
223
}
224
+
225
+ // variables
226
+ semaphores_max = rrdsetvar_custom_chart_variable_create(st_semaphores, "ipc.semaphores.max");
227
+ arrays_max = rrdsetvar_custom_chart_variable_create(st_arrays, "ipc.semaphores.arrays.max");
228
}
229
230
if(unlikely(read_limits_next < 0)) {
@@ -234,8 +232,8 @@ int do_ipc(int update_every, usec_t dt) {
232
error("Unable to fetch semaphore limits.");
233
}
234
else {
237
- if(arrays_max) rrdvar_custom_host_variable_set(localhost, arrays_max, limits.semmni);
238
- if(semaphores_max) rrdvar_custom_host_variable_set(localhost, semaphores_max, limits.semmns);
235
+ if(semaphores_max) rrdsetvar_custom_chart_variable_set(semaphores_max, limits.semmns);
236
+ if(arrays_max) rrdsetvar_custom_chart_variable_set(arrays_max, limits.semmni);
237
238
st_arrays->red = limits.semmni;
239
st_semaphores->red = limits.semmns;
src/plugins_d.c
+11
-3
@@ -400,7 +400,15 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
400
value = NULL;
401
402
if(value) {
403
- calculated_number v = (calculated_number)str2ld(value, NULL);
403
+ char *endptr = NULL;
404
+ calculated_number v = (calculated_number)str2ld(value, &endptr);
405
+
406
+ if(unlikely(endptr && *endptr)) {
407
+ if(endptr == value)
408
+ error("PLUGINSD: '%s': the value '%s' of VARIABLE '%s' on host '%s' cannot be parsed as a number", cd->fullfilename, value, name, host->hostname);
409
+ else
410
+ error("PLUGINSD: '%s': the value '%s' of VARIABLE '%s' on host '%s' has leftovers: '%s'", cd->fullfilename, value, name, host->hostname, endptr);
411
+ }
412
413
if(global) {
414
RRDVAR *rv = rrdvar_custom_host_variable_create(host, name);
@@ -408,8 +416,8 @@ inline size_t pluginsd_process(RRDHOST *host, struct plugind *cd, FILE *fp, int
416
else error("PLUGINSD: '%s': cannot find/create HOST VARIABLE '%s' on host '%s'", cd->fullfilename, name, host->hostname);
417
}
418
else if(st) {
411
- RRDVAR *rv = rrdvar_custom_chart_variable_create(st, name);
412
- if (rv) rrdvar_custom_chart_variable_set(st, rv, v);
419
+ RRDSETVAR *rs = rrdsetvar_custom_chart_variable_create(st, name);
420
+ if (rs) rrdsetvar_custom_chart_variable_set(rs, v);
421
else error("PLUGINSD: '%s': cannot find/create CHART VARIABLE '%s' on host '%s', chart '%s'", cd->fullfilename, name, host->hostname, st->id);
422
}
423
else
src/rrdfamily.c
+9
-8
@@ -34,7 +34,7 @@ RRDFAMILY *rrdfamily_create(RRDHOST *host, const char *id) {
34
35
RRDFAMILY *ret = rrdfamily_index_add(host, rc);
36
if(ret != rc)
37
- fatal("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
37
+ error("RRDFAMILY: INTERNAL ERROR: Expected to INSERT RRDFAMILY '%s' into index, but inserted '%s'.", rc->family, (ret)?ret->family:"NONE");
38
}
39
40
rc->use_count++;
@@ -46,13 +46,14 @@ void rrdfamily_free(RRDHOST *host, RRDFAMILY *rc) {
46
if(!rc->use_count) {
47
RRDFAMILY *ret = rrdfamily_index_del(host, rc);
48
if(ret != rc)
49
- fatal("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
50
-
51
- if(rc->rrdvar_root_index.avl_tree.root != NULL)
52
- fatal("RRDFAMILY: INTERNAL ERROR: Variables index of RRDFAMILY '%s' that is freed, is not empty.", rc->family);
53
-
54
- freez((void *)rc->family);
55
- freez(rc);
49
+ error("RRDFAMILY: INTERNAL ERROR: Expected to DELETE RRDFAMILY '%s' from index, but deleted '%s'.", rc->family, (ret)?ret->family:"NONE");
50
+ else {
51
+ debug(D_RRD_CALLS, "RRDFAMILY: Cleaning up remaining family variables for host '%s', family '%s'", host->hostname, rc->family);
52
+ rrdvar_free_remaining_variables(host, &rc->rrdvar_root_index);
53
+
54
+ freez((void *) rc->family);
55
+ freez(rc);
56
+ }
57
}
58
}
59
src/rrdhost.c
+1
@@ -496,6 +496,7 @@ void rrdhost_free(RRDHOST *host) {
496
while(host->templates)
497
rrdcalctemplate_unlink_and_free(host, host->templates);
498
499
+ debug(D_RRD_CALLS, "RRDHOST: Cleaning up remaining host variables for host '%s'", host->hostname);
500
rrdvar_free_remaining_variables(host, &host->rrdvar_root_index);
501
502
health_alarm_log_free(host);
src/rrdpush.c
+21
-29
@@ -77,35 +77,15 @@ static inline int need_to_send_chart_definition(RRDSET *st) {
77
return 0;
78
}
79
80
-static int rrdpush_sender_add_chart_variable_to_buffer_nolock(void *rrdvar_ptr, void *rrdset_ptr) {
81
- RRDVAR *rv = (RRDVAR *)rrdvar_ptr;
82
-
83
- if(unlikely(rv->type == RRDVAR_TYPE_CALCULATED_ALLOCATED)) {
84
- RRDSET *st = (RRDSET *)rrdset_ptr;
85
-
86
- calculated_number *value = (calculated_number *) rv->value;
87
-
88
- buffer_sprintf(
89
- st->rrdhost->rrdpush_sender_buffer
90
- , "VARIABLE CHART %s = " CALCULATED_NUMBER_FORMAT "\n"
91
- , rv->name
92
- , *value
93
- );
94
-
95
- debug(D_STREAM, "RRDVAR pushed CHART VARIABLE %s = " CALCULATED_NUMBER_FORMAT, rv->name, *value);
96
-
97
- return 1;
98
- }
99
-
100
- return 0;
101
-}
102
-
80
// sends the current chart definition
81
static inline void rrdpush_send_chart_definition_nolock(RRDSET *st) {
82
+ RRDHOST *host = st->rrdhost;
83
+
84
rrdset_flag_set(st, RRDSET_FLAG_EXPOSED_UPSTREAM);
85
86
+ // send the chart
87
buffer_sprintf(
108
- st->rrdhost->rrdpush_sender_buffer
88
+ host->rrdpush_sender_buffer
89
, "CHART \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %ld %d \"%s %s %s\" \"%s\" \"%s\"\n"
90
, st->id
91
, st->name
@@ -123,10 +103,11 @@ static inline void rrdpush_send_chart_definition_nolock(RRDSET *st) {
103
, (st->module_name)?st->module_name:""
104
);
105
106
+ // send the dimensions
107
RRDDIM *rd;
108
rrddim_foreach_read(rd, st) {
109
buffer_sprintf(
129
- st->rrdhost->rrdpush_sender_buffer
110
+ host->rrdpush_sender_buffer
111
, "DIMENSION \"%s\" \"%s\" \"%s\" " COLLECTED_NUMBER_FORMAT " " COLLECTED_NUMBER_FORMAT " \"%s %s\"\n"
112
, rd->id
113
, rd->name
@@ -139,11 +120,22 @@ static inline void rrdpush_send_chart_definition_nolock(RRDSET *st) {
120
rd->exposed = 1;
121
}
122
142
- st->upstream_resync_time = st->last_collected_time.tv_sec + (remote_clock_resync_iterations * st->update_every);
143
-
144
- int ret = rrdvar_callback_for_all_chart_variables(st, rrdpush_sender_add_chart_variable_to_buffer_nolock, st);
145
- debug(D_STREAM, "RRDVAR sent %d VARIABLES", ret);
123
+ // send the chart local custom variables
124
+ RRDSETVAR *rs;
125
+ for(rs = st->variables; rs ;rs = rs->next) {
126
+ if(unlikely(rs->options && RRDVAR_OPTION_ALLOCATED)) {
127
+ calculated_number *value = (calculated_number *) rs->value;
128
+
129
+ buffer_sprintf(
130
+ host->rrdpush_sender_buffer
131
+ , "VARIABLE CHART %s = " CALCULATED_NUMBER_FORMAT "\n"
132
+ , rs->variable
133
+ , *value
134
+ );
135
+ }
136
+ }
137
138
+ st->upstream_resync_time = st->last_collected_time.tv_sec + (remote_clock_resync_iterations * st->update_every);
139
}
140
141
// sends the current chart dimensions
src/rrdset.c
+6
-5
@@ -316,6 +316,7 @@ void rrdset_free(RRDSET *st) {
316
317
rrdfamily_free(st->rrdhost, st->rrdfamily);
318
319
+ debug(D_RRD_CALLS, "RRDSET: Cleaning up remaining chart variables for host '%s', chart '%s'", st->rrdhost->hostname, st->id);
320
rrdvar_free_remaining_variables(st->rrdhost, &st->rrdvar_root_index);
321
322
// ------------------------------------------------------------------------
@@ -662,11 +663,11 @@ RRDSET *rrdset_create_custom(
663
host->rrdset_root = st;
664
665
if(host->health_enabled) {
665
- rrdsetvar_create(st, "last_collected_t", RRDVAR_TYPE_TIME_T, &st->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT);
666
- rrdsetvar_create(st, "collected_total_raw", RRDVAR_TYPE_TOTAL, &st->last_collected_total, RRDVAR_OPTION_DEFAULT);
667
- rrdsetvar_create(st, "green", RRDVAR_TYPE_CALCULATED, &st->green, RRDVAR_OPTION_DEFAULT);
668
- rrdsetvar_create(st, "red", RRDVAR_TYPE_CALCULATED, &st->red, RRDVAR_OPTION_DEFAULT);
669
- rrdsetvar_create(st, "update_every", RRDVAR_TYPE_INT, &st->update_every, RRDVAR_OPTION_DEFAULT);
666
+ rrdsetvar_create(st, "last_collected_t", RRDVAR_TYPE_TIME_T, &st->last_collected_time.tv_sec, RRDVAR_OPTION_DEFAULT);
667
+ rrdsetvar_create(st, "collected_total_raw", RRDVAR_TYPE_TOTAL, &st->last_collected_total, RRDVAR_OPTION_DEFAULT);
668
+ rrdsetvar_create(st, "green", RRDVAR_TYPE_CALCULATED, &st->green, RRDVAR_OPTION_DEFAULT);
669
+ rrdsetvar_create(st, "red", RRDVAR_TYPE_CALCULATED, &st->red, RRDVAR_OPTION_DEFAULT);
670
+ rrdsetvar_create(st, "update_every", RRDVAR_TYPE_INT, &st->update_every, RRDVAR_OPTION_DEFAULT);
671
}
672
673
if(unlikely(rrdset_index_add(host, st) != st))
src/rrdsetvar.c
+82
-23
@@ -8,29 +8,29 @@
8
static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
9
RRDSET *st = rs->rrdset;
10
11
+ // ------------------------------------------------------------------------
12
// CHART
12
-
13
rrdvar_free(st->rrdhost, &st->rrdvar_root_index, rs->var_local);
14
rs->var_local = NULL;
15
16
+ // ------------------------------------------------------------------------
17
// FAMILY
17
-
18
rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family);
19
rs->var_family = NULL;
20
21
- rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host);
22
- rs->var_host = NULL;
23
-
24
- // HOST
25
-
21
rrdvar_free(st->rrdhost, &st->rrdfamily->rrdvar_root_index, rs->var_family_name);
22
rs->var_family_name = NULL;
23
24
+ // ------------------------------------------------------------------------
25
+ // HOST
26
+ rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host);
27
+ rs->var_host = NULL;
28
+
29
rrdvar_free(st->rrdhost, &st->rrdhost->rrdvar_root_index, rs->var_host_name);
30
rs->var_host_name = NULL;
31
32
+ // ------------------------------------------------------------------------
33
// KEYS
33
-
34
freez(rs->key_fullid);
35
rs->key_fullid = NULL;
36
@@ -39,10 +39,14 @@ static inline void rrdsetvar_free_variables(RRDSETVAR *rs) {
39
}
40
41
static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
42
- rrdsetvar_free_variables(rs);
43
-
42
RRDSET *st = rs->rrdset;
43
44
+ // ------------------------------------------------------------------------
45
+ // free the old ones (if any)
46
+
47
+ rrdsetvar_free_variables(rs);
48
+
49
+ // ------------------------------------------------------------------------
50
// KEYS
51
52
char buffer[RRDVAR_MAX_LENGTH + 1];
@@ -52,20 +56,19 @@ static inline void rrdsetvar_create_variables(RRDSETVAR *rs) {
56
snprintfz(buffer, RRDVAR_MAX_LENGTH, "%s.%s", st->name, rs->variable);
57
rs->key_fullname = strdupz(buffer);
58
59
+ // ------------------------------------------------------------------------
60
// CHART
61
+ rs->var_local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->variable, rs->type, rs->value);
62
57
- rs->var_local = rrdvar_create_and_index("local", &st->rrdvar_root_index, rs->variable, rs->type, rs->value);
58
-
63
+ // ------------------------------------------------------------------------
64
// FAMILY
65
+ rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
66
+ rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
67
61
- rs->var_family = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
62
- rs->var_family_name = rrdvar_create_and_index("family", &st->rrdfamily->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
63
-
68
+ // ------------------------------------------------------------------------
69
// HOST
65
-
66
- rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
67
- rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
68
-
70
+ rs->var_host = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullid, rs->type, rs->value);
71
+ rs->var_host_name = rrdvar_create_and_index("host", &st->rrdhost->rrdvar_root_index, rs->key_fullname, rs->type, rs->value);
72
}
73
74
RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type, void *value, RRDVAR_OPTIONS options) {
@@ -73,6 +76,7 @@ RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type,
76
RRDSETVAR *rs = (RRDSETVAR *)callocz(1, sizeof(RRDSETVAR));
77
78
rs->variable = strdupz(variable);
79
+ rs->hash = simple_hash(rs->variable);
80
rs->type = type;
81
rs->value = value;
82
rs->options = options;
@@ -89,11 +93,9 @@ RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, RRDVAR_TYPE type,
93
void rrdsetvar_rename_all(RRDSET *st) {
94
debug(D_VARIABLES, "RRDSETVAR rename for chart id '%s' name '%s'", st->id, st->name);
95
92
- RRDSETVAR *rs, *next = st->variables;
93
- while((rs = next)) {
94
- next = rs->next;
96
+ RRDSETVAR *rs;
97
+ for(rs = st->variables; rs ; rs = rs->next)
98
rrdsetvar_create_variables(rs);
96
- }
99
100
rrdsetcalc_link_matching(st);
101
}
@@ -115,6 +117,63 @@ void rrdsetvar_free(RRDSETVAR *rs) {
117
rrdsetvar_free_variables(rs);
118
119
freez(rs->variable);
120
+
121
+ if(rs->options & RRDVAR_OPTION_ALLOCATED)
122
+ freez(rs->value);
123
+
124
freez(rs);
125
}
126
127
+// --------------------------------------------------------------------------------------------------------------------
128
+// custom chart variables
129
+
130
+RRDSETVAR *rrdsetvar_custom_chart_variable_create(RRDSET *st, const char *name) {
131
+ char *n = strdupz(name);
132
+ rrdvar_fix_name(n);
133
+ uint32_t hash = simple_hash(n);
134
+
135
+ rrdset_wrlock(st);
136
+
137
+ // find it
138
+ RRDSETVAR *rs;
139
+ for(rs = st->variables; rs ; rs = rs->next) {
140
+ if(hash == rs->hash && strcmp(n, rs->variable) == 0) {
141
+ rrdset_unlock(st);
142
+ if(rs->options & RRDVAR_OPTION_ALLOCATED) {
143
+ free(n);
144
+ return rs;
145
+ }
146
+ else {
147
+ error("RRDSETVAR: custom variable '%s' on chart '%s' of host '%s', conflicts with an internal chart variable", n, st->id, st->rrdhost->hostname);
148
+ free(n);
149
+ return NULL;
150
+ }
151
+ }
152
+ }
153
+
154
+ // not found, allocate one
155
+
156
+ calculated_number *v = mallocz(sizeof(calculated_number));
157
+ *v = NAN;
158
+
159
+ rs = rrdsetvar_create(st, n, RRDVAR_TYPE_CALCULATED, v, RRDVAR_OPTION_ALLOCATED);
160
+ rrdset_unlock(st);
161
+
162
+ free(n);
163
+ return rs;
164
+}
165
+
166
+void rrdsetvar_custom_chart_variable_set(RRDSETVAR *rs, calculated_number value) {
167
+ if(unlikely(!(rs->options & RRDVAR_OPTION_ALLOCATED))) {
168
+ error("RRDSETVAR: requested to set variable '%s' of chart '%s' on host '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rs->variable, rs->rrdset->id, rs->rrdset->rrdhost->hostname, value);
169
+ }
170
+ else {
171
+ calculated_number *v = rs->value;
172
+ if(*v != value) {
173
+ *v = value;
174
+
175
+ // mark the chart to be sent upstream
176
+ rrdset_flag_clear(rs->rrdset, RRDSET_FLAG_EXPOSED_UPSTREAM);
177
+ }
178
+ }
179
+}
src/rrdvar.c
+9
-25
@@ -108,23 +108,25 @@ inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, c
108
void rrdvar_free_remaining_variables(RRDHOST *host, avl_tree_lock *tree_lock) {
109
// FIXME: this is not bullet proof - avl should support some means to destroy it
110
// with a callback for each item already in the index
111
- while(host->rrdvar_root_index.avl_tree.root) {
112
- RRDVAR *rv = (RRDVAR *)tree_lock->avl_tree.root;
111
+
112
+ RRDVAR *rv, *last = NULL;
113
+ while((rv = (RRDVAR *)tree_lock->avl_tree.root)) {
114
+ if(unlikely(rv == last)) {
115
+ error("RRDVAR: INTERNAL ERROR: Cannot cleanup tree of RRDVARs");
116
+ break;
117
+ }
118
+ last = rv;
119
rrdvar_free(host, tree_lock, rv);
120
}
121
}
122
123
// ----------------------------------------------------------------------------
118
-// CUSTOM VARIABLES
124
+// CUSTOM HOST VARIABLES
125
126
inline int rrdvar_callback_for_all_host_variables(RRDHOST *host, int (*callback)(void *rrdvar, void *data), void *data) {
127
return avl_traverse_lock(&host->rrdvar_root_index, callback, data);
128
}
129
124
-inline int rrdvar_callback_for_all_chart_variables(RRDSET *st, int (*callback)(void *rrdvar, void *data), void *data) {
125
- return avl_traverse_lock(&st->rrdhost->rrdvar_root_index, callback, data);
126
-}
127
-
130
static RRDVAR *rrdvar_custom_variable_create(const char *scope, avl_tree_lock *tree_lock, const char *name) {
131
calculated_number *v = callocz(1, sizeof(calculated_number));
132
*v = NAN;
@@ -150,10 +152,6 @@ RRDVAR *rrdvar_custom_host_variable_create(RRDHOST *host, const char *name) {
152
return rrdvar_custom_variable_create("host", &host->rrdvar_root_index, name);
153
}
154
153
-RRDVAR *rrdvar_custom_chart_variable_create(RRDSET *st, const char *name) {
154
- return rrdvar_custom_variable_create("local", &st->rrdvar_root_index, name);
155
-}
156
-
155
void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_number value) {
156
if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
157
error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
@@ -168,20 +166,6 @@ void rrdvar_custom_host_variable_set(RRDHOST *host, RRDVAR *rv, calculated_numbe
166
}
167
}
168
171
-void rrdvar_custom_chart_variable_set(RRDSET *st, RRDVAR *rv, calculated_number value) {
172
- if(rv->type != RRDVAR_TYPE_CALCULATED_ALLOCATED)
173
- error("requested to set variable '%s' to value " CALCULATED_NUMBER_FORMAT " but the variable is not a custom one.", rv->name, value);
174
- else {
175
- calculated_number *v = rv->value;
176
- if(*v != value) {
177
- *v = value;
178
-
179
- // mark the chart to be sent upstream
180
- rrdset_flag_clear(st, RRDSET_FLAG_EXPOSED_UPSTREAM);
181
- }
182
- }
183
-}
184
-
169
// ----------------------------------------------------------------------------
170
// RRDVAR lookup
171