diff --git a/src/agent/rustjail/src/cgroups/notifier.rs b/src/agent/rustjail/src/cgroups/notifier.rs index e9819da4aed2..ad3f3a8dcc0b 100644 --- a/src/agent/rustjail/src/cgroups/notifier.rs +++ b/src/agent/rustjail/src/cgroups/notifier.rs @@ -110,6 +110,18 @@ async fn register_memory_event_v2( // info!("is1: {}", event.wd == wd1); info!(sl(), "event.wd: {:?}", event.wd); + // When a cgroup is destroyed, an event is sent to eventfd. + // Check if the control paths are gone BEFORE trying to read from them. + // This prevents infinite loops and log floods when the cgroup is destroyed + // while events are being processed. + if !Path::new(&event_control_path).exists() || !Path::new(&cgroup_event_control_path).exists() { + info!( + sl(), + "container[{}] cgroup path no longer exists, stopping event monitoring", &containere_id + ); + return; + } + if event.wd == ev_wd { let oom = get_value_from_cgroup(&event_control_path, "oom_kill"); if oom.unwrap_or(0) > 0 { @@ -124,12 +136,6 @@ async fn register_memory_event_v2( return; } } - - // When a cgroup is destroyed, an event is sent to eventfd. - // So if the control path is gone, return instead of notifying. - if !Path::new(&event_control_path).exists() { - return; - } } }); diff --git a/src/agent/src/rpc.rs b/src/agent/src/rpc.rs index f9df3e1860ed..420e48f1db52 100644 --- a/src/agent/src/rpc.rs +++ b/src/agent/src/rpc.rs @@ -524,7 +524,22 @@ impl AgentService { ); } - let pids = self.get_pids(&cid).await?; + // When the cgroup is destroyed early (e.g., systemd deactivated the scope before + // we finish processing), get_pids() may fail. This is not an error - it just means + // there are no processes left to signal. Log and continue. + let pids = match self.get_pids(&cid).await { + Ok(pids) => pids, + Err(err) => { + warn!( + sl(), + "get_pids failed, cgroup may be destroyed"; + "container-id" => &cid, + "exec-id" => &eid, + "error" => format!("{:?}", err), + ); + Vec::new() + } + }; for pid in pids.iter() { let res = unsafe { libc::kill(*pid, sig) }; if let Err(err) = Errno::result(res).map(drop) {