Skip to content

Commit

Permalink
Merge pull request #33 from cpuguy83/fix_cg2_nesting
Browse files Browse the repository at this point in the history
cgroups: v2: Enable all controllers from parent
  • Loading branch information
cpuguy83 committed Dec 3, 2022
2 parents 398e385 + 4a5833f commit e266bbb
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
44 changes: 44 additions & 0 deletions crates/containerd-shim-wasm/src/sandbox/cgroups/cgroupv2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,51 @@ impl CgroupV2 {
fn get_file(&self, name: &str) -> Result<PathBuf> {
safe_join(self.base.clone(), self.path.join(name))
}

// Make sure the cgroup parents exist and that cgroup controllers are delegated from the parent cgroup.
fn ensure_parents(&self) -> Result<()> {
let mut full = safe_join(PathBuf::from("/"), self.base.clone())?;

for d in self.path.clone().iter() {
full = safe_join(full.clone(), PathBuf::from(d))?;

if full.exists() {
// This is a pre-existing cgroup, so we won't touch subtree control.
continue;
}

fs::create_dir_all(&full)?;

// For every enabled controller, add it to the subtree control so the child cgroup can use it.
let controllers = fs::read_to_string(full.join(CGROUP_CONTROLLERS))
.map_err(|e| {
Error::Others(format!(
"could not read cgroup.controllers at path {}: {}",
full.display(),
e
))
})?
.replace(" ", " +");

let c = "+".to_string() + &controllers.to_string();

fs::write(full.join(CGROUP_SUBTREE_CONTROL), &c).map_err(|e| {
Error::Others(format!(
"could not write cgroup.subtree_controll at path {}: controllers: {}: {}",
full.display(),
c,
e
))
})?;
}

Ok(())
}
}

mod files {
pub const CGROUP_CONTROLLERS: &str = "cgroup.controllers";
pub const CGROUP_SUBTREE_CONTROL: &str = "cgroup.subtree_control";
pub const CGROUP_PROCS: &str = "cgroup.procs";

pub const CPU_WEIGHT: &str = "cpu.weight";
Expand Down Expand Up @@ -84,6 +126,8 @@ impl Cgroup for CgroupV2 {
}
let res = res.unwrap();

self.ensure_parents()?;

if let Some(cpu) = res.cpu() {
if let Some(shares) = cpu.shares() {
let s = 1 + ((shares - 2) * 9999) / 262142;
Expand Down
32 changes: 32 additions & 0 deletions crates/containerd-shim-wasm/src/sandbox/cgroups/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ fn ensure_write_file(path: std::path::PathBuf, content: &str) -> Result<()> {
}
let mut file = fs::OpenOptions::new()
.write(true)
.create(true)
.open(&path)
.map_err(|e| {
Error::Others(format!(
Expand Down Expand Up @@ -249,6 +250,7 @@ fn find_cgroup_mounts<T: BufRead>(
#[cfg(test)]
mod tests {
use super::*;
use log::debug;
use oci_spec::runtime::Spec;
use serde_json as json;
use std::io::{Cursor, Write};
Expand Down Expand Up @@ -286,13 +288,35 @@ mod tests {
.map_err(|e| Error::Others(format!("failed to apply cgroup: {}", e)))
}

struct CgWrapper {
cg: Box<dyn Cgroup>,
}

impl CgWrapper {
fn new(p: &str) -> Self {
Self {
cg: p.try_into().unwrap(),
}
}
}

impl Drop for CgWrapper {
fn drop(&mut self) {
self.cg.delete().unwrap();
}
}

#[test]
fn test_cgroup() -> Result<()> {
if !super::super::exec::has_cap_sys_admin() {
println!("running test with sudo: {}", function!());
return run_test_with_sudo(function!());
}

let cg = new("containerd-wasm-shim-test_cgroup".to_string())?;

debug!("cgroup: {}", cg.version());

let res = cgroup_test(Box::new(&*cg));
if cg.version() == Version::V2 {
match cg.open() {
Expand All @@ -306,6 +330,10 @@ mod tests {
cg.delete()?;
res?;

// make sure each nesting is cleaned up at the end of the test
let _tmpcg1 = CgWrapper::new("relative");
let _tmpcg2 = CgWrapper::new("relative/nested");

let cg = new("relative/nested/containerd-wasm-shim-test_cgroup".to_string())?;
let res = cgroup_test(Box::new(&*cg));
if cg.version() == Version::V2 {
Expand All @@ -320,6 +348,10 @@ mod tests {
cg.delete()?;
res?;

// again, make sure each nesting is cleaned up at the end of the test
let _tmpcg3 = CgWrapper::new("/absolute");
let _tmpcg3 = CgWrapper::new("/absolute/nested");

let cg = new("/absolute/nested/containerd-wasm-shim-test_cgroup".to_string())?;
let res = cgroup_test(Box::new(&*cg));
if cg.version() == Version::V2 {
Expand Down

0 comments on commit e266bbb

Please sign in to comment.