@cryptotaxi247 / netdata-1 / commits / efded8959

add missing spinlock unlocks on containers (#19011)

* add missing spinlock unlocks on containers * do not destroy the hashtable when cleaning up old versions

Costa Tsaousis committed Nov 14, 2024 at 14:05 UTC efded89593b5870cd4eae71bb6b102b753e2b8a0
3 files changed +62 -58
src/libnetdata/os/system-maps/cached-gid-groupname.c
+30 -28
@@ -17,7 +17,8 @@ static struct {
17 bool initialized;
18 SPINLOCK spinlock;
19 SIMPLE_HASHTABLE_GROUPNAMES_CACHE ht;
20 -} uc = {
20 +} group_cache = {
21 + .initialized = false,
22 .spinlock = NETDATA_SPINLOCK_INITIALIZER,
23 .ht = { 0 },
24 };
@@ -31,13 +32,13 @@ static bool compar_gid_ptr(gid_t *a, gid_t *b) {
32 }
33
34 void cached_groupname_populate_by_gid(gid_t gid, const char *groupname, uint32_t version) {
34 - internal_fatal(!uc.initialized, "system-users cache needs to be initialized");
35 + internal_fatal(!group_cache.initialized, "system-users cache needs to be initialized");
36 if(!groupname || !*groupname) return;
37
37 - spinlock_lock(&uc.spinlock);
38 + spinlock_lock(&group_cache.spinlock);
39
40 XXH64_hash_t hash = XXH3_64bits(&gid, sizeof(gid));
40 - SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_get_slot_GROUPNAMES_CACHE(&uc.ht, hash, &gid, true);
41 + SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_get_slot_GROUPNAMES_CACHE(&group_cache.ht, hash, &gid, true);
42 CACHED_GROUPNAME *cg = SIMPLE_HASHTABLE_SLOT_DATA(sl);
43 if(!cg || (cg->version && version > cg->version)) {
44 internal_fatal(cg && cg->gid != gid, "invalid gid matched from cache");
@@ -50,19 +51,19 @@ void cached_groupname_populate_by_gid(gid_t gid, const char *groupname, uint32_t
51 cg->version = version;
52 cg->gid = gid;
53 cg->groupname = string_strdupz(groupname);
53 - simple_hashtable_set_slot_GROUPNAMES_CACHE(&uc.ht, sl, hash, cg);
54 + simple_hashtable_set_slot_GROUPNAMES_CACHE(&group_cache.ht, sl, hash, cg);
55 }
56
56 - spinlock_unlock(&uc.spinlock);
57 + spinlock_unlock(&group_cache.spinlock);
58 }
59
60 CACHED_GROUPNAME cached_groupname_get_by_gid(gid_t gid) {
60 - internal_fatal(!uc.initialized, "system-users cache needs to be initialized");
61 + internal_fatal(!group_cache.initialized, "system-users cache needs to be initialized");
62
62 - spinlock_lock(&uc.spinlock);
63 + spinlock_lock(&group_cache.spinlock);
64
65 XXH64_hash_t hash = XXH3_64bits(&gid, sizeof(gid));
65 - SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_get_slot_GROUPNAMES_CACHE(&uc.ht, hash, &gid, true);
66 + SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_get_slot_GROUPNAMES_CACHE(&group_cache.ht, hash, &gid, true);
67 CACHED_GROUPNAME *cg = SIMPLE_HASHTABLE_SLOT_DATA(sl);
68 if(!cg) {
69 cg = callocz(1, sizeof(*cg));
@@ -79,7 +80,7 @@ CACHED_GROUPNAME cached_groupname_get_by_gid(gid_t gid) {
80 cg->groupname = string_strdupz(gr.gr_name);
81
82 cg->gid = gid;
82 - simple_hashtable_set_slot_GROUPNAMES_CACHE(&uc.ht, sl, hash, cg);
83 + simple_hashtable_set_slot_GROUPNAMES_CACHE(&group_cache.ht, sl, hash, cg);
84 }
85
86 internal_fatal(cg->gid != gid, "invalid gid matched from cache");
@@ -90,7 +91,7 @@ CACHED_GROUPNAME cached_groupname_get_by_gid(gid_t gid) {
91 .groupname = string_dup(cg->groupname),
92 };
93
93 - spinlock_unlock(&uc.spinlock);
94 + spinlock_unlock(&group_cache.spinlock);
95 return rc;
96 }
97
@@ -99,21 +100,21 @@ void cached_groupname_release(CACHED_GROUPNAME cg) {
100 }
101
102 void cached_groupnames_init(void) {
102 - if(uc.initialized) return;
103 - uc.initialized = true;
103 + if(group_cache.initialized) return;
104 + group_cache.initialized = true;
105
105 - spinlock_init(&uc.spinlock);
106 - simple_hashtable_init_GROUPNAMES_CACHE(&uc.ht, 100);
106 + spinlock_init(&group_cache.spinlock);
107 + simple_hashtable_init_GROUPNAMES_CACHE(&group_cache.ht, 100);
108 }
109
110 void cached_groupnames_destroy(void) {
110 - if(!uc.initialized) return;
111 + if(!group_cache.initialized) return;
112
112 - spinlock_lock(&uc.spinlock);
113 + spinlock_lock(&group_cache.spinlock);
114
114 - for(SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_first_read_only_GROUPNAMES_CACHE(&uc.ht);
115 + for(SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_first_read_only_GROUPNAMES_CACHE(&group_cache.ht);
116 sl;
116 - sl = simple_hashtable_next_read_only_GROUPNAMES_CACHE(&uc.ht, sl)) {
117 + sl = simple_hashtable_next_read_only_GROUPNAMES_CACHE(&group_cache.ht, sl)) {
118 CACHED_GROUPNAME *u = SIMPLE_HASHTABLE_SLOT_DATA(sl);
119 if(u) {
120 string_freez(u->groupname);
@@ -122,26 +123,27 @@ void cached_groupnames_destroy(void) {
123 }
124 }
125
125 - simple_hashtable_destroy_GROUPNAMES_CACHE(&uc.ht);
126 - uc.initialized = false;
126 + simple_hashtable_destroy_GROUPNAMES_CACHE(&group_cache.ht);
127 + group_cache.initialized = false;
128 +
129 + spinlock_unlock(&group_cache.spinlock);
130 }
131
132 void cached_groupnames_delete_old_versions(uint32_t version) {
130 - if(!uc.initialized) return;
133 + if(!group_cache.initialized) return;
134
132 - spinlock_lock(&uc.spinlock);
135 + spinlock_lock(&group_cache.spinlock);
136
134 - for(SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_first_read_only_GROUPNAMES_CACHE(&uc.ht);
137 + for(SIMPLE_HASHTABLE_SLOT_GROUPNAMES_CACHE *sl = simple_hashtable_first_read_only_GROUPNAMES_CACHE(&group_cache.ht);
138 sl;
136 - sl = simple_hashtable_next_read_only_GROUPNAMES_CACHE(&uc.ht, sl)) {
139 + sl = simple_hashtable_next_read_only_GROUPNAMES_CACHE(&group_cache.ht, sl)) {
140 CACHED_GROUPNAME *cg = SIMPLE_HASHTABLE_SLOT_DATA(sl);
141 if(cg && cg->version && cg->version < version) {
142 string_freez(cg->groupname);
143 freez(cg);
141 - simple_hashtable_del_slot_GROUPNAMES_CACHE(&uc.ht, sl);
144 + simple_hashtable_del_slot_GROUPNAMES_CACHE(&group_cache.ht, sl);
145 }
146 }
147
145 - simple_hashtable_destroy_GROUPNAMES_CACHE(&uc.ht);
146 - uc.initialized = false;
148 + spinlock_unlock(&group_cache.spinlock);
149 }
src/libnetdata/os/system-maps/cached-sid-username.c
+2 -1
@@ -35,7 +35,8 @@ static struct {
35 SPINLOCK spinlock;
36 struct simple_hashtable_SID hashtable;
37 } sid_globals = {
38 - .spinlock = NETDATA_SPINLOCK_INITIALIZER,
38 + .spinlock = NETDATA_SPINLOCK_INITIALIZER,
39 + .hashtable = { 0 },
40 };
41
42 static inline SID_KEY *sid_value_to_key(SID_VALUE *s) {
src/libnetdata/os/system-maps/cached-uid-username.c
+30 -29
@@ -14,11 +14,11 @@
14 #include "libnetdata/simple_hashtable/simple_hashtable.h"
15
16 static struct {
17 - uint32_t version;
17 bool initialized;
18 SPINLOCK spinlock;
19 SIMPLE_HASHTABLE_USERNAMES_CACHE ht;
21 -} uc = {
20 +} user_cache = {
21 + .initialized = false,
22 .spinlock = NETDATA_SPINLOCK_INITIALIZER,
23 .ht = { 0 },
24 };
@@ -32,13 +32,13 @@ static bool compar_uid_ptr(uid_t *a, uid_t *b) {
32 }
33
34 void cached_username_populate_by_uid(uid_t uid, const char *username, uint32_t version) {
35 - internal_fatal(!uc.initialized, "system-users cache needs to be initialized");
35 + internal_fatal(!user_cache.initialized, "system-users cache needs to be initialized");
36 if(!username || !*username) return;
37
38 - spinlock_lock(&uc.spinlock);
38 + spinlock_lock(&user_cache.spinlock);
39
40 XXH64_hash_t hash = XXH3_64bits(&uid, sizeof(uid));
41 - SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_get_slot_USERNAMES_CACHE(&uc.ht, hash, &uid, true);
41 + SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_get_slot_USERNAMES_CACHE(&user_cache.ht, hash, &uid, true);
42 CACHED_USERNAME *cu = SIMPLE_HASHTABLE_SLOT_DATA(sl);
43 if(!cu || (cu->version && version > cu->version)) {
44 internal_fatal(cu && cu->uid != uid, "invalid uid matched from cache");
@@ -51,19 +51,19 @@ void cached_username_populate_by_uid(uid_t uid, const char *username, uint32_t v
51 cu->version = version;
52 cu->uid = uid;
53 cu->username = string_strdupz(username);
54 - simple_hashtable_set_slot_USERNAMES_CACHE(&uc.ht, sl, hash, cu);
54 + simple_hashtable_set_slot_USERNAMES_CACHE(&user_cache.ht, sl, hash, cu);
55 }
56
57 - spinlock_unlock(&uc.spinlock);
57 + spinlock_unlock(&user_cache.spinlock);
58 }
59
60 CACHED_USERNAME cached_username_get_by_uid(uid_t uid) {
61 - internal_fatal(!uc.initialized, "system-users cache needs to be initialized");
61 + internal_fatal(!user_cache.initialized, "system-users cache needs to be initialized");
62
63 - spinlock_lock(&uc.spinlock);
63 + spinlock_lock(&user_cache.spinlock);
64
65 XXH64_hash_t hash = XXH3_64bits(&uid, sizeof(uid));
66 - SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_get_slot_USERNAMES_CACHE(&uc.ht, hash, &uid, true);
66 + SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_get_slot_USERNAMES_CACHE(&user_cache.ht, hash, &uid, true);
67 CACHED_USERNAME *cu = SIMPLE_HASHTABLE_SLOT_DATA(sl);
68 if(!cu) {
69 cu = callocz(1, sizeof(*cu));
@@ -80,7 +80,7 @@ CACHED_USERNAME cached_username_get_by_uid(uid_t uid) {
80 cu->username = string_strdupz(pw.pw_name);
81
82 cu->uid = uid;
83 - simple_hashtable_set_slot_USERNAMES_CACHE(&uc.ht, sl, hash, cu);
83 + simple_hashtable_set_slot_USERNAMES_CACHE(&user_cache.ht, sl, hash, cu);
84 }
85
86 internal_fatal(cu->uid != uid, "invalid uid matched from cache");
@@ -91,7 +91,7 @@ CACHED_USERNAME cached_username_get_by_uid(uid_t uid) {
91 .username = string_dup(cu->username),
92 };
93
94 - spinlock_unlock(&uc.spinlock);
94 + spinlock_unlock(&user_cache.spinlock);
95 return rc;
96 }
97
@@ -100,21 +100,21 @@ void cached_username_release(CACHED_USERNAME cu) {
100 }
101
102 void cached_usernames_init(void) {
103 - if(uc.initialized) return;
104 - uc.initialized = true;
103 + if(user_cache.initialized) return;
104 + user_cache.initialized = true;
105
106 - spinlock_init(&uc.spinlock);
107 - simple_hashtable_init_USERNAMES_CACHE(&uc.ht, 100);
106 + spinlock_init(&user_cache.spinlock);
107 + simple_hashtable_init_USERNAMES_CACHE(&user_cache.ht, 100);
108 }
109
110 void cached_usernames_destroy(void) {
111 - if(!uc.initialized) return;
111 + if(!user_cache.initialized) return;
112
113 - spinlock_lock(&uc.spinlock);
113 + spinlock_lock(&user_cache.spinlock);
114
115 - for(SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_first_read_only_USERNAMES_CACHE(&uc.ht);
115 + for(SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_first_read_only_USERNAMES_CACHE(&user_cache.ht);
116 sl;
117 - sl = simple_hashtable_next_read_only_USERNAMES_CACHE(&uc.ht, sl)) {
117 + sl = simple_hashtable_next_read_only_USERNAMES_CACHE(&user_cache.ht, sl)) {
118 CACHED_USERNAME *u = SIMPLE_HASHTABLE_SLOT_DATA(sl);
119 if(u) {
120 string_freez(u->username);
@@ -123,26 +123,27 @@ void cached_usernames_destroy(void) {
123 }
124 }
125
126 - simple_hashtable_destroy_USERNAMES_CACHE(&uc.ht);
127 - uc.initialized = false;
126 + simple_hashtable_destroy_USERNAMES_CACHE(&user_cache.ht);
127 + user_cache.initialized = false;
128 +
129 + spinlock_unlock(&user_cache.spinlock);
130 }
131
132 void cached_usernames_delete_old_versions(uint32_t version) {
131 - if(!uc.initialized) return;
133 + if(!user_cache.initialized) return;
134
133 - spinlock_lock(&uc.spinlock);
135 + spinlock_lock(&user_cache.spinlock);
136
135 - for(SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_first_read_only_USERNAMES_CACHE(&uc.ht);
137 + for(SIMPLE_HASHTABLE_SLOT_USERNAMES_CACHE *sl = simple_hashtable_first_read_only_USERNAMES_CACHE(&user_cache.ht);
138 sl;
137 - sl = simple_hashtable_next_read_only_USERNAMES_CACHE(&uc.ht, sl)) {
139 + sl = simple_hashtable_next_read_only_USERNAMES_CACHE(&user_cache.ht, sl)) {
140 CACHED_USERNAME *cu = SIMPLE_HASHTABLE_SLOT_DATA(sl);
141 if(cu && cu->version && cu->version < version) {
142 string_freez(cu->username);
143 freez(cu);
142 - simple_hashtable_del_slot_USERNAMES_CACHE(&uc.ht, sl);
144 + simple_hashtable_del_slot_USERNAMES_CACHE(&user_cache.ht, sl);
145 }
146 }
147
146 - simple_hashtable_destroy_USERNAMES_CACHE(&uc.ht);
147 - uc.initialized = false;
148 + spinlock_unlock(&user_cache.spinlock);
149 }