diff --git a/CHANGELOG.md b/CHANGELOG.md index d3dee91387de..7b6d867c7db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- [#4309](https://github.com/firecracker-microvm/firecracker/pull/4309): The + jailer's option `--parent-cgroup` will move the process to that cgroup if no + `cgroup` options are provided. - Simplified and clarified the removal policy of deprecated API elements to follow semantic versioning 2.0.0. For more information, please refer to [this GitHub discussion](https://github.com/firecracker-microvm/firecracker/discussions/4135). diff --git a/src/jailer/src/cgroup.rs b/src/jailer/src/cgroup.rs index 349bf0183ae8..ceefdecea40a 100644 --- a/src/jailer/src/cgroup.rs +++ b/src/jailer/src/cgroup.rs @@ -161,6 +161,16 @@ impl CgroupBuilder { } } } + + // Returns the path to the root of the hierarchy + pub fn get_v2_hierarchy_path(&mut self) -> Result<&PathBuf, JailerError> { + match self.hierarchies.entry("unified".to_string()) { + Occupied(entry) => Ok(entry.into_mut()), + Vacant(_entry) => Err(JailerError::CgroupHierarchyMissing( + "cgroupsv2 hierarchy missing".to_string(), + )), + } + } } #[derive(Debug)] diff --git a/src/jailer/src/env.rs b/src/jailer/src/env.rs index d7a6613075d8..ada4e2965197 100644 --- a/src/jailer/src/env.rs +++ b/src/jailer/src/env.rs @@ -233,11 +233,23 @@ impl Env { .parse::() .map_err(|_| JailerError::CgroupInvalidVersion(cgroup_ver.to_string()))?; - let mut cgroup_builder = None; + let cgroups_args: &[String] = arguments.multiple_values("cgroup").unwrap_or_default(); + + // If the --parent-cgroup exists, and we have no other cgroups, + // then the intent is to move the process to that cgroup. + // Only applies to cgroupsv2 since it's a unified hierarchy + if cgroups_args.len() == 0 && cgroup_ver == 2 { + let mut builder = CgroupBuilder::new(cgroup_ver)?; + let cg_parent = builder.get_v2_hierarchy_path()?.join(parent_cgroup); + let cg_parent_procs = cg_parent.join("cgroup.procs"); + if cg_parent.exists() { + fs::write(cg_parent_procs, std::process::id().to_string()); + } + } // cgroup format: .=,... if let Some(cgroups_args) = arguments.multiple_values("cgroup") { - let builder = cgroup_builder.get_or_insert(CgroupBuilder::new(cgroup_ver)?); + let mut builder = CgroupBuilder::new(cgroup_ver)?; for cg in cgroups_args { let aux: Vec<&str> = cg.split('=').collect(); if aux.len() != 2 || aux[1].is_empty() {