@cryptotaxi247 / netdata-1 / commits / bead8823c

fix cgroup netdev renames (#20050)

* fix cgroup netdev renames when multiple renames exist for the same device * remove obsolete members and functions

Costa Tsaousis committed Apr 3, 2025 at 20:28 UTC bead8823cc7ed4b4f5b1698605adefb46f0a5041
3 files changed +37 -36
src/collectors/proc.plugin/proc_net_dev.c
+4 -4
@@ -383,9 +383,7 @@ static netdata_mutex_t netdev_mutex = NETDATA_MUTEX_INITIALIZER;
383
384 // ----------------------------------------------------------------------------
385
386 -static inline void netdev_rename(struct netdev *d, struct rename_task *r) {
387 - rename_task_verify_checksum(r);
388 -
386 +static inline void netdev_rename_unsafe(struct netdev *d, struct rename_task *r) {
387 collector_info("CGROUP: renaming network interface '%s' as '%s' under '%s'", d->name, r->container_device, r->container_name);
388
389 netdev_charts_release(d);
@@ -474,7 +472,9 @@ static void netdev_rename_this_device(struct netdev *d) {
472 const DICTIONARY_ITEM *item = dictionary_get_and_acquire_item(netdev_renames, d->name);
473 if(item) {
474 struct rename_task *r = dictionary_acquired_item_value(item);
477 - netdev_rename(d, r);
475 + spinlock_lock(&r->spinlock);
476 + netdev_rename_unsafe(d, r);
477 + spinlock_unlock(&r->spinlock);
478 dictionary_acquired_item_release(netdev_renames, item);
479 }
480 }
src/collectors/proc.plugin/proc_net_dev_renames.c
+27 -29
@@ -4,40 +4,41 @@
4
5 DICTIONARY *netdev_renames = NULL;
6
7 -static XXH64_hash_t rename_task_hash(struct rename_task *r) {
8 - struct rename_task local_copy = *r;
9 - local_copy.checksum = 0;
10 - return XXH3_64bits(&local_copy, sizeof(local_copy));
11 -}
7 +static void netdev_rename_task_cleanup_unsafe(struct rename_task *r) {
8 + cgroup_netdev_release(r->cgroup_netdev_link);
9 + r->cgroup_netdev_link = NULL;
10
13 -// Set the checksum for a rename_task
14 -static void rename_task_set_checksum(struct rename_task *r) {
15 - r->checksum = rename_task_hash(r);
16 -}
11 + rrdlabels_destroy(r->chart_labels);
12 + r->chart_labels = NULL;
13
18 -// Verify the checksum for a rename_task
19 -void rename_task_verify_checksum(struct rename_task *r) {
20 - if(r->checksum != rename_task_hash(r))
21 - fatal("MEMORY CORRUPTION DETECTED in rename_task structure. "
22 - "Expected checksum: 0x%016" PRIx64 ", "
23 - "Calculated checksum: 0x%016" PRIx64,
24 - r->checksum, rename_task_hash(r));
14 + freez_and_set_to_null(r->container_name);
15 + freez_and_set_to_null(r->container_device);
16 + freez_and_set_to_null(r->ctx_prefix);
17 }
18
19 static void dictionary_netdev_rename_delete_cb(const DICTIONARY_ITEM *item __maybe_unused, void *value, void *data __maybe_unused) {
20 struct rename_task *r = value;
21
30 - rename_task_verify_checksum(r);
22 + spinlock_lock(&r->spinlock);
23 + netdev_rename_task_cleanup_unsafe(r);
24 + spinlock_unlock(&r->spinlock);
25 +}
26
32 - cgroup_netdev_release(r->cgroup_netdev_link);
33 - r->cgroup_netdev_link = NULL;
27 +static bool dictionary_netdev_rename_conflict_cb(const DICTIONARY_ITEM *item __maybe_unused, void *old_value, void *new_value, void *data __maybe_unused) {
28 + struct rename_task *old_r = old_value;
29 + struct rename_task *new_r = new_value;
30
35 - rrdlabels_destroy(r->chart_labels);
36 - r->chart_labels = NULL;
31 + spinlock_lock(&old_r->spinlock);
32 + SWAP(old_r->cgroup_netdev_link, new_r->cgroup_netdev_link);
33 + SWAP(old_r->chart_labels, new_r->chart_labels);
34 + SWAP(old_r->container_device, new_r->container_device);
35 + SWAP(old_r->container_name, new_r->container_name);
36 + SWAP(old_r->ctx_prefix, new_r->ctx_prefix);
37 + spinlock_unlock(&old_r->spinlock);
38
38 - freez_and_set_to_null(r->container_name);
39 - freez_and_set_to_null(r->container_device);
40 - freez_and_set_to_null(r->ctx_prefix);
39 + netdev_rename_task_cleanup_unsafe(new_r);
40 +
41 + return true;
42 }
43
44 void netdev_renames_init(void) {
@@ -45,7 +46,8 @@ void netdev_renames_init(void) {
46
47 spinlock_lock(&spinlock);
48 if(!netdev_renames) {
48 - netdev_renames = dictionary_create_advanced(DICT_OPTION_FIXED_SIZE, NULL, sizeof(struct rename_task));
49 + netdev_renames = dictionary_create_advanced(DICT_OPTION_FIXED_SIZE | DICT_OPTION_DONT_OVERWRITE_VALUE, NULL, sizeof(struct rename_task));
50 + dictionary_register_conflict_callback(netdev_renames, dictionary_netdev_rename_conflict_cb, NULL);
51 dictionary_register_delete_callback(netdev_renames, dictionary_netdev_rename_delete_cb, NULL);
52 }
53 spinlock_unlock(&spinlock);
@@ -67,12 +69,8 @@ void cgroup_rename_task_add(
69 .ctx_prefix = strdupz(ctx_prefix),
70 .chart_labels = rrdlabels_create(),
71 .cgroup_netdev_link = cgroup_netdev_link,
70 - .checksum = 0, // Will be set below
72 };
73 rrdlabels_migrate_to_these(tmp.chart_labels, labels);
73 -
74 - // Set the checksum after all fields are initialized
75 - rename_task_set_checksum(&tmp);
74
75 dictionary_set(netdev_renames, host_device, &tmp, sizeof(tmp));
76 }
src/collectors/proc.plugin/proc_net_dev_renames.h
+6 -3
@@ -13,17 +13,20 @@
13 extern DICTIONARY *netdev_renames;
14
15 struct rename_task {
16 + SPINLOCK spinlock;
17 const char *container_device;
18 const char *container_name;
19 const char *ctx_prefix;
20 RRDLABELS *chart_labels;
21 const DICTIONARY_ITEM *cgroup_netdev_link;
21 - XXH64_hash_t checksum;
22 };
23
24 -void netdev_renames_init(void);
24 +#define freez_and_set_to_null(p) do { \
25 + freez((void *)p); \
26 + p = NULL; \
27 +} while(0)
28
26 -void rename_task_verify_checksum(struct rename_task *r);
29 +void netdev_renames_init(void);
30
31 void cgroup_netdev_reset_all(void);
32 void cgroup_netdev_release(const DICTIONARY_ITEM *link);