@cryptotaxi247 / netdata-1 / commits / 1e81d422c

Fix ebpf shutdown and cgroup ipc integration (#22242)

fix: ensure proper cleanup and synchronization in cgroup and ebpf integration

Stelios Fragkakis committed Apr 22, 2026 at 09:20 UTC 1e81d422cfb750a88e06a88d55b14cb1cba6ca12
4 files changed +18 -10
src/collectors/cgroups.plugin/cgroup-discovery.c
+3 -1
@@ -1194,6 +1194,9 @@ void cgroup_discovery_worker(void *ptr)
1194 discovery_find_all_cgroups();
1195 }
1196
1197 + // Stop the netipc server first so its worker threads cannot iterate cgroup_root while we free it.
1198 + cgroup_netipc_cleanup();
1199 +
1200 // free all cgroups
1201 netdata_mutex_lock(&cgroup_root_mutex);
1202 while(cgroup_root) {
@@ -1204,7 +1207,6 @@ void cgroup_discovery_worker(void *ptr)
1207 netdata_mutex_unlock(&cgroup_root_mutex);
1208
1209 collector_info("discovery thread stopped");
1207 - cgroup_netipc_cleanup();
1210 worker_unregister();
1211 service_exits();
1212 __atomic_store_n(&discovery_thread.exited, 1, __ATOMIC_RELEASE);
src/collectors/cgroups.plugin/cgroup-netipc.c
-4
@@ -90,13 +90,9 @@ static bool cgroups_snapshot_handler(void *user __maybe_unused,
90 }
91 }
92
93 - netdata_mutex_unlock(&cgroup_root_mutex);
94 -
93 bool log_zero_generation = false;
94 bool log_truncated_generation = false;
95
98 - netdata_mutex_lock(&cgroup_root_mutex);
99 -
96 if (count == 0 && last_logged_zero_generation != snapshot_generation) {
97 last_logged_zero_generation = snapshot_generation;
98 log_zero_generation = true;
src/collectors/ebpf.plugin/ebpf.c
+6
@@ -1158,6 +1158,12 @@ void ebpf_stop_threads(int sig)
1158 #endif
1159 netdata_mutex_unlock(&mutex_cgroup_shm);
1160
1161 + // Join the cgroup integration thread before ebpf_exit() tears down the netipc cache it reads.
1162 + if (cgroup_integration_thread.thread) {
1163 + nd_thread_join(cgroup_integration_thread.thread);
1164 + cgroup_integration_thread.thread = NULL;
1165 + }
1166 +
1167 usec_t before_checks_ut = now_monotonic_usec();
1168 if (!ebpf_pre_exit_check_done) {
1169 ebpf_check_before2go();
src/collectors/ebpf.plugin/ebpf_cgroup.c
+9 -5
@@ -347,11 +347,8 @@ static void ebpf_parse_cgroup_netipc_data(void)
347 uint64_t generation = ebpf_cgroup_cache.generation;
348 uint32_t enabled_count = 0;
349
350 - // Publish the latest cgroup state before collectors read the lock-free flags.
350 int systemd_enabled = (int)ebpf_cgroup_cache.systemd_enabled;
351 int integration_active = (count > 0) ? 1 : 0;
353 - ebpf_cgroup_systemd_enabled_set(systemd_enabled);
354 - ebpf_cgroup_integration_active_set(integration_active);
352
353 for (uint32_t i = 0; i < count; i++) {
354 const nipc_cgroups_cache_item_t *item = &ebpf_cgroup_cache.items[i];
@@ -371,6 +368,10 @@ static void ebpf_parse_cgroup_netipc_data(void)
368 netdata_mutex_lock(&mutex_cgroup_shm);
369 preserved_targets = ebpf_count_cgroup_targets_unsafe();
370 preserved_pids = ebpf_count_cgroup_pids_unsafe();
371 + // Publish flags while holding the mutex so collectors never observe a flag
372 + // change before the pid/target lists match it.
373 + ebpf_cgroup_systemd_enabled_set(systemd_enabled);
374 + ebpf_cgroup_integration_active_set(integration_active);
375 netdata_mutex_unlock(&mutex_cgroup_shm);
376
377 if (last_count != 0 ||
@@ -416,6 +417,10 @@ static void ebpf_parse_cgroup_netipc_data(void)
417 int chart_refresh_needed = previous_count != count;
418 ebpf_send_cgroup_chart_set(chart_refresh_needed);
419 previous_count = count;
420 + // Publish integration flags only after the target/pid lists have been rebuilt,
421 + // so collectors never observe integration_active=1 with stale pid state.
422 + ebpf_cgroup_systemd_enabled_set(systemd_enabled);
423 + ebpf_cgroup_integration_active_set(integration_active);
424 netdata_mutex_unlock(&mutex_cgroup_shm);
425
426 if (last_count != count ||
@@ -423,8 +428,7 @@ static void ebpf_parse_cgroup_netipc_data(void)
428 previous_imported_targets != imported_targets ||
429 previous_total_pids != total_pids ||
430 previous_integration_active != integration_active ||
426 - previous_systemd_enabled != systemd_enabled ||
427 - enabled_count == 0 || imported_targets == 0 || total_pids == 0) {
431 + previous_systemd_enabled != systemd_enabled) {
432 collector_info(
433 "EBPF CGROUP: netipc snapshot generation=%llu items=%u enabled=%u imported_targets=%zu total_pids=%zu "
434 "send_cgroup_chart=%d integration_active=%d systemd_enabled=%d refresh_failures=%d",