chart and dimensions variables linked to 3 indexes: local, context and host variables
Costa Tsaousis committed
Aug 7, 2016 at 14:59 UTC
dd4b84630650c98211f2289e369c65aff1a3ce3f
5 files changed
+513
-34
src/health.c
+382
-26
@@ -1,15 +1,31 @@
1
#include "common.h"
2
3
+// ----------------------------------------------------------------------------
4
+// RRDVAR management
5
+
6
int rrdvar_compare(void* a, void* b) {
7
if(((RRDVAR *)a)->hash < ((RRDVAR *)b)->hash) return -1;
8
else if(((RRDVAR *)a)->hash > ((RRDVAR *)b)->hash) return 1;
9
else return strcmp(((RRDVAR *)a)->name, ((RRDVAR *)b)->name);
10
}
11
9
-#define rrdvar_index_add(tree, rv) (RRDVAR *)avl_insert_lock(tree, (avl *)(rv))
10
-#define rrdvar_index_del(tree, rv) (RRDVAR *)avl_remove_lock(tree, (avl *)(rv))
12
+static inline RRDVAR *rrdvar_index_add(avl_tree_lock *tree, RRDVAR *rv) {
13
+ RRDVAR *ret = (RRDVAR *)avl_insert_lock(tree, (avl *)(rv));
14
+ if(ret != rv)
15
+ debug(D_VARIABLES, "Request to insert RRDVAR '%s' into index failed. Already exists.", rv->name);
16
+
17
+ return ret;
18
+}
19
+
20
+static inline RRDVAR *rrdvar_index_del(avl_tree_lock *tree, RRDVAR *rv) {
21
+ RRDVAR *ret = (RRDVAR *)avl_remove_lock(tree, (avl *)(rv));
22
+ if(!ret)
23
+ fatal("Request to remove RRDVAR '%s' from index failed. Not Found.", rv->name);
24
+
25
+ return ret;
26
+}
27
12
-static RRDVAR *rrdvar_index_find(avl_tree_lock *tree, const char *name, uint32_t hash) {
28
+static inline RRDVAR *rrdvar_index_find(avl_tree_lock *tree, const char *name, uint32_t hash) {
29
RRDVAR tmp;
30
tmp.name = (char *)name;
31
tmp.hash = (hash)?hash:simple_hash(tmp.name);
@@ -17,37 +33,377 @@ static RRDVAR *rrdvar_index_find(avl_tree_lock *tree, const char *name, uint32_t
33
return (RRDVAR *)avl_search_lock(tree, (avl *)&tmp);
34
}
35
36
+static inline RRDVAR *rrdvar_create(const char *name, uint32_t hash, int type, calculated_number *value) {
37
+ RRDVAR *rv = calloc(1, sizeof(RRDVAR));
38
+ if(!rv) fatal("Cannot allocate memory for RRDVAR");
39
21
-RRDVAR *rrdvar_get(RRDHOST *host, RRDCONTEXT *co, RRDSET *st, const char *name) {
22
- uint32_t hash = simple_hash(name);
40
+ rv->name = (char *)name;
41
+ rv->hash = (hash)?hash:simple_hash((rv->name));
42
+ rv->type = type;
43
+ rv->value = value;
44
24
- RRDVAR *ret = NULL;
25
- RRDVAR *rv = rrdvar_index_find(&st->variables_root_index, name, hash);
26
- if(!rv) {
27
- rv = calloc(1, sizeof(RRDVAR));
28
- if(!rv) fatal("Cannot allocate memory for RRDVAR");
45
+ return rv;
46
+}
47
30
- rv->name = strdup(name);
31
- if(!rv->name) fatal("Cannot allocate memory for RRDVAR name");
48
+static inline void rrdvar_free(RRDVAR *rv) {
49
+ free(rv);
50
+}
51
33
- rv->hash = hash;
52
+static inline RRDVAR *rrdvar_create_and_index(const char *scope, avl_tree_lock *tree, const char *name, uint32_t hash, int type, calculated_number *value) {
53
+ RRDVAR *rv = rrdvar_index_find(tree, name, hash);
54
+ if(unlikely(!rv)) {
55
+ debug(D_VARIABLES, "Variable '%s' not found in scope '%s'. Creating a new one.", name, scope);
56
35
- ret = rrdvar_index_add(&st->variables_root_index, rv);
36
- if(ret != rv) {
37
- error("Duplicate RRDVAR '%s' found on chart '%s'", name, st->id);
38
- free(rv->name);
39
- free(rv);
40
- rv = ret;
57
+ rv = rrdvar_create(name, hash, type, value);
58
+ RRDVAR *ret = rrdvar_index_add(tree, rv);
59
+ if(unlikely(ret != rv)) {
60
+ debug(D_VARIABLES, "Variable '%s' in scope '%s' already exists", name, scope);
61
+ rrdvar_free(rv);
62
+ rv = NULL;
63
}
64
+ else
65
+ debug(D_VARIABLES, "Variable '%s' created in scope '%s'", name, scope);
66
+ }
67
+
68
+ return rv;
69
+}
70
+
71
+// ----------------------------------------------------------------------------
72
+// RRDSETVAR management
73
+
74
+#define RRDSETVAR_ID_MAX 1024
75
+
76
+RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, int type, void *value, uint32_t options) {
77
+ RRDSETVAR *rs = (RRDSETVAR *)calloc(1, sizeof(RRDSETVAR));
78
+ if(!rs) fatal("Cannot allocate memory for RRDSETVAR");
79
+
80
+ char buffer[RRDSETVAR_ID_MAX + 1];
81
+ snprintfz(buffer, RRDSETVAR_ID_MAX, "%s.%s.%s", st->type, st->id, variable);
82
+ rs->fullid = strdup(buffer);
83
+ if(!rs->fullid) fatal("Cannot allocate memory for RRDVASET id");
84
+ rs->hash_fullid = simple_hash(rs->fullid);
85
+
86
+ snprintfz(buffer, RRDSETVAR_ID_MAX, "%s.%s.%s", st->type, st->name, variable);
87
+ rs->fullname = strdup(buffer);
88
+ if(!rs->fullname) fatal("Cannot allocate memory for RRDVASET name");
89
+ rs->hash_fullname = simple_hash(rs->fullname);
90
+
91
+ rs->variable = strdup(variable);
92
+ if(!rs->variable) fatal("Cannot allocate memory for RRDVASET variable name");
93
+ rs->hash_variable = simple_hash(rs->variable);
94
+
95
+ rs->type = type;
96
+ rs->value = value;
97
+ rs->options = options;
98
+
99
+ rs->local = rrdvar_create_and_index("local", &st->variables_root_index, rs->variable, rs->hash_variable, rs->type, rs->value);
100
+ rs->context = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullid, rs->hash_fullid, rs->type, rs->value);
101
+ rs->host = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullid, rs->hash_fullid, rs->type, rs->value);
102
+ rs->context_name = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullname, rs->hash_fullname, rs->type, rs->value);
103
+ rs->host_name = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullname, rs->hash_fullname, rs->type, rs->value);
104
+
105
+ rs->next = st->variables;
106
+ st->variables = rs;
107
+
108
+ return rs;
109
+}
110
43
- ret = rrdvar_index_add(&co->variables_root_index, rv);
44
- if(ret != rv)
45
- debug(D_VARIABLES, "Variable '%s' in context '%s' does not come from chart '%s'", name, co->id, st->id);
111
+void rrdsetvar_rename_all(RRDSET *st) {
112
+ // only these 2 can change name
113
+ // rs->context_name
114
+ // rs->host_name
115
47
- ret = rrdvar_index_add(&host->variables_root_index, rv);
48
- if(ret != rv)
49
- debug(D_VARIABLES, "Variable '%s' in host '%s' does not come from chart '%s'", name, host->hostname, st->id);
116
+ char buffer[RRDSETVAR_ID_MAX + 1];
117
+ RRDSETVAR *rs, *next = st->variables;
118
+ while((rs = next)) {
119
+ next = rs->next;
120
+
121
+ snprintfz(buffer, RRDSETVAR_ID_MAX, "%s.%s.%s", st->type, st->name, rs->variable);
122
+
123
+ if (strcmp(buffer, rs->fullname)) {
124
+ // name changed
125
+ if (rs->context_name) {
126
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context_name);
127
+ rrdvar_free(rs->context_name);
128
+ }
129
+
130
+ if (rs->host_name) {
131
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->host_name);
132
+ rrdvar_free(rs->host_name);
133
+ }
134
+
135
+ free(rs->fullname);
136
+ rs->fullname = strdup(st->name);
137
+ if(!rs->fullname) fatal("Cannot allocate memory for RRDSETVAR name");
138
+ rs->hash_fullname = simple_hash(rs->fullname);
139
+ rs->context_name = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullname, rs->hash_fullname, rs->type, rs->value);
140
+ rs->host_name = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullname, rs->hash_fullname, rs->type, rs->value);
141
+ }
142
+ }
143
+}
144
+
145
+void rrdsetvar_free(RRDSETVAR *rs) {
146
+ RRDSET *st = rs->rrdset;
147
+
148
+ if(rs->local) {
149
+ rrdvar_index_del(&st->variables_root_index, rs->local);
150
+ rrdvar_free(rs->local);
151
}
152
52
- return rv;
153
+ if(rs->context) {
154
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context);
155
+ rrdvar_free(rs->context);
156
+ }
157
+
158
+ if(rs->host) {
159
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->host);
160
+ rrdvar_free(rs->host);
161
+ }
162
+
163
+ if(rs->context_name) {
164
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context_name);
165
+ rrdvar_free(rs->context_name);
166
+ }
167
+
168
+ if(rs->host_name) {
169
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->host_name);
170
+ rrdvar_free(rs->host_name);
171
+ }
172
+
173
+ if(st->variables == rs) {
174
+ st->variables = rs->next;
175
+ }
176
+ else {
177
+ RRDSETVAR *t;
178
+ for (t = st->variables; t && t->next != rs; t = t->next);
179
+ if(!t) error("RRDSETVAR '%s' not found in chart '%s' variables linked list", rs->fullname, st->id);
180
+ else t->next = rs->next;
181
+ }
182
+
183
+ free(rs->fullid);
184
+ free(rs->fullname);
185
+ free(rs->variable);
186
+ free(rs);
187
+}
188
+
189
+// ----------------------------------------------------------------------------
190
+// RRDDIMVAR management
191
+
192
+#define RRDDIMVAR_ID_MAX 1024
193
+
194
+RRDDIMVAR *rrddimvar_create(RRDDIM *rd, int type, const char *prefix, const char *suffix, void *value, uint32_t options) {
195
+ RRDSET *st = rd->rrdset;
196
+
197
+ if(!prefix) prefix = "";
198
+ if(!suffix) suffix = "";
199
+
200
+ char buffer[RRDDIMVAR_ID_MAX + 1];
201
+ RRDDIMVAR *rs = (RRDDIMVAR *)calloc(1, sizeof(RRDDIMVAR));
202
+ if(!rs) fatal("Cannot allocate memory for RRDDIMVAR");
203
+
204
+ rs->prefix = strdup(prefix);
205
+ if(!rs->prefix) fatal("Cannot allocate memory for RRDDIMVAR prefix");
206
+
207
+ rs->suffix = strdup(suffix);
208
+ if(!rs->suffix) fatal("Cannot allocate memory for RRDDIMVAR suffix");
209
+
210
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s%s%s", rs->prefix, rd->id, rs->suffix);
211
+ rs->id = strdup(buffer);
212
+ if(!rs->id) fatal("Cannot allocate memory for RRDIM id");
213
+ rs->hash = simple_hash(rs->id);
214
+
215
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s%s%s", rs->prefix, rd->name, rs->suffix);
216
+ rs->name = strdup(buffer);
217
+ if(!rs->name) fatal("Cannot allocate memory for RRDIM name");
218
+ rs->hash_name = simple_hash(rs->name);
219
+
220
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", rd->rrdset->type, rd->rrdset->id, rs->id);
221
+ rs->fullidid = strdup(buffer);
222
+ if(!rs->fullidid) fatal("Cannot allocate memory for RRDDIMVAR fullidid");
223
+ rs->hash_fullidid = simple_hash(rs->fullidid);
224
+
225
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", rd->rrdset->type, rd->rrdset->id, rs->name);
226
+ rs->fullidname = strdup(buffer);
227
+ if(!rs->fullidname) fatal("Cannot allocate memory for RRDDIMVAR fullidname");
228
+ rs->hash_fullidname = simple_hash(rs->fullidname);
229
+
230
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", rd->rrdset->type, rd->rrdset->name, rs->id);
231
+ rs->fullnameid = strdup(buffer);
232
+ if(!rs->fullnameid) fatal("Cannot allocate memory for RRDDIMVAR fullnameid");
233
+ rs->hash_fullnameid = simple_hash(rs->fullnameid);
234
+
235
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", rd->rrdset->type, rd->rrdset->name, rs->name);
236
+ rs->fullnamename = strdup(buffer);
237
+ if(!rs->fullnamename) fatal("Cannot allocate memory for RRDDIMVAR fullnamename");
238
+ rs->hash_fullnamename = simple_hash(rs->fullnamename);
239
+
240
+ rs->type = type;
241
+ rs->value = value;
242
+ rs->options = options;
243
+
244
+ rs->local_id = rrdvar_create_and_index("local", &st->variables_root_index, rs->id, rs->hash, rs->type, rs->value);
245
+ rs->local_name = rrdvar_create_and_index("local", &st->variables_root_index, rs->name, rs->hash_name, rs->type, rs->value);
246
+
247
+ rs->context_fullidid = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullidid, rs->hash_fullidid, rs->type, rs->value);
248
+ rs->context_fullidname = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullidname, rs->hash_fullidname, rs->type, rs->value);
249
+ rs->context_fullnameid = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullnameid, rs->hash_fullnameid, rs->type, rs->value);
250
+ rs->context_fullnamename = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index, rs->fullnamename, rs->hash_fullnamename, rs->type, rs->value);
251
+
252
+ rs->host_fullidid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullidid, rs->hash_fullidid, rs->type, rs->value);
253
+ rs->host_fullidname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullidname, rs->hash_fullidname, rs->type, rs->value);
254
+ rs->host_fullnameid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullnameid, rs->hash_fullnameid, rs->type, rs->value);
255
+ rs->host_fullnamename = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index, rs->fullnamename, rs->hash_fullnamename, rs->type, rs->value);
256
+
257
+ rs->next = rd->variables;
258
+ rd->variables = rs;
259
+
260
+ return rs;
261
+}
262
+
263
+void rrddimvar_rename_all(RRDDIM *rd) {
264
+ RRDSET *st = rd->rrdset;
265
+
266
+ RRDDIMVAR *rs, *next = rd->variables;
267
+ while((rs = next)) {
268
+ next = rs->next;
269
+
270
+ if (strcmp(rd->name, rs->name)) {
271
+ char buffer[RRDDIMVAR_ID_MAX + 1];
272
+ // name changed
273
+
274
+ // name
275
+ if (rs->local_name) {
276
+ rrdvar_index_del(&st->variables_root_index, rs->local_name);
277
+ rrdvar_free(rs->local_name);
278
+ }
279
+ free(rs->name);
280
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s%s%s", rs->prefix, rd->name, rs->suffix);
281
+ rs->name = strdup(buffer);
282
+ if(!rs->name) fatal("Cannot allocate memory for RRDDIMVAR name");
283
+ rs->hash_name = simple_hash(rs->name);
284
+ rs->local_name = rrdvar_create_and_index("local", &st->variables_root_index, rs->name, rs->hash_name, rs->type, rs->value);
285
+
286
+ // fullidname
287
+ if (rs->context_fullidname) {
288
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context_fullidname);
289
+ rrdvar_free(rs->context_fullidname);
290
+ }
291
+ if (rs->host_fullidname) {
292
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->context_fullidname);
293
+ rrdvar_free(rs->host_fullidname);
294
+ }
295
+ free(rs->fullidname);
296
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", st->type, st->id, rs->name);
297
+ rs->fullidname = strdup(buffer);
298
+ if(!rs->fullidname) fatal("Cannot allocate memory for RRDDIMVAR fullidname");
299
+ rs->hash_fullidname = simple_hash(rs->fullidname);
300
+ rs->context_fullidname = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index,
301
+ rs->fullidname, rs->hash_fullidname, rs->type, rs->value);
302
+ rs->host_fullidname = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index,
303
+ rs->fullidname, rs->hash_fullidname, rs->type, rs->value);
304
+
305
+ // fullnameid
306
+ if (rs->context_fullnameid) {
307
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context_fullnameid);
308
+ rrdvar_free(rs->context_fullnameid);
309
+ }
310
+ if (rs->host_fullnameid) {
311
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->context_fullnameid);
312
+ rrdvar_free(rs->host_fullnameid);
313
+ }
314
+ free(rs->fullnameid);
315
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", st->type, st->name, rs->id);
316
+ rs->fullnameid = strdup(buffer);
317
+ if(!rs->fullnameid) fatal("Cannot allocate memory for RRDDIMVAR fullnameid");
318
+ rs->hash_fullnameid = simple_hash(rs->fullnameid);
319
+ rs->context_fullnameid = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index,
320
+ rs->fullnameid, rs->hash_fullnameid, rs->type, rs->value);
321
+ rs->host_fullnameid = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index,
322
+ rs->fullnameid, rs->hash_fullnameid, rs->type, rs->value);
323
+
324
+ // fullnamename
325
+ if (rs->context_fullnamename) {
326
+ rrdvar_index_del(&st->rrdcontext->variables_root_index, rs->context_fullnamename);
327
+ rrdvar_free(rs->context_fullnamename);
328
+ }
329
+ if (rs->host_fullnamename) {
330
+ rrdvar_index_del(&st->rrdhost->variables_root_index, rs->context_fullnamename);
331
+ rrdvar_free(rs->host_fullnamename);
332
+ }
333
+ free(rs->fullnamename);
334
+ snprintfz(buffer, RRDDIMVAR_ID_MAX, "%s.%s.%s", st->type, st->name, rs->name);
335
+ rs->fullnamename = strdup(buffer);
336
+ if(!rs->fullnamename) fatal("Cannot allocate memory for RRDDIMVAR fullnamename");
337
+ rs->hash_fullnamename = simple_hash(rs->fullnamename);
338
+ rs->context_fullnamename = rrdvar_create_and_index("context", &st->rrdcontext->variables_root_index,
339
+ rs->fullnamename, rs->hash_fullnamename, rs->type, rs->value);
340
+ rs->host_fullnamename = rrdvar_create_and_index("host", &st->rrdhost->variables_root_index,
341
+ rs->fullnamename, rs->hash_fullnamename, rs->type, rs->value);
342
+ }
343
+ }
344
+}
345
+
346
+void rrddimvar_free(RRDDIMVAR *rs) {
347
+ if(rs->local_id) {
348
+ rrdvar_index_del(&rs->rrddim->rrdset->variables_root_index, rs->local_id);
349
+ rrdvar_free(rs->local_id);
350
+ }
351
+ if(rs->local_name) {
352
+ rrdvar_index_del(&rs->rrddim->rrdset->variables_root_index, rs->local_name);
353
+ rrdvar_free(rs->local_name);
354
+ }
355
+
356
+ if(rs->context_fullidid) {
357
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdcontext->variables_root_index, rs->context_fullidid);
358
+ rrdvar_free(rs->context_fullidid);
359
+ }
360
+ if(rs->context_fullidname) {
361
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdcontext->variables_root_index, rs->context_fullidname);
362
+ rrdvar_free(rs->context_fullidname);
363
+ }
364
+ if(rs->context_fullnameid) {
365
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdcontext->variables_root_index, rs->context_fullnameid);
366
+ rrdvar_free(rs->context_fullnameid);
367
+ }
368
+ if(rs->context_fullnamename) {
369
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdcontext->variables_root_index, rs->context_fullnamename);
370
+ rrdvar_free(rs->context_fullnamename);
371
+ }
372
+
373
+ if(rs->host_fullidid) {
374
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdhost->variables_root_index, rs->host_fullidid);
375
+ rrdvar_free(rs->host_fullidid);
376
+ }
377
+ if(rs->host_fullidname) {
378
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdhost->variables_root_index, rs->host_fullidname);
379
+ rrdvar_free(rs->host_fullidname);
380
+ }
381
+ if(rs->host_fullnameid) {
382
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdhost->variables_root_index, rs->host_fullnameid);
383
+ rrdvar_free(rs->host_fullnameid);
384
+ }
385
+ if(rs->host_fullnamename) {
386
+ rrdvar_index_del(&rs->rrddim->rrdset->rrdhost->variables_root_index, rs->host_fullnamename);
387
+ rrdvar_free(rs->host_fullnamename);
388
+ }
389
+
390
+ if(rs->rrddim->variables == rs) {
391
+ rs->rrddim->variables = rs->next;
392
+ }
393
+ else {
394
+ RRDDIMVAR *t;
395
+ for (t = rs->rrddim->variables; t && t->next != rs; t = t->next);
396
+ if(!t) error("RRDDIMVAR '%s' not found in dimension '%s.%s/%s' variables linked list", rs->name, rs->rrddim->rrdset->type, rs->rrddim->rrdset->id, rs->rrddim->id);
397
+ else t->next = rs->next;
398
+ }
399
+
400
+ free(rs->prefix);
401
+ free(rs->suffix);
402
+ free(rs->id);
403
+ free(rs->name);
404
+ free(rs->fullidid);
405
+ free(rs->fullidname);
406
+ free(rs->fullnameid);
407
+ free(rs->fullnamename);
408
+ free(rs);
409
}
src/health.h
+92
-1
@@ -25,17 +25,98 @@ extern int rrdvar_compare(void *a, void *b);
25
*
26
*/
27
28
+#define RRDVAR_TYPE_CALCULATED 1
29
+#define RRDVAR_TYPE_TIME_T 2
30
+#define RRDVAR_TYPE_COLLECTED 3
31
+#define RRDVAR_TYPE_TOTAL 4
32
+
33
+// the variables as stored in the variables indexes
34
typedef struct rrdvar {
35
avl avl;
36
37
char *name;
38
uint32_t hash;
39
34
- calculated_number *value;
40
+ int type;
41
+ void *value;
42
43
time_t last_updated;
44
} RRDVAR;
45
46
+// variables linked to charts
47
+typedef struct rrdsetvar {
48
+ char *fullid; // chart type.chart id.variable
49
+ uint32_t hash_fullid;
50
+
51
+ char *fullname; // chart type.chart name.variable
52
+ uint32_t hash_fullname;
53
+
54
+ char *variable; // variable
55
+ uint32_t hash_variable;
56
+
57
+ int type;
58
+ void *value;
59
+
60
+ uint32_t options;
61
+
62
+ RRDVAR *local;
63
+ RRDVAR *context;
64
+ RRDVAR *host;
65
+ RRDVAR *context_name;
66
+ RRDVAR *host_name;
67
+
68
+ struct rrdset *rrdset;
69
+
70
+ struct rrdsetvar *next;
71
+} RRDSETVAR;
72
+
73
+
74
+// variables linked to dimensions
75
+typedef struct rrddimvar {
76
+ char *prefix;
77
+ char *suffix;
78
+
79
+ char *id; // dimension id
80
+ uint32_t hash;
81
+
82
+ char *name; // dimension name
83
+ uint32_t hash_name;
84
+
85
+ char *fullidid; // chart type.chart id.dimension id
86
+ uint32_t hash_fullidid;
87
+
88
+ char *fullidname; // chart type.chart id.dimension name
89
+ uint32_t hash_fullidname;
90
+
91
+ char *fullnameid; // chart type.chart name.dimension id
92
+ uint32_t hash_fullnameid;
93
+
94
+ char *fullnamename; // chart type.chart name.dimension name
95
+ uint32_t hash_fullnamename;
96
+
97
+ int type;
98
+ void *value;
99
+
100
+ uint32_t options;
101
+
102
+ RRDVAR *local_id;
103
+ RRDVAR *local_name;
104
+
105
+ RRDVAR *context_fullidid;
106
+ RRDVAR *context_fullidname;
107
+ RRDVAR *context_fullnameid;
108
+ RRDVAR *context_fullnamename;
109
+
110
+ RRDVAR *host_fullidid;
111
+ RRDVAR *host_fullidname;
112
+ RRDVAR *host_fullnameid;
113
+ RRDVAR *host_fullnamename;
114
+
115
+ struct rrddim *rrddim;
116
+
117
+ struct rrddimvar *next;
118
+} RRDDIMVAR;
119
+
120
typedef struct rrdcalc {
121
avl avl;
122
@@ -55,4 +136,14 @@ typedef struct rrdcalc {
136
struct rrdcalc *prev;
137
} RRDCALC;
138
139
+#include "rrd.h"
140
+
141
+extern void rrdsetvar_rename_all(RRDSET *st);
142
+extern RRDSETVAR *rrdsetvar_create(RRDSET *st, const char *variable, int type, void *value, uint32_t options);
143
+extern void rrdsetvar_free(RRDSETVAR *rs);
144
+
145
+extern void rrddimvar_rename_all(RRDDIM *rd);
146
+extern RRDDIMVAR *rrddimvar_create(RRDDIM *rd, int type, const char *prefix, const char *suffix, void *value, uint32_t options);
147
+extern void rrddimvar_free(RRDDIMVAR *rs);
148
+
149
#endif //NETDATA_HEALTH_H
src/rrd.c
+29
-5
@@ -313,7 +313,10 @@ void rrdset_set_name(RRDSET *st, const char *name)
313
{
314
debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
315
316
- if(st->name) rrdset_index_del_name(&localhost, st);
316
+ if(st->name) {
317
+ rrdset_index_del_name(&localhost, st);
318
+ rrdsetvar_rename_all(st);
319
+ }
320
321
char b[CONFIG_MAX_VALUE + 1];
322
char n[RRD_ID_LENGTH_MAX + 1];
@@ -459,6 +462,7 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
462
st->dimensions = NULL;
463
st->next = NULL;
464
st->mapped = rrd_memory_mode;
465
+ st->variables = NULL;
466
}
467
else {
468
st = calloc(1, size);
@@ -516,12 +520,16 @@ RRDSET *rrdset_create(const char *type, const char *id, const char *name, const
520
st->title = config_get(st->id, "title", varvalue);
521
}
522
519
- st->next = localhost.rrdset_root;
523
+ st->rrdcontext = rrdcontext_create(st->context);
524
+ st->rrdhost = &localhost;
525
+
526
+ st->next = localhost.rrdset_root;
527
localhost.rrdset_root = st;
528
522
- rrdset_index_add(&localhost, st);
529
+ rrdsetvar_create(st, "last_collected", RRDVAR_TYPE_TIME_T, &st->last_collected_time.tv_sec, 0);
530
+ rrdsetvar_create(st, "raw_total", RRDVAR_TYPE_TOTAL, &st->collected_total, 0);
531
524
- st->rrdcontext = rrdcontext_create(st->context);
532
+ rrdset_index_add(&localhost, st);
533
534
pthread_rwlock_unlock(&localhost.rrdset_root_rwlock);
535
@@ -594,6 +602,7 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
602
// we have a file mapped for rd
603
rd->mapped = rrd_memory_mode;
604
rd->flags = 0x00000000;
605
+ rd->variables = NULL;
606
rd->next = NULL;
607
rd->name = NULL;
608
}
@@ -610,6 +619,8 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
619
}
620
rd->memsize = size;
621
622
+ rd->rrdset = st;
623
+
624
strcpy(rd->magic, RRDDIMENSION_MAGIC);
625
strcpy(rd->cache_filename, fullfilename);
626
strncpyz(rd->id, id, RRD_ID_LENGTH_MAX);
@@ -653,6 +664,11 @@ RRDDIM *rrddim_add(RRDSET *st, const char *id, const char *name, long multiplier
664
for(; td->next; td = td->next) ;
665
td->next = rd;
666
}
667
+
668
+ rrddimvar_create(rd, RRDVAR_TYPE_CALCULATED, NULL, NULL, &rd->calculated_value, 0);
669
+ rrddimvar_create(rd, RRDVAR_TYPE_COLLECTED, NULL, "_raw", &rd->collected_value, 0);
670
+ rrddimvar_create(rd, RRDVAR_TYPE_TIME_T, NULL, "_last_collected", &rd->last_collected_time.tv_sec, 0);
671
+
672
pthread_rwlock_unlock(&st->rwlock);
673
674
rrddim_index_add(st, rd);
@@ -667,6 +683,8 @@ void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
683
char varname[CONFIG_MAX_NAME + 1];
684
snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
685
config_set_default(st->id, varname, name);
686
+
687
+ rrddimvar_rename_all(rd);
688
}
689
690
void rrddim_free(RRDSET *st, RRDDIM *rd)
@@ -685,7 +703,10 @@ void rrddim_free(RRDSET *st, RRDDIM *rd)
703
else st->dimensions = rd->next;
704
rd->next = NULL;
705
688
- rrddim_index_del(st, rd);
706
+ while(rd->variables)
707
+ rrddimvar_free(rd->variables);
708
+
709
+ rrddim_index_del(st, rd);
710
711
// free(rd->annotations);
712
if(rd->mapped == RRD_MEMORY_MODE_SAVE) {
@@ -716,6 +737,9 @@ void rrdset_free_all(void)
737
while(st->dimensions)
738
rrddim_free(st, st->dimensions);
739
740
+ while(st->variables)
741
+ rrdsetvar_free(st->variables);
742
+
743
rrdset_index_del(&localhost, st);
744
745
st->rrdcontext->use_count--;
src/rrd.h
+7
-1
@@ -16,7 +16,7 @@ extern int rrd_delete_unupdated_dimensions;
16
#define RRD_ID_LENGTH_MAX 1024
17
18
#define RRDSET_MAGIC "NETDATA RRD SET FILE V018"
19
-#define RRDDIMENSION_MAGIC "NETDATA RRD DIMENSION FILE V017"
19
+#define RRDDIMENSION_MAGIC "NETDATA RRD DIMENSION FILE V018"
20
21
typedef long long total_number;
22
#define TOTAL_NUMBER_FORMAT "%lld"
@@ -150,6 +150,7 @@ struct rrddim {
150
calculated_number stored_volume; // the sum of all stored values so far
151
152
struct rrddim *next; // linking of dimensions within the same data set
153
+ struct rrdset *rrdset;
154
155
// ------------------------------------------------------------------------
156
// members for checking the data when loading from disk
@@ -164,6 +165,8 @@ struct rrddim {
165
166
char magic[sizeof(RRDDIMENSION_MAGIC) + 1]; // a string to be saved, used to identify our data file
167
168
+ struct rrddimvar *variables;
169
+
170
// ------------------------------------------------------------------------
171
// the values stored in this dimension, using our floating point numbers
172
@@ -246,6 +249,8 @@ struct rrdset {
249
total_number last_collected_total; // used internally to calculate percentages
250
251
RRDCONTEXT *rrdcontext;
252
+ struct rrdhost *rrdhost;
253
+
254
struct rrdset *next; // linking of rrdsets
255
256
// ------------------------------------------------------------------------
@@ -265,6 +270,7 @@ struct rrdset {
270
// local variables
271
272
avl_tree_lock variables_root_index;
273
+ RRDSETVAR *variables;
274
};
275
typedef struct rrdset RRDSET;
276
src/web_server.c
+3
-1
@@ -195,7 +195,7 @@ static inline void close_listen_sockets(void) {
195
static inline int bind_to_one(const char *definition, int default_port, int listen_backlog) {
196
int added = 0;
197
struct addrinfo hints;
198
- struct addrinfo *result, *rp;
198
+ struct addrinfo *result = NULL, *rp = NULL;
199
200
char buffer[strlen(definition) + 1];
201
strcpy(buffer, definition);
@@ -275,6 +275,8 @@ static inline int bind_to_one(const char *definition, int default_port, int list
275
}
276
}
277
278
+ freeaddrinfo(result);
279
+
280
return added;
281
}
282