use std::fs; use std::path::PathBuf; #[derive(Debug)] pub enum CgroupError { #[allow(unused)] PathNotFound(PathBuf), NotSupported, PermissionDenied, #[allow(unused)] Io(std::io::Error), } impl From for CgroupError { fn from(e: std::io::Error) -> Self { CgroupError::Io(e) } } pub fn get_cgroup_path() -> Result { let cgroup_info = fs::read_to_string("/proc/1/cgroup")?; // Format: "0::/kubepods.slice/..." - we want the part after the second colon let cgroup_rel = cgroup_info .lines() .next() .and_then(|line| line.splitn(3, ':').nth(2)) .unwrap_or("") .trim(); let cgroup_path = PathBuf::from(format!("/sys/fs/cgroup{}", cgroup_rel)); if !cgroup_path.is_dir() { return Err(CgroupError::PathNotFound(cgroup_path)); } Ok(cgroup_path) } pub fn disable_oom_group() -> Result<(), CgroupError> { let cgroup_path = get_cgroup_path()?; let oom_group_file = cgroup_path.join("memory.oom.group"); if !oom_group_file.exists() { tracing::warn!( "memory.oom.group not found at {:?} — cgroups v2 memory controller may not be enabled. \ OOM killer may kill the entire pod instead of individual jobs", oom_group_file ); return Err(CgroupError::NotSupported); } let current = fs::read_to_string(&oom_group_file)?; if current.trim() == "0" { tracing::info!("memory.oom.group already disabled at {:?}", cgroup_path); return Ok(()); } tracing::info!( "memory.oom.group is currently '{}' at {:?}, attempting to disable", current.trim(), cgroup_path ); match fs::write(&oom_group_file, "0") { Ok(_) => { // Verify the write took effect match fs::read_to_string(&oom_group_file) { Ok(val) if val.trim() == "0" => { tracing::info!("Disabled memory.oom.group at {:?}", cgroup_path); } Ok(val) => { tracing::error!( "Wrote 0 to memory.oom.group but read back '{}' at {:?}. \ OOM killer may kill the entire pod instead of individual jobs", val.trim(), cgroup_path ); return Err(CgroupError::Io(std::io::Error::new( std::io::ErrorKind::Other, format!( "memory.oom.group write did not take effect, read back '{}'", val.trim() ), ))); } Err(e) => { tracing::warn!( "Wrote 0 to memory.oom.group but could not verify at {:?}: {e}", cgroup_path ); } } Ok(()) } Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => { tracing::error!( "Failed to disable memory.oom.group at {:?} (permission denied). \ The container needs SYS_RESOURCE capability or privileged mode. \ OOM killer WILL kill the entire pod instead of individual jobs", oom_group_file ); Err(CgroupError::PermissionDenied) } Err(e) => { tracing::error!( "Failed to disable memory.oom.group at {:?}: {e}. \ OOM killer may kill the entire pod instead of individual jobs", oom_group_file ); Err(CgroupError::Io(e)) } } }