This commit is contained in:
mchtech 2025-08-11 12:49:30 -04:00 committed by GitHub
commit f3f7e2a165
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 50 additions and 18 deletions

View File

@ -1167,21 +1167,37 @@ impl Manager {
})
}
pub fn subcgroup(&self) -> &str {
// Check if we're in a Docker-in-Docker setup by verifying:
// 1. We're using cgroups v2 (which restricts direct process control)
// 2. An "init" subdirectory exists (used by DinD for process delegation)
let is_dind = cgroups::hierarchies::is_cgroup2_unified_mode()
&& cgroups::hierarchies::auto()
.root()
.join(&self.cpath)
.join("init")
.exists();
if is_dind {
"/init/"
} else {
"/"
pub fn subcgroup(&self, init_pid: pid_t, container_cgroup: &str) -> Result<String> {
if init_pid <= 0 || !cgroups::hierarchies::is_cgroup2_unified_mode() {
return Ok("/".into());
}
// get sub-cgroup from container init pid
let cgroup_info = fs::read_to_string(format!("/proc/{}/cgroup", init_pid))?;
for line in cgroup_info.lines() {
// the entry for cgroup v2 is always in the format "0::$PATH"
// see https://docs.kernel.org/admin-guide/cgroup-v2.html
if let Some((_, init_cgroup_path)) = line.split_once("0::") {
let container_cgroup_path = format!("/{}", container_cgroup);
debug!(
sl(),
"subcgroup info: init_pid {}, init_cgroup_path {}, container_cgroup_path {}",
init_pid,
init_cgroup_path,
container_cgroup_path
);
// get relative cgroup path of init_cgroup_path to container_cgroup_path
// container_cgroup_path: /a/b/c.slice
// init_cgroup_path: /a/b/c.slice/d.scope or /a/b/c.slice
if let Some((_, sub_path)) = init_cgroup_path.split_once(&container_cgroup_path) {
match sub_path {
"" => return Ok("/".into()),
_ => return Ok(sub_path.into()),
}
};
break;
}
}
Ok("/".into())
}
fn get_paths_and_mounts(

View File

@ -30,6 +30,10 @@ pub trait Manager {
Err(anyhow!("not supported!".to_string()))
}
fn set_init_pid(&mut self, _pid: i32) -> Result<()> {
Err(anyhow!("not supported!"))
}
fn get_pids(&self) -> Result<Vec<i32>> {
Err(anyhow!("not supported!"))
}

View File

@ -37,13 +37,15 @@ pub struct Manager {
fs_manager: FsManager,
// cgroup version for different dbus properties
cg_hierarchy: CgroupHierarchy,
// pid of first process in container
init_pid: pid_t,
}
impl CgroupManager for Manager {
fn apply(&self, pid: pid_t) -> Result<()> {
if self.dbus_client.unit_exists()? {
let subcgroup = self.fs_manager.subcgroup();
self.dbus_client.add_process(pid, subcgroup)?;
let subcgroup = self.fs_manager.subcgroup(self.init_pid, &self.cpath)?;
self.dbus_client.add_process(pid, subcgroup.as_str())?;
} else {
self.dbus_client.start_unit(
(pid as u32).try_into().unwrap(),
@ -55,6 +57,13 @@ impl CgroupManager for Manager {
Ok(())
}
fn set_init_pid(&mut self, pid: pid_t) -> Result<()> {
if self.init_pid == 0 {
self.init_pid = pid;
}
Ok(())
}
fn set(&self, r: &LinuxResources, _: bool) -> Result<()> {
let mut properties: Properties = vec![];
@ -130,6 +139,7 @@ impl Manager {
} else {
CgroupHierarchy::Legacy
},
init_pid: 0,
})
}
}

View File

@ -1216,7 +1216,7 @@ impl BaseContainer for LinuxContainer {
&logger,
spec,
&p,
self.cgroup_manager.as_ref(),
self.cgroup_manager.as_mut(),
self.config.use_systemd_cgroup,
&st,
&mut pipe_w,
@ -1517,7 +1517,7 @@ async fn join_namespaces(
logger: &Logger,
spec: &Spec,
p: &Process,
cm: &(dyn Manager + Send + Sync),
cm: &mut (dyn Manager + Send + Sync),
use_systemd_cgroup: bool,
st: &OCIState,
pipe_w: &mut PipeStream,
@ -1583,6 +1583,8 @@ async fn join_namespaces(
}
if p.init && res.is_some() {
info!(logger, "set init pid {} for {:p}", p.pid, cm);
cm.set_init_pid(p.pid)?;
info!(logger, "set properties to cgroups!");
cm.set(res.unwrap(), false)?;
}