diff --git a/src/cpuset.rs b/src/cpuset.rs index 2748680..c37c1b0 100644 --- a/src/cpuset.rs +++ b/src/cpuset.rs @@ -315,10 +315,12 @@ impl CpuSetController { /// Control whether the kernel should collect information to calculate memory pressure for /// control groups. /// - /// Note: This is a no-operation if the control group referred by `self` is not the root + /// Note: This will fail with `InvalidOperation` if the current congrol group is not the root /// control group. pub fn set_enable_memory_pressure(self: &Self, b: bool) -> Result<(), CgroupError> { - /* XXX: this file should only be present in the root cpuset cg */ + if !self.path_exists("cpuset.memory_pressure_enabled") { + return Err(CgroupError::InvalidOperation); + } self.open_path("cpuset.memory_pressure_enabled", true).and_then(|mut file| { if b { file.write_all(b"1").map_err(CgroupError::WriteError) diff --git a/src/lib.rs b/src/lib.rs index ff18bbc..b8eb231 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -88,6 +88,28 @@ pub enum CgroupError { InvalidPath, } +impl PartialEq for CgroupError { + fn eq(&self, other: &CgroupError) -> bool { + match self { + CgroupError::WriteError(_) => if let CgroupError::WriteError(_) = other { + return true; + } else { return false }, + CgroupError::ReadError(_) => if let CgroupError::ReadError(_) = other { + return true; + } else { return false }, + CgroupError::ParseError => if let CgroupError::ParseError = other { + return true; + } else { return false }, + CgroupError::InvalidOperation => if let CgroupError::InvalidOperation = other { + return true; + } else { return false }, + CgroupError::InvalidPath => if let CgroupError::InvalidPath = other { + return true; + } else { return false }, + } + } +} + #[doc(hidden)] #[derive(Eq, PartialEq, Debug)] pub enum Controllers { @@ -193,6 +215,15 @@ pub trait Controller { } } + #[doc(hidden)] + fn path_exists(self: &Self, p: &str) -> bool { + if !self.verify_path() { + return false; + } + + std::path::Path::new(p).exists() + } + /// Attach a task to this controller. fn add_task(self: &Self, pid: &CgroupPid) -> Result<(), CgroupError> { self.open_path("tasks", true).and_then(|mut file| { diff --git a/tests/cpuset.rs b/tests/cpuset.rs new file mode 100644 index 0000000..4595b2d --- /dev/null +++ b/tests/cpuset.rs @@ -0,0 +1,19 @@ +extern crate cgroups; + +use cgroups::{Cgroup, CgroupError}; +use cgroups::cpuset::CpuSetController; + +#[test] +fn test_cpuset_memory_pressure_root_cg() { + let hier = cgroups::hierarchies::V1::new(); + let cg = Cgroup::new(&hier, String::from("test_cpuset_memory_pressure_root_cg")); + { + let cpuset: &CpuSetController = cg.controller_of().unwrap(); + + // This is not a root control group, so it should fail via InvalidOperation. + let res = cpuset.set_enable_memory_pressure(true); + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), CgroupError::InvalidOperation); + } + cg.delete(); +}