@cryptotaxi247 / netdata-1 / commits / fe8d713e7

Fix crashes No 3 (#20007)

reinitialize data collection if an OBSOLETE or ARCHIVED dimension is collected

Costa Tsaousis committed Mar 31, 2025 at 14:34 UTC fe8d713e74cae9d4c8be43254fb7f13d19a35d05
4 files changed +22 -11
src/collectors/cgroups.plugin/cgroup-discovery.c
+1
@@ -124,6 +124,7 @@ static inline void cgroup_free(struct cgroup *cg) {
124
125 rrdlabels_destroy(cg->chart_labels);
126
127 + memset(cg, 0, sizeof(*cg));
128 freez(cg);
129
130 cgroup_root_count--;
src/database/rrddim.c
+17 -9
@@ -35,6 +35,16 @@ static void *rrddim_alloc_db(size_t entries) {
35 return callocz(entries, sizeof(storage_number));
36 }
37
38 +static void rrddim_reinitialize_collection(RRDDIM *rd) {
39 + RRDSET *st = rd->rrdset;
40 +
41 + for(size_t tier = 0; tier < nd_profile.storage_tiers; tier++) {
42 + if (!rd->tiers[tier].sch)
43 + rd->tiers[tier].sch =
44 + storage_metric_store_init(rd->tiers[tier].seb, rd->tiers[tier].smh, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->smg[tier]);
45 + }
46 +}
47 +
48 static void rrddim_insert_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrddim, void *constructor_data) {
49 struct rrddim_constructor *ctr = constructor_data;
50 RRDDIM *rd = rrddim;
@@ -244,6 +254,8 @@ static void rrddim_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
254 string_freez(rd->id);
255 string_freez(rd->name);
256 uuidmap_free(rd->uuid);
257 +
258 + memset(rd, 0, sizeof(RRDDIM));
259 }
260
261 static bool rrddim_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused, void *rrddim, void *new_rrddim, void *constructor_data) {
@@ -255,19 +267,14 @@ static bool rrddim_conflict_callback(const DICTIONARY_ITEM *item __maybe_unused,
267
268 ctr->react_action = RRDDIM_REACT_NONE;
269
270 + rrddim_flag_clear(rd, RRDDIM_FLAG_ARCHIVED | RRDDIM_FLAG_OBSOLETE);
271 +
272 int rc = rrddim_reset_name(st, rd, ctr->name);
273 rc += rrddim_set_algorithm(st, rd, ctr->algorithm);
274 rc += rrddim_set_multiplier(st, rd, ctr->multiplier);
275 rc += rrddim_set_divisor(st, rd, ctr->divisor);
276
263 - for(size_t tier = 0; tier < nd_profile.storage_tiers;tier++) {
264 - if (!rd->tiers[tier].sch)
265 - rd->tiers[tier].sch =
266 - storage_metric_store_init(rd->tiers[tier].seb, rd->tiers[tier].smh, st->rrdhost->db[tier].tier_grouping * st->update_every, rd->rrdset->smg[tier]);
267 - }
268 -
269 - if(rrddim_flag_check(rd, RRDDIM_FLAG_ARCHIVED))
270 - rrddim_flag_clear(rd, RRDDIM_FLAG_ARCHIVED);
277 + rrddim_reinitialize_collection(rd);
278
279 if(unlikely(rc))
280 ctr->react_action = RRDDIM_REACT_UPDATED;
@@ -559,7 +566,8 @@ inline void rrddim_is_obsolete___safe_from_collector_thread(RRDSET *st, RRDDIM *
566 inline void rrddim_isnot_obsolete___safe_from_collector_thread(RRDSET *st __maybe_unused, RRDDIM *rd) {
567 netdata_log_debug(D_RRD_CALLS, "rrddim_isnot_obsolete___safe_from_collector_thread() for chart %s, dimension %s", rrdset_name(st), rrddim_name(rd));
568
562 - rrddim_flag_clear(rd, RRDDIM_FLAG_OBSOLETE);
569 + rrddim_flag_clear(rd, RRDDIM_FLAG_OBSOLETE|RRDDIM_FLAG_ARCHIVED);
570 + rrddim_reinitialize_collection(rd);
571 rrdcontext_updated_rrddim_flags(rd);
572 }
573
src/database/rrdset-collection.c
+2 -2
@@ -686,8 +686,8 @@ void rrdset_timed_done(RRDSET *st, struct timeval now, bool pending_rrdset_next)
686 last_collected_total += rd->collector.last_collected_value;
687 collected_total += rd->collector.collected_value;
688
689 - if(unlikely(rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE))) {
690 - netdata_log_error("Dimension %s in chart '%s' has the OBSOLETE flag set, but it is collected.", rrddim_name(rd), rrdset_id(st));
689 + if(unlikely(rrddim_flag_check(rd, RRDDIM_FLAG_OBSOLETE | RRDDIM_FLAG_ARCHIVED))) {
690 + netdata_log_error("Dimension %s in chart '%s' has the OBSOLETE or ARCHIVED flag set, but it is collected.", rrddim_name(rd), rrdset_id(st));
691 rrddim_isnot_obsolete___safe_from_collector_thread(st, rd);
692 }
693 }
src/database/rrdset-index-id.c
+2
@@ -179,6 +179,8 @@ static void rrdset_delete_callback(const DICTIONARY_ITEM *item __maybe_unused, v
179 string_freez(st->module_name);
180
181 freez(st->exporting_flags);
182 +
183 + memset(st, 0, sizeof(RRDSET));
184 }
185
186 // the item to be inserted, is already in the dictionary