Improve storage collector by using dictionary delete callbacks (#21500)
* Add dictionary delete callbacks Ensure proper deallocation of disk-related strings and reset pointers to NULL. Add metadata reset (`collected_metadata = false`) during cleanup to prevent stale data usage. * Reset `st_disk_space` pointer to NULL during cleanup in perflib-storage.
Stelios Fragkakis committed
Jan 8, 2026 at 19:17 UTC
3bcd59a2346c4b626cf74315877802b641430679
1 file changed
+33
-8
src/collectors/windows.plugin/perflib-storage.c
+33
-8
@@ -97,7 +97,13 @@ dict_logical_disk_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, void *va
97
98
static void logical_disk_cleanup(struct logical_disk *d)
99
{
100
+ string_freez(d->filesystem);
101
+ d->filesystem = NULL;
102
+
103
+ d->collected_metadata = false;
104
+
105
rrdset_is_obsolete___safe_from_collector_thread(d->st_disk_space);
106
+ d->st_disk_space = NULL;
107
}
108
109
static void physical_disk_initialize(struct physical_disk *d)
@@ -128,12 +134,21 @@ static void physical_disk_initialize(struct physical_disk *d)
134
static void physical_disk_cleanup(struct physical_disk *d)
135
{
136
string_freez(d->device);
137
+ d->device = NULL;
138
string_freez(d->mount_point);
139
+ d->mount_point = NULL;
140
string_freez(d->manufacturer);
141
+ d->manufacturer = NULL;
142
string_freez(d->model);
143
+ d->model = NULL;
144
string_freez(d->media_type);
145
+ d->media_type = NULL;
146
string_freez(d->name);
147
+ d->name = NULL;
148
string_freez(d->device_id);
149
+ d->device_id = NULL;
150
+
151
+ d->collected_metadata = false;
152
153
rrdset_is_obsolete___safe_from_collector_thread(d->disk_io.st_io);
154
rrdset_is_obsolete___safe_from_collector_thread(d->disk_ops.st_ops);
@@ -153,6 +168,18 @@ void dict_physical_disk_insert_cb(const DICTIONARY_ITEM *item __maybe_unused, vo
168
physical_disk_initialize(pd);
169
}
170
171
+static void dict_logical_disk_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
172
+{
173
+ struct logical_disk *d = value;
174
+ logical_disk_cleanup(d);
175
+}
176
+
177
+static void dict_physical_disk_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused)
178
+{
179
+ struct physical_disk *d = value;
180
+ physical_disk_cleanup(d);
181
+}
182
+
183
static DICTIONARY *logicalDisks = NULL, *physicalDisks = NULL;
184
static void initialize(void)
185
{
@@ -162,11 +189,13 @@ static void initialize(void)
189
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct logical_disk));
190
191
dictionary_register_insert_callback(logicalDisks, dict_logical_disk_insert_cb, NULL);
192
+ dictionary_register_delete_callback(logicalDisks, dict_logical_disk_delete_cb, NULL);
193
194
physicalDisks = dictionary_create_advanced(
195
DICT_OPTION_DONT_OVERWRITE_VALUE | DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct physical_disk));
196
197
dictionary_register_insert_callback(physicalDisks, dict_physical_disk_insert_cb, NULL);
198
+ dictionary_register_delete_callback(physicalDisks, dict_physical_disk_delete_cb, NULL);
199
}
200
201
static STRING *getFileSystemType(struct logical_disk *d, const char *diskName)
@@ -347,15 +376,13 @@ static bool do_logical_disk(PERF_DATA_BLOCK *pDataBlock, int update_every, usec_
376
rrdset_done(d->st_disk_space);
377
}
378
350
- // cleanup
379
+ // cleanup - delete callback will handle resource cleanup
380
{
381
struct logical_disk *d;
382
dfe_start_write(dict, d)
383
{
355
- if (d->last_collected < now_ut) {
356
- logical_disk_cleanup(d);
384
+ if (d->last_collected < now_ut)
385
dictionary_del(dict, d_dfe.name);
358
- }
386
}
387
dfe_done(d);
388
dictionary_garbage_collect(dict);
@@ -661,15 +688,13 @@ static bool do_physical_disk(PERF_DATA_BLOCK *pDataBlock, int update_every, usec
688
}
689
}
690
664
- // cleanup
691
+ // cleanup - delete callback will handle resource cleanup
692
{
693
struct physical_disk *d;
694
dfe_start_write(dict, d)
695
{
669
- if (d->last_collected < now_ut) {
670
- physical_disk_cleanup(d);
696
+ if (d->last_collected < now_ut)
697
dictionary_del(dict, d_dfe.name);
672
- }
698
}
699
dfe_done(d);
700
dictionary_garbage_collect(dict);