use std::fs;
pub fn detect_memory_limit() -> u64 {
if let Some(limit) = read_cgroup_v2_limit() {
tracing::info!(
limit_bytes = limit,
source = "cgroup-v2",
"detected memory limit"
);
return limit;
}
if let Some(limit) = read_cgroup_v1_limit() {
tracing::info!(
limit_bytes = limit,
source = "cgroup-v1",
"detected memory limit"
);
return limit;
}
let mut sys = sysinfo::System::new();
sys.refresh_memory();
let total = sys.total_memory();
tracing::info!(
limit_bytes = total,
source = "system-memory",
"detected memory limit (no cgroup)"
);
total
}
fn read_cgroup_v2_limit() -> Option<u64> {
let content = fs::read_to_string("/sys/fs/cgroup/memory.max").ok()?;
let trimmed = content.trim();
if trimmed == "max" {
return None; }
trimmed.parse::<u64>().ok()
}
fn read_cgroup_v1_limit() -> Option<u64> {
let content = fs::read_to_string("/sys/fs/cgroup/memory/memory.limit_in_bytes").ok()?;
let value = content.trim().parse::<u64>().ok()?;
if value > 1 << 62 {
return None;
}
Some(value)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_detect_memory_limit_returns_nonzero() {
let limit = detect_memory_limit();
assert!(limit > 0, "memory limit should be positive");
}
}