master
c 87 lines 3 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "proc_net_dev_renames.h"
4
5 DICTIONARY *netdev_renames = NULL;
6
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
11 rrdlabels_destroy(r->chart_labels);
12 r->chart_labels = NULL;
13
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
22 spinlock_lock(&r->spinlock);
23 netdev_rename_task_cleanup_unsafe(r);
24 spinlock_unlock(&r->spinlock);
25 }
26
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
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
39 netdev_rename_task_cleanup_unsafe(new_r);
40
41 return true;
42 }
43
44 static SPINLOCK netdev_renames_spinlock = SPINLOCK_INITIALIZER;
45 void netdev_renames_init(void) {
46 spinlock_lock(&netdev_renames_spinlock);
47 if(!netdev_renames) {
48 netdev_renames = dictionary_create_advanced(DICT_OPTION_FIXED_SIZE | DICT_OPTION_DONT_OVERWRITE_VALUE, NULL, sizeof(struct rename_task));
49 dictionary_register_conflict_callback(netdev_renames, dictionary_netdev_rename_conflict_cb, NULL);
50 dictionary_register_delete_callback(netdev_renames, dictionary_netdev_rename_delete_cb, NULL);
51 }
52 spinlock_unlock(&netdev_renames_spinlock);
53 }
54
55 void netdev_renames_destroy(void) {
56 spinlock_lock(&netdev_renames_spinlock);
57 dictionary_destroy(netdev_renames);
58 netdev_renames = NULL;
59 spinlock_unlock(&netdev_renames_spinlock);
60 }
61
62 void cgroup_rename_task_add(
63 const char *host_device,
64 const char *container_device,
65 const char *container_name,
66 RRDLABELS *labels,
67 const char *ctx_prefix,
68 const DICTIONARY_ITEM *cgroup_netdev_link)
69 {
70 netdev_renames_init();
71
72 struct rename_task tmp = {
73 .container_device = strdupz(container_device),
74 .container_name = strdupz(container_name),
75 .ctx_prefix = strdupz(ctx_prefix),
76 .chart_labels = rrdlabels_create(),
77 .cgroup_netdev_link = cgroup_netdev_link,
78 };
79 rrdlabels_migrate_to_these(tmp.chart_labels, labels);
80
81 dictionary_set(netdev_renames, host_device, &tmp, sizeof(tmp));
82 }
83
84 // other threads can call this function to delete a rename to a netdev
85 void cgroup_rename_task_device_del(const char *host_device) {
86 dictionary_del(netdev_renames, host_device);
87 }