cpuset: fail if trying to enable memory pressure on a non-root cg

Signed-off-by: Levente Kurusa <lkurusa@acm.org>
This commit is contained in:
Levente Kurusa
2018-09-04 10:45:32 +02:00
parent 19e2847e15
commit be5db6ba50
3 changed files with 54 additions and 2 deletions

View File

@@ -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)

View File

@@ -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| {

19
tests/cpuset.rs Normal file
View File

@@ -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();
}