fix contexts labels to avoid clearing the rrdlabels pointer (#19853)
Costa Tsaousis committed
Mar 13, 2025 at 17:16 UTC
a4341ee3d7c0a3e9bab3c098c26531a3efe8b9a9
7 files changed
+51
-44
src/database/contexts/api_v1_contexts.c
+12
-7
@@ -131,13 +131,18 @@ static inline int rrdinstance_to_json_callback(const DICTIONARY_ITEM *item, void
131
if(before && (!ri->first_time_s || before < ri->first_time_s))
132
return 0;
133
134
- if(t_parent->chart_label_key && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, t_parent->chart_label_key,
135
- '\0', NULL) != SP_MATCHED_POSITIVE)
134
+ RRDLABELS *labels = rrdinstance_labels(ri);
135
+
136
+ if(t_parent->chart_label_key && rrdlabels_match_simple_pattern_parsed(
137
+ labels,
138
+ t_parent->chart_label_key,
139
+ '\0', NULL) != SP_MATCHED_POSITIVE)
140
return 0;
141
138
- if(t_parent->chart_labels_filter && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels,
139
- t_parent->chart_labels_filter, ':',
140
- NULL) != SP_MATCHED_POSITIVE)
142
+ if(t_parent->chart_labels_filter && rrdlabels_match_simple_pattern_parsed(
143
+ labels,
144
+ t_parent->chart_labels_filter, ':',
145
+ NULL) != SP_MATCHED_POSITIVE)
146
return 0;
147
148
time_t first_time_s = ri->first_time_s;
@@ -213,9 +218,9 @@ static inline int rrdinstance_to_json_callback(const DICTIONARY_ITEM *item, void
218
buffer_json_array_close(wb);
219
}
220
216
- if(options & RRDCONTEXT_OPTION_SHOW_LABELS && ri->rrdlabels && rrdlabels_entries(ri->rrdlabels)) {
221
+ if(options & RRDCONTEXT_OPTION_SHOW_LABELS && rrdlabels_entries(labels)) {
222
buffer_json_member_add_object(wb, "labels");
218
- rrdlabels_to_buffer_json_members(ri->rrdlabels, wb);
223
+ rrdlabels_to_buffer_json_members(labels, wb);
224
buffer_json_object_close(wb);
225
}
226
src/database/contexts/api_v2_contexts.c
+3
-2
@@ -118,8 +118,9 @@ static FTS_MATCH rrdcontext_to_json_v2_full_text_search(struct rrdcontext_to_jso
118
dfe_done(rm);
119
120
size_t label_searches = 0;
121
- if(unlikely(ri->rrdlabels && rrdlabels_entries(ri->rrdlabels) &&
122
- rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, q, ':', &label_searches) == SP_MATCHED_POSITIVE)) {
121
+ RRDLABELS *labels = rrdinstance_labels(ri);
122
+ if(unlikely(rrdlabels_entries(labels) &&
123
+ rrdlabels_match_simple_pattern_parsed(labels, q, ':', &label_searches) == SP_MATCHED_POSITIVE)) {
124
ctl->q.fts.searches += label_searches;
125
ctl->q.fts.char_searches += label_searches;
126
matched = FTS_MATCHED_LABEL;
src/database/contexts/instance.c
+21
-31
@@ -35,16 +35,24 @@ inline STRING *rrdinstance_acquired_units_dup(RRDINSTANCE_ACQUIRED *ria) {
35
return string_dup(ri->units);
36
}
37
38
-inline RRDLABELS *rrdinstance_acquired_labels(RRDINSTANCE_ACQUIRED *ria) {
39
- RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
40
- if (rrd_flag_check(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS)) {
38
+inline RRDLABELS *rrdinstance_labels(RRDINSTANCE *ri) {
39
+ if(ri->rrdset)
40
+ return ri->rrdset->rrdlabels;
41
+
42
+ if (rrd_flag_check_all(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS)) {
43
rrd_flag_clear(ri, RRD_FLAG_DEMAND_LABELS);
44
load_instance_labels_on_demand(uuidmap_uuid_ptr(ri->uuid), ri);
45
rrdinstance_trigger_updates(ri, __FUNCTION__ );
46
}
47
+
48
return ri->rrdlabels;
49
}
50
51
+inline RRDLABELS *rrdinstance_acquired_labels(RRDINSTANCE_ACQUIRED *ria) {
52
+ RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
53
+ return rrdinstance_labels(ri);
54
+}
55
+
56
inline DICTIONARY *rrdinstance_acquired_functions(RRDINSTANCE_ACQUIRED *ria) {
57
RRDINSTANCE *ri = rrdinstance_acquired_value(ria);
58
if(!ri->rrdset) return NULL;
@@ -107,14 +115,12 @@ static void rrdinstance_insert_callback(const DICTIONARY_ITEM *item __maybe_unus
115
if(!ri->name)
116
ri->name = string_dup(ri->id);
117
110
- if(ri->rrdset) {
111
- ri->rrdlabels = ri->rrdset->rrdlabels;
118
+ ri->rrdlabels = rrdlabels_create();
119
+
120
+ if(ri->rrdset)
121
ri->flags &= ~(RRD_FLAG_OWN_LABELS| RRD_FLAG_DEMAND_LABELS); // no need of atomics at the constructor
113
- }
114
- else {
115
- ri->rrdlabels = rrdlabels_create();
122
+ else
123
ri->flags |= (RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS); // no need of atomics at the constructor
117
- }
124
125
if(ri->rrdset) {
126
if(unlikely(rrdset_flag_check(ri->rrdset, RRDSET_FLAG_HIDDEN)))
@@ -199,27 +205,15 @@ static bool rrdinstance_conflict_callback(const DICTIONARY_ITEM *item __maybe_un
205
rrd_flag_set_updated(ri, RRD_FLAG_UPDATE_REASON_CHANGED_METADATA);
206
}
207
202
- if(ri->rrdset && ri_new->rrdset && ri->rrdset != ri_new->rrdset) {
208
+ if(ri_new->rrdset && ri->rrdset != ri_new->rrdset) {
209
ri->rrdset = ri_new->rrdset;
210
rrd_flag_set_updated(ri, RRD_FLAG_UPDATE_REASON_CHANGED_LINKING);
211
}
212
207
- if(ri->rrdset != ri_new->rrdset) {
208
- ri->rrdset = ri_new->rrdset;
209
-
210
- if(ri->rrdset && rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
211
- RRDLABELS *old = ri->rrdlabels;
212
- ri->rrdlabels = ri->rrdset->rrdlabels;
213
- rrd_flag_clear(ri, RRD_FLAG_OWN_LABELS| RRD_FLAG_DEMAND_LABELS);
214
- rrdlabels_destroy(old);
215
- }
216
- else if(!ri->rrdset && !rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
217
- ri->rrdlabels = rrdlabels_create();
218
- rrd_flag_set(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS);
219
- }
220
- }
221
-
213
if(ri->rrdset) {
214
+ // our labels are not needed any more
215
+ rrdlabels_flush(ri->rrdlabels);
216
+
217
if(unlikely(rrdset_flag_check(ri->rrdset, RRDSET_FLAG_HIDDEN)))
218
rrd_flag_set(ri, RRD_FLAG_HIDDEN);
219
else
@@ -438,12 +432,8 @@ inline void rrdinstance_rrdset_is_freed(RRDSET *st) {
432
433
rrdinstance_set_archived(ri);
434
441
- if(!rrd_flag_check(ri, RRD_FLAG_OWN_LABELS)) {
442
- ri->rrdlabels = rrdlabels_create();
443
- // Do not load copy labels, just load on demand
444
- //rrdlabels_copy(ri->rrdlabels, st->rrdlabels);
445
- rrd_flag_set(ri, RRD_FLAG_OWN_LABELS | RRD_FLAG_DEMAND_LABELS);
446
- }
435
+ SWAP(ri->rrdlabels, st->rrdlabels);
436
+ rrd_flag_set(ri, RRD_FLAG_OWN_LABELS);
437
438
ri->rrdset = NULL;
439
src/database/contexts/internal.h
+2
@@ -481,4 +481,6 @@ void get_metric_retention_by_id(RRDHOST *host, UUIDMAP_ID id, time_t *min_first_
481
void rrdcontext_delete_after_loading(RRDHOST *host, RRDCONTEXT *rc);
482
void rrdcontext_initial_processing_after_loading(RRDCONTEXT *rc);
483
484
+RRDLABELS *rrdinstance_labels(RRDINSTANCE *ri);
485
+
486
#endif //NETDATA_RRDCONTEXT_INTERNAL_H
src/database/contexts/query_target.c
+3
-2
@@ -732,12 +732,13 @@ static inline bool query_instance_matches_labels(
732
SIMPLE_PATTERN *labels_sp)
733
{
734
735
- if (chart_label_key_sp && rrdlabels_match_simple_pattern_parsed(ri->rrdlabels, chart_label_key_sp, '\0', NULL) != SP_MATCHED_POSITIVE)
735
+ RRDLABELS *labels = rrdinstance_labels(ri);
736
+ if (chart_label_key_sp && rrdlabels_match_simple_pattern_parsed(labels, chart_label_key_sp, '\0', NULL) != SP_MATCHED_POSITIVE)
737
return false;
738
739
if (labels_sp) {
740
struct pattern_array *pa = pattern_array_add_simple_pattern(NULL, labels_sp, ':');
740
- bool found = pattern_array_label_match(pa, ri->rrdlabels, ':', NULL);
741
+ bool found = pattern_array_label_match(pa, labels, ':', NULL);
742
pattern_array_free(pa);
743
return found;
744
}
src/database/rrdlabels.c
+9
-2
@@ -183,8 +183,7 @@ static void delete_label(RRDLABEL *label)
183
// ----------------------------------------------------------------------------
184
// rrdlabels_destroy()
185
186
-void rrdlabels_destroy(RRDLABELS *labels)
187
-{
186
+void rrdlabels_flush(RRDLABELS *labels) {
187
if (unlikely(!labels))
188
return;
189
@@ -199,6 +198,14 @@ void rrdlabels_destroy(RRDLABELS *labels)
198
size_t memory_freed = JudyLFreeArray(&labels->JudyL, PJE0);
199
STATS_MINUS_MEMORY(&dictionary_stats_category_rrdlabels, 0, memory_freed + sizeof(RRDLABELS), 0);
200
spinlock_unlock(&labels->spinlock);
201
+}
202
+
203
+void rrdlabels_destroy(RRDLABELS *labels)
204
+{
205
+ if (unlikely(!labels))
206
+ return;
207
+
208
+ rrdlabels_flush(labels);
209
freez(labels);
210
}
211
src/database/rrdlabels.h
+1
@@ -35,6 +35,7 @@ typedef struct rrdlabels RRDLABELS;
35
36
RRDLABELS *rrdlabels_create(void);
37
void rrdlabels_destroy(RRDLABELS *labels_dict);
38
+void rrdlabels_flush(RRDLABELS *labels);
39
void rrdlabels_add(RRDLABELS *labels, const char *name, const char *value, RRDLABEL_SRC ls);
40
void rrdlabels_add_pair(RRDLABELS *labels, const char *string, RRDLABEL_SRC ls);
41
void rrdlabels_value_to_buffer_array_item_or_null(RRDLABELS *labels, BUFFER *wb, const char *key);