#![cfg(all(feature = "backend-linux", target_os = "linux"))]
use bvisor::linux::cgroup::{probe_cgroup_delegation, CgroupLeaf, CgroupLimits};
use std::io::Write;
use std::sync::atomic::{AtomicU64, Ordering};
static LEAF_COUNTER: AtomicU64 = AtomicU64::new(0);
fn pids_delegated(base: &std::path::Path) -> bool {
std::fs::read_to_string(base.join("cgroup.subtree_control"))
.map(|text| text.split_whitespace().any(|c| c == "pids"))
.unwrap_or(false)
}
#[test]
fn real_delegated_leaf_roundtrip_or_explicit_skip() {
let mut sink = std::io::stderr();
let Some(base) = probe_cgroup_delegation() else {
let _ = writeln!(
sink,
"SKIP real_delegated_leaf_roundtrip: no writable delegated cgroup v2 base \
(probe_cgroup_delegation() == None) on this host"
);
return;
};
let _ = writeln!(
sink,
"REAL cgroup v2 delegation available at {}; running the live leaf round-trip",
base.display()
);
let pids = pids_delegated(&base);
let suffix = LEAF_COUNTER.fetch_add(1, Ordering::Relaxed);
let name = format!("bvisor-test-leaf-{}-{suffix}", std::process::id());
let limits = if pids {
CgroupLimits::with_pids_max(32)
} else {
let _ = writeln!(
sink,
"NOTE: `pids` not delegated at this base; creating a bare leaf (no limit) to \
still prove create/remove round-trips on the real kernel"
);
CgroupLimits::default()
};
let mut leaf = match CgroupLeaf::create(&base, &name, limits) {
Ok(leaf) => leaf,
Err(e) => {
let _ = writeln!(
sink,
"SKIP real_delegated_leaf_roundtrip: probe said writable but create failed \
({e}); treating as no-delegation rather than a false failure"
);
return;
}
};
assert!(
leaf.dir().expect("dir").is_dir(),
"the real leaf must exist"
);
if pids {
let readback = std::fs::read_to_string(leaf.dir().expect("dir").join("pids.max"))
.expect("read back real pids.max");
assert_eq!(
readback.trim(),
"32",
"the kernel must echo the pids.max we wrote"
);
assert!(
leaf.setup().pids_enforced,
"a delegated+written pids limit is honestly Enforced"
);
}
leaf.remove().expect("remove the real leaf");
assert!(
!base.join(&name).exists(),
"the real leaf must be gone after remove"
);
}