@cryptotaxi247 / netdata-1 / commits / 1a75f552b

fix rrdset name crash on cleanup (#19838)

* fix rrdset name crash on cleanup * move rrdset name management outside of the contructors/destructors of the rrdset

Costa Tsaousis committed Mar 12, 2025 at 17:19 UTC 1a75f552b6a24dda3d7d5d172e485530f609107e
3 files changed +48 -46
src/database/rrdset-index-id.c
+28 -18
@@ -67,11 +67,6 @@ static void rrdset_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
67
68 st->id = string_strdupz(chart_full_id);
69
70 - st->name = rrdset_fix_name(host, chart_full_id, ctr->type, NULL, ctr->name);
71 - if(!st->name)
72 - st->name = rrdset_fix_name(host, chart_full_id, ctr->type, NULL, ctr->id);
73 - rrdset_index_add_name(host, st);
74 -
70 st->collection_modulo = rrdset_collection_modulo_init();
71
72 st->parts.id = string_strdupz(ctr->id);
@@ -137,7 +132,7 @@ static void rrdset_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, v
132
133 // the destructor - the dictionary is write locked while this runs
134 static void rrdset_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrdset, void *rrdhost) {
140 - RRDHOST *host = rrdhost;
135 + RRDHOST *host = rrdhost; (void)host;
136 RRDSET *st = rrdset;
137
138 rrdset_flag_clear(st, RRDSET_FLAG_INDEXED_ID);
@@ -146,10 +141,6 @@ static void rrdset_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
141
142 rrdset_stream_send_chart_slot_release(st);
143
149 - // remove it from the name index
150 - rrdset_index_del_name(host, st);
151 -
152 - // release the collector info
144 dictionary_destroy(st->functions_view);
145
146 rrdcalc_unlink_and_delete_all_rrdset_alerts(st);
@@ -203,9 +194,6 @@ static bool rrdset_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused,
194
195 ctr->react_action = RRDSET_REACT_NONE;
196
206 - if (rrdset_reset_name(st, (ctr->name && *ctr->name) ? ctr->name : ctr->id) == 2)
207 - ctr->react_action |= RRDSET_REACT_UPDATED;
208 -
197 if (unlikely(st->priority != ctr->priority)) {
198 st->priority = ctr->priority;
199 ctr->react_action |= RRDSET_REACT_UPDATED;
@@ -430,15 +418,15 @@ RRDSET *rrdset_create_custom(
418 // ------------------------------------------------------------------------
419 // check if it already exists
420
433 - char full_id[RRD_ID_LENGTH_MAX + 1];
434 - snprintfz(full_id, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
421 + char chart_full_id[RRD_ID_LENGTH_MAX + 1];
422 + snprintfz(chart_full_id, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
423
424 // ------------------------------------------------------------------------
425 // allocate it
426
427 netdata_log_debug(D_RRD_CALLS, "Creating RRD_STATS for '%s.%s'.", type, id);
428
441 - struct rrdset_constructor tmp = {
429 + struct rrdset_constructor ctr = {
430 .host = host,
431 .type = type,
432 .id = id,
@@ -456,11 +444,33 @@ RRDSET *rrdset_create_custom(
444 .history_entries = history_entries,
445 };
446
459 - RRDSET *st = rrdset_index_add(host, full_id, &tmp);
460 - return(st);
447 + RRDSET *st = rrdset_index_add(host, chart_full_id, &ctr);
448 +
449 + bool name_updated = false;
450 + if(!st->name) {
451 + st->name = rrdset_fix_name(host, chart_full_id, ctr.type, NULL, ctr.name);
452 + if(!st->name)
453 + st->name = rrdset_fix_name(host, chart_full_id, ctr.type, NULL, ctr.id);
454 +
455 + if(st->name) {
456 + name_updated = true;
457 + rrdset_index_add_name(host, st);
458 + }
459 + }
460 + else if(rrdset_reset_name(st, (name && *name) ? name : id) == 2)
461 + name_updated = true;
462 +
463 + if(name_updated) {
464 + rrdset_flag_set(st, RRDSET_FLAG_METADATA_UPDATE);
465 + rrdhost_flag_set(host, RRDHOST_FLAG_METADATA_UPDATE);
466 + rrdset_metadata_updated(st);
467 + }
468 +
469 + return st;
470 }
471
472 void rrdset_free(RRDSET *st) {
473 if(unlikely(!st)) return;
474 + rrdset_index_del_name(st->rrdhost, st);
475 rrdset_index_del(st->rrdhost, st);
476 }
src/database/rrdset-index-name.c
+19 -27
@@ -49,33 +49,21 @@ int rrdset_reset_name(RRDSET *st, const char *name) {
49
50 if(st->name) {
51 rrdset_index_del_name(host, st);
52 - string_freez(st->name);
53 - st->name = name_string;
52 + SWAP(name_string, st->name);
53 + string_freez(name_string);
54 }
55 else
56 st->name = name_string;
57
58 rrdset_index_add_name(host, st);
59
60 - rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_SEND);
61 - rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_IGNORE);
62 - rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_SEND);
63 - rrdset_flag_clear(st, RRDSET_FLAG_UPSTREAM_IGNORE);
60 + rrdset_flag_clear(st, RRDSET_FLAG_EXPORTING_SEND|RRDSET_FLAG_EXPORTING_IGNORE|RRDSET_FLAG_UPSTREAM_SEND|RRDSET_FLAG_UPSTREAM_IGNORE);
61 rrdset_metadata_updated(st);
62
63 rrdcontext_updated_rrdset_name(st);
64 return 2;
65 }
66
70 -static void rrdset_name_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrdset, void *rrdhost __maybe_unused) {
71 - RRDSET *st = rrdset;
72 - rrdset_flag_set(st, RRDSET_FLAG_INDEXED_NAME);
73 -}
74 -static void rrdset_name_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrdset, void *rrdhost __maybe_unused) {
75 - RRDSET *st = rrdset;
76 - rrdset_flag_clear(st, RRDSET_FLAG_INDEXED_NAME);
77 -}
78 -
67 static RRDSET *rrdset_index_find_name(RRDHOST *host, const char *name) {
68 if (unlikely(!host->rrdset_root_index_name))
69 return NULL;
@@ -83,28 +71,32 @@ static RRDSET *rrdset_index_find_name(RRDHOST *host, const char *name) {
71 }
72
73 void rrdset_index_byname_init(RRDHOST *host) {
86 - if(!host->rrdset_root_index_name) {
87 - host->rrdset_root_index_name = dictionary_create_advanced(
88 - DICT_OPTION_NAME_LINK_DONT_CLONE | DICT_OPTION_VALUE_LINK_DONT_CLONE | DICT_OPTION_DONT_OVERWRITE_VALUE,
89 - &dictionary_stats_category_rrdset, 0);
90 -
91 - dictionary_register_insert_callback(host->rrdset_root_index_name, rrdset_name_insert_callback, host);
92 - dictionary_register_delete_callback(host->rrdset_root_index_name, rrdset_name_delete_callback, host);
93 - }
74 + if(!host->rrdset_root_index_name)
75 + host->rrdset_root_index_name = dictionary_create_view(host->rrdset_root_index);
76 }
77
78 void rrdset_index_add_name(RRDHOST *host, RRDSET *st) {
79 if(!st->name) return;
98 - dictionary_set(host->rrdset_root_index_name, rrdset_name(st), st, sizeof(RRDSET));
80 + const DICTIONARY_ITEM *sta = dictionary_get_and_acquire_item(host->rrdset_root_index, rrdset_id(st));
81 + if(sta) {
82 + const DICTIONARY_ITEM *sta2 = dictionary_view_set_and_acquire_item(host->rrdset_root_index_name, rrdset_name(st), sta);
83 + if(sta2 && dictionary_acquired_item_value(sta2) == st)
84 + rrdset_flag_set(st, RRDSET_FLAG_INDEXED_NAME);
85 + }
86 }
87
88 void rrdset_index_del_name(RRDHOST *host, RRDSET *st) {
102 - if(rrdset_flag_check(st, RRDSET_FLAG_INDEXED_NAME))
103 - dictionary_del(host->rrdset_root_index_name, rrdset_name(st));
89 + if(rrdset_flag_check(st, RRDSET_FLAG_INDEXED_NAME)) {
90 + const DICTIONARY_ITEM *sta = dictionary_get_and_acquire_item(host->rrdset_root_index_name, rrdset_name(st));
91 +
92 + if(sta && dictionary_acquired_item_value(sta) == st)
93 + dictionary_del(host->rrdset_root_index_name, rrdset_name(st));
94 +
95 + rrdset_flag_clear(st, RRDSET_FLAG_INDEXED_NAME);
96 + }
97 }
98
99 RRDSET *rrdset_find_byname(RRDHOST *host, const char *name) {
107 - netdata_log_debug(D_RRD_CALLS, "rrdset_find_byname() for chart '%s' in host '%s'", name, rrdhost_hostname(host));
100 RRDSET *st = rrdset_index_find_name(host, name);
101 return(st);
102 }
src/libnetdata/dictionary/dictionary.h
+1 -1
@@ -194,7 +194,7 @@ DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_set_and_acquire_item_advanced(DICTIO
194
195 // set an item in a dictionary view
196 #define dictionary_view_set_and_acquire_item(dict, name, master_item) dictionary_view_set_and_acquire_item_advanced(dict, name, -1, master_item)
197 -DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_view_set_and_acquire_item_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICTIONARY_ITEM *master_item);
197 +DICT_ITEM_CONST DICTIONARY_ITEM *dictionary_view_set_and_acquire_item_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICT_ITEM_CONST DICTIONARY_ITEM *master_item);
198 #define dictionary_view_set(dict, name, master_item) dictionary_view_set_advanced(dict, name, -1, master_item)
199 void *dictionary_view_set_advanced(DICTIONARY *dict, const char *name, ssize_t name_len, DICT_ITEM_CONST DICTIONARY_ITEM *master_item);
200