diff --git a/src/cgroup.rs b/src/cgroup.rs index 9750344..a11d12e 100644 --- a/src/cgroup.rs +++ b/src/cgroup.rs @@ -36,14 +36,18 @@ pub struct Cgroup { /// The hierarchy. hier: Box, path: String, + + /// List of controllers specifically enabled in the control group. + specified_controllers: Option>, } impl Clone for Cgroup { fn clone(&self) -> Self { Cgroup { subsystems: self.subsystems.clone(), - path: self.path.clone(), hier: crate::hierarchies::auto(), + path: self.path.clone(), + specified_controllers: None, } } } @@ -54,48 +58,67 @@ impl Default for Cgroup { subsystems: Vec::new(), hier: crate::hierarchies::auto(), path: "".to_string(), + specified_controllers: None, } } } impl Cgroup { + pub fn v2(&self) -> bool { + self.hier.v2() + } + /// Create this control group. - fn create(&self) { + fn create(&self) -> Result<()> { if self.hier.v2() { - let _ret = create_v2_cgroup(self.hier.root(), &self.path); + create_v2_cgroup(self.hier.root(), &self.path, &self.specified_controllers) } else { for subsystem in &self.subsystems { subsystem.to_controller().create(); } + Ok(()) } } - pub fn v2(&self) -> bool { - self.hier.v2() + /// Create a new control group in the hierarchy `hier`, with name `path`. + /// + /// Returns a handle to the control group that can be used to manipulate it. + pub fn new>(hier: Box, path: P) -> Result { + let cg = Cgroup::load(hier, path); + cg.create()?; + Ok(cg) } /// Create a new control group in the hierarchy `hier`, with name `path`. /// /// Returns a handle to the control group that can be used to manipulate it. - pub fn new>(hier: Box, path: P) -> Cgroup { - let cg = Cgroup::load(hier, path); - cg.create(); - cg + pub fn new_with_specified_controllers>( + hier: Box, + path: P, + specified_controllers: Option>, + ) -> Result { + let cg = if let Some(sc) = specified_controllers { + Cgroup::load_with_specified_controllers(hier, path, sc) + } else { + Cgroup::load(hier, path) + }; + cg.create()?; + Ok(cg) } /// Create a new control group in the hierarchy `hier`, with name `path` and `relative_paths` /// /// Returns a handle to the control group that can be used to manipulate it. /// - /// Note that this method is only meaningful for cgroup v1, call it is equivalent to call `new` in the v2 mode + /// Note that this method is only meaningful for cgroup v1, call it is equivalent to call `new` in the v2 mode. pub fn new_with_relative_paths>( hier: Box, path: P, relative_paths: HashMap, - ) -> Cgroup { + ) -> Result { let cg = Cgroup::load_with_relative_paths(hier, path, relative_paths); - cg.create(); - cg + cg.create()?; + Ok(cg) } /// Create a handle for a control group in the hierarchy `hier`, with name `path`. @@ -116,6 +139,34 @@ impl Cgroup { path: path.to_str().unwrap().to_string(), subsystems, hier, + specified_controllers: None, + } + } + + /// Create a handle for a specified control group in the hierarchy `hier`, with name `path`. + /// + /// Returns a handle to the control group (that possibly does not exist until `create()` has + /// been called on the cgroup. + pub fn load_with_specified_controllers>( + hier: Box, + path: P, + specified_controllers: Vec, + ) -> Cgroup { + let path = path.as_ref(); + let mut subsystems = hier.subsystems(); + if path.as_os_str() != "" { + subsystems = subsystems + .into_iter() + .filter(|x| specified_controllers.contains(&x.controller_name())) + .map(|x| x.enter(path)) + .collect::>(); + } + + Cgroup { + path: path.to_str().unwrap().to_string(), + subsystems, + hier, + specified_controllers: Some(specified_controllers), } } @@ -159,6 +210,7 @@ impl Cgroup { subsystems, hier, path: path.to_str().unwrap().to_string(), + specified_controllers: None, } } @@ -233,36 +285,102 @@ impl Cgroup { None } + /// Removes tasks from the control group by thread group id. + /// + /// Note that this means that the task will be moved back to the root control group in the + /// hierarchy and any rules applied to that control group will _still_ apply to the proc. + pub fn remove_task_by_tgid(&self, tgid: CgroupPid) -> Result<()> { + self.hier.root_control_group().add_task_by_tgid(tgid) + } + /// Removes a task from the control group. /// /// Note that this means that the task will be moved back to the root control group in the /// hierarchy and any rules applied to that control group will _still_ apply to the task. - pub fn remove_task(&self, pid: CgroupPid) { - let _ = self.hier.root_control_group().add_task(pid); + pub fn remove_task(&self, tid: CgroupPid) -> Result<()> { + self.hier.root_control_group().add_task(tid) + } + + /// Moves tasks to the parent control group by thread group id. + pub fn move_task_to_parent_by_tgid(&self, tgid: CgroupPid) -> Result<()> { + self.hier + .parent_control_group(&self.path) + .add_task_by_tgid(tgid) + } + + /// Moves a task to the parent control group. + pub fn move_task_to_parent(&self, tid: CgroupPid) -> Result<()> { + self.hier.parent_control_group(&self.path).add_task(tid) + } + + /// Return a handle to the parent control group in the hierarchy. + pub fn parent_control_group(&self) -> Cgroup { + self.hier.parent_control_group(&self.path) } /// Attach a task to the control group. - pub fn add_task(&self, pid: CgroupPid) -> Result<()> { + pub fn add_task(&self, tid: CgroupPid) -> Result<()> { if self.v2() { let subsystems = self.subsystems(); if !subsystems.is_empty() { let c = subsystems[0].to_controller(); - c.add_task(&pid) + c.add_task(&tid) } else { - Ok(()) + Err(Error::new(SubsystemsEmpty)) } } else { self.subsystems() .iter() - .try_for_each(|sub| sub.to_controller().add_task(&pid)) + .try_for_each(|sub| sub.to_controller().add_task(&tid)) } } - /// Attach a task to the control group by thread group id. - pub fn add_task_by_tgid(&self, pid: CgroupPid) -> Result<()> { - self.subsystems() - .iter() - .try_for_each(|sub| sub.to_controller().add_task_by_tgid(&pid)) + /// Attach tasks to the control group by thread group id. + pub fn add_task_by_tgid(&self, tgid: CgroupPid) -> Result<()> { + if self.v2() { + let subsystems = self.subsystems(); + if !subsystems.is_empty() { + let c = subsystems[0].to_controller(); + c.add_task_by_tgid(&tgid) + } else { + Err(Error::new(SubsystemsEmpty)) + } + } else { + self.subsystems() + .iter() + .try_for_each(|sub| sub.to_controller().add_task_by_tgid(&tgid)) + } + } + + /// set cgroup.type + pub fn set_cgroup_type(&self, cgroup_type: &str) -> Result<()> { + if self.v2() { + let subsystems = self.subsystems(); + if !subsystems.is_empty() { + let c = subsystems[0].to_controller(); + c.set_cgroup_type(cgroup_type) + } else { + Err(Error::new(SubsystemsEmpty)) + } + } else { + Err(Error::new(CgroupVersion)) + } + } + + /// get cgroup.type + pub fn get_cgroup_type(&self) -> Result { + if self.v2() { + let subsystems = self.subsystems(); + if !subsystems.is_empty() { + let c = subsystems[0].to_controller(); + let cgroup_type = c.get_cgroup_type()?; + Ok(cgroup_type) + } else { + Err(Error::new(SubsystemsEmpty)) + } + } else { + Err(Error::new(CgroupVersion)) + } } /// Set notify_on_release to the control group. @@ -281,6 +399,33 @@ impl Cgroup { .try_for_each(|sub| sub.to_controller().set_release_agent(path)) } + /// Returns an Iterator that can be used to iterate over the procs that are currently in the + /// control group. + pub fn procs(&self) -> Vec { + // Collect the procs from all subsystems + let mut v = if self.v2() { + let subsystems = self.subsystems(); + if !subsystems.is_empty() { + let c = subsystems[0].to_controller(); + c.procs() + } else { + vec![] + } + } else { + self.subsystems() + .iter() + .map(|x| x.to_controller().procs()) + .fold(vec![], |mut acc, mut x| { + acc.append(&mut x); + acc + }) + }; + + v.sort(); + v.dedup(); + v + } + /// Returns an Iterator that can be used to iterate over the tasks that are currently in the /// control group. pub fn tasks(&self) -> Vec { @@ -328,9 +473,22 @@ fn supported_controllers() -> Vec { .collect::>() } -fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> { +fn create_v2_cgroup( + root: PathBuf, + path: &str, + specified_controllers: &Option>, +) -> Result<()> { // controler list ["memory", "cpu"] - let controllers = supported_controllers(); + let controllers = if let Some(s_controllers) = specified_controllers.clone() { + if verify_supported_controllers(s_controllers.as_ref()) { + s_controllers + } else { + return Err(Error::new(ErrorKind::SpecifiedControllers)); + } + } else { + supported_controllers() + }; + let mut fp = root; // enable for root @@ -358,6 +516,16 @@ fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> { Ok(()) } +pub fn verify_supported_controllers(controllers: &[String]) -> bool { + let sc = supported_controllers(); + for controller in controllers.iter() { + if !sc.contains(controller) { + return false; + } + } + true +} + pub fn get_cgroups_relative_paths() -> Result> { let path = "/proc/self/cgroup".to_string(); get_cgroups_relative_paths_by_path(path) diff --git a/src/cgroup_builder.rs b/src/cgroup_builder.rs index 09eca24..a453d04 100644 --- a/src/cgroup_builder.rs +++ b/src/cgroup_builder.rs @@ -57,11 +57,11 @@ //! .read(6, 1, 10) //! .write(11, 1, 100) //! .done() -//! .build(h); +//! .build(h).unwrap(); //! ``` use crate::{ - BlkIoDeviceResource, BlkIoDeviceThrottleResource, Cgroup, DeviceResource, Hierarchy, + BlkIoDeviceResource, BlkIoDeviceThrottleResource, Cgroup, DeviceResource, Error, Hierarchy, HugePageResource, MaxValue, NetworkPriority, Resources, }; @@ -80,6 +80,8 @@ pub struct CgroupBuilder { name: String, /// Internal, unsupported field: use the associated builders instead. resources: Resources, + /// List of controllers specifically enabled in the control group. + specified_controllers: Option>, } impl CgroupBuilder { @@ -90,6 +92,7 @@ impl CgroupBuilder { CgroupBuilder { name: name.to_owned(), resources: Resources::default(), + specified_controllers: None, } } @@ -134,10 +137,22 @@ impl CgroupBuilder { } /// Finalize the control group, consuming the builder and creating the control group. - pub fn build(self, hier: Box) -> Cgroup { - let cg = Cgroup::new(hier, self.name); - let _ret = cg.apply(&self.resources); - cg + pub fn build(self, hier: Box) -> Result { + if let Some(controllers) = self.specified_controllers { + let cg = Cgroup::new_with_specified_controllers(hier, self.name, Some(controllers))?; + cg.apply(&self.resources)?; + Ok(cg) + } else { + let cg = Cgroup::new(hier, self.name)?; + cg.apply(&self.resources)?; + Ok(cg) + } + } + + /// Specifically enable some controllers in the control group. + pub fn set_specified_controllers(mut self, specified_controllers: Vec) -> Self { + self.specified_controllers = Some(specified_controllers); + self } } diff --git a/src/error.rs b/src/error.rs index 95fe5f5..884db3a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -51,6 +51,18 @@ pub enum ErrorKind { #[error("invalid bytes size")] InvalidBytesSize, + /// The specified controller is not in the list of supported controllers. + #[error("specified controller is not in the list of supported controllers")] + SpecifiedControllers, + + /// Using method in wrong cgroup version. + #[error("using method in wrong cgroup version")] + CgroupVersion, + + /// Subsystems is empty. + #[error("subsystems is empty")] + SubsystemsEmpty, + /// An unknown error has occured. #[error("an unknown error")] Other, diff --git a/src/hierarchies.rs b/src/hierarchies.rs index 056f6ca..1306c28 100644 --- a/src/hierarchies.rs +++ b/src/hierarchies.rs @@ -12,7 +12,7 @@ use std::fs; use std::fs::File; use std::io::{BufRead, BufReader}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use crate::blkio::BlkIoController; use crate::cpu::CpuController; @@ -173,6 +173,12 @@ impl Hierarchy for V1 { Cgroup::load(auto(), "") } + fn parent_control_group(&self, path: &str) -> Cgroup { + let path = Path::new(path); + let parent_path = path.parent().unwrap().to_string_lossy().to_string(); + Cgroup::load(auto(), &parent_path) + } + fn root(&self) -> PathBuf { self.mountinfo .iter() @@ -249,6 +255,12 @@ impl Hierarchy for V2 { Cgroup::load(auto(), "") } + fn parent_control_group(&self, path: &str) -> Cgroup { + let path = Path::new(path); + let parent_path = path.parent().unwrap().to_string_lossy().to_string(); + Cgroup::load(auto(), &parent_path) + } + fn root(&self) -> PathBuf { PathBuf::from(self.root.clone()) } diff --git a/src/lib.rs b/src/lib.rs index 2889344..8e8103f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -280,9 +280,18 @@ pub trait Controller { /// Attach a task to this controller. fn add_task_by_tgid(&self, pid: &CgroupPid) -> Result<()>; + /// set cgroup type. + fn set_cgroup_type(&self, cgroup_type: &str) -> Result<()>; + + /// get cgroup type. + fn get_cgroup_type(&self) -> Result; + /// Get the list of tasks that this controller has. fn tasks(&self) -> Vec; + /// Get the list of procs that this controller has. + fn procs(&self) -> Vec; + fn v2(&self) -> bool; } @@ -317,6 +326,9 @@ where /// Set notify_on_release fn set_notify_on_release(&self, enable: bool) -> Result<()> { + if self.is_v2() { + return Err(Error::new(ErrorKind::CgroupVersion)); + } self.open_path("notify_on_release", true) .and_then(|mut file| { write!(file, "{}", enable as i32).map_err(|e| { @@ -330,6 +342,9 @@ where /// Set release_agent fn set_release_agent(&self, path: &str) -> Result<()> { + if self.is_v2() { + return Err(Error::new(ErrorKind::CgroupVersion)); + } self.open_path("release_agent", true).and_then(|mut file| { file.write_all(path.as_bytes()).map_err(|e| { Error::with_cause( @@ -373,7 +388,7 @@ where fn add_task(&self, pid: &CgroupPid) -> Result<()> { let mut file_name = "tasks"; if self.is_v2() { - file_name = "cgroup.procs"; + file_name = "cgroup.threads"; } self.open_path(file_name, true).and_then(|mut file| { file.write_all(pid.pid.to_string().as_ref()).map_err(|e| { @@ -387,23 +402,45 @@ where /// Attach a task to this controller by thread group id. fn add_task_by_tgid(&self, pid: &CgroupPid) -> Result<()> { - self.open_path("cgroup.procs", true).and_then(|mut file| { + let file_name = "cgroup.procs"; + self.open_path(file_name, true).and_then(|mut file| { file.write_all(pid.pid.to_string().as_ref()).map_err(|e| { Error::with_cause( - ErrorKind::WriteFailed("cgroup.procs".to_string(), pid.pid.to_string()), + ErrorKind::WriteFailed(file_name.to_string(), pid.pid.to_string()), e, ) }) }) } + /// Get the list of procs that this controller has. + fn procs(&self) -> Vec { + let file_name = "cgroup.procs"; + self.open_path(file_name, false) + .map(|file| { + let bf = BufReader::new(file); + let mut v = Vec::new(); + for line in bf.lines() { + match line { + Ok(line) => { + let n = line.trim().parse().unwrap_or(0u64); + v.push(n); + } + Err(_) => break, + } + } + v.into_iter().map(CgroupPid::from).collect() + }) + .unwrap_or_default() + } + /// Get the list of tasks that this controller has. fn tasks(&self) -> Vec { - let mut file = "tasks"; + let mut file_name = "tasks"; if self.is_v2() { - file = "cgroup.procs"; + file_name = "cgroup.threads"; } - self.open_path(file, false) + self.open_path(file_name, false) .map(|file| { let bf = BufReader::new(file); let mut v = Vec::new(); @@ -421,6 +458,40 @@ where .unwrap_or_default() } + /// set cgroup.type + fn set_cgroup_type(&self, cgroup_type: &str) -> Result<()> { + if !self.is_v2() { + return Err(Error::new(ErrorKind::CgroupVersion)); + } + let file_name = "cgroup.type"; + self.open_path(file_name, true).and_then(|mut file| { + file.write_all(cgroup_type.as_bytes()).map_err(|e| { + Error::with_cause( + ErrorKind::WriteFailed(file_name.to_string(), cgroup_type.to_string()), + e, + ) + }) + }) + } + + /// get cgroup.type + fn get_cgroup_type(&self) -> Result { + if !self.is_v2() { + return Err(Error::new(ErrorKind::CgroupVersion)); + } + let file_name = "cgroup.type"; + self.open_path(file_name, false).and_then(|mut file: File| { + let mut string = String::new(); + match file.read_to_string(&mut string) { + Ok(_) => Ok(string.trim().to_owned()), + Err(e) => Err(Error::with_cause( + ErrorKind::ReadFailed(file_name.to_string()), + e, + )), + } + }) + } + fn v2(&self) -> bool { self.is_v2() } @@ -468,6 +539,9 @@ pub trait Hierarchy: std::fmt::Debug + Send + Sync { /// Return a handle to the root control group in the hierarchy. fn root_control_group(&self) -> Cgroup; + /// Return a handle to the parent control group in the hierarchy. + fn parent_control_group(&self, path: &str) -> Cgroup; + fn v2(&self) -> bool; } diff --git a/tests/builder.rs b/tests/builder.rs index e91d3c9..afce133 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -22,7 +22,8 @@ pub fn test_cpu_res_build() { .cpu() .shares(85) .done() - .build(h); + .build(h) + .unwrap(); { let cpu: &CpuController = cg.controller_of().unwrap(); @@ -42,7 +43,8 @@ pub fn test_memory_res_build() { .swappiness(70) .memory_hard_limit(1024 * 1024 * 1024) .done() - .build(h); + .build(h) + .unwrap(); { let c: &MemController = cg.controller_of().unwrap(); @@ -64,7 +66,8 @@ pub fn test_pid_res_build() { .pid() .maximum_number_of_processes(MaxValue::Value(123)) .done() - .build(h); + .build(h) + .unwrap(); { let c: &PidController = cg.controller_of().unwrap(); @@ -83,7 +86,8 @@ pub fn test_devices_res_build() { .devices() .device(1, 6, DeviceType::Char, true, vec![DevicePermissions::Read]) .done() - .build(h); + .build(h) + .unwrap(); { let c: &DevicesController = cg.controller_of().unwrap(); @@ -113,7 +117,8 @@ pub fn test_network_res_build() { .network() .class_id(1337) .done() - .build(h); + .build(h) + .unwrap(); { let c: &NetClsController = cg.controller_of().unwrap(); @@ -134,7 +139,8 @@ pub fn test_hugepages_res_build() { .hugepages() .limit("2MB".to_string(), 4 * 2 * 1024 * 1024) .done() - .build(h); + .build(h) + .unwrap(); { let c: &HugeTlbController = cg.controller_of().unwrap(); @@ -152,7 +158,8 @@ pub fn test_blkio_res_build() { .blkio() .weight(100) .done() - .build(h); + .build(h) + .unwrap(); { let c: &BlkIoController = cg.controller_of().unwrap(); diff --git a/tests/cgroup.rs b/tests/cgroup.rs index 563168b..8de56b8 100644 --- a/tests/cgroup.rs +++ b/tests/cgroup.rs @@ -10,24 +10,24 @@ use cgroups_rs::Controller; use cgroups_rs::{Cgroup, CgroupPid, Subsystem}; #[test] -fn test_tasks_iterator() { +fn test_tasks_iterator_cgroup() { let h = cgroups_rs::hierarchies::auto(); let pid = libc::pid_t::from(nix::unistd::getpid()) as u64; - let cg = Cgroup::new(h, String::from("test_tasks_iterator")); + let cg = Cgroup::new(h, String::from("test_tasks_iterator_cgroup")).unwrap(); { // Add a task to the control group. - cg.add_task(CgroupPid::from(pid)).unwrap(); + cg.add_task_by_tgid(CgroupPid::from(pid)).unwrap(); use std::{thread, time}; thread::sleep(time::Duration::from_millis(100)); - let mut tasks = cg.tasks().into_iter(); + let mut tasks = cg.procs().into_iter(); // Verify that the task is indeed in the control group assert_eq!(tasks.next(), Some(CgroupPid::from(pid))); assert_eq!(tasks.next(), None); // Now, try removing it. - cg.remove_task(CgroupPid::from(pid)); + cg.remove_task_by_tgid(CgroupPid::from(pid)).unwrap(); tasks = cg.tasks().into_iter(); // Verify that it was indeed removed. @@ -83,7 +83,7 @@ fn test_cgroup_v2() { return; } let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_v2")); + let cg = Cgroup::new(h, String::from("test_v2")).unwrap(); let mem_controller: &MemController = cg.controller_of().unwrap(); let (mem, swp, rev) = (4 * 1024 * 1000, 2 * 1024 * 1000, 1024 * 1000); @@ -103,3 +103,49 @@ fn test_cgroup_v2() { cg.delete().unwrap(); } + +#[test] +fn test_tasks_iterator_cgroup_threaded_mode() { + if !cgroups_rs::hierarchies::is_cgroup2_unified_mode() { + return; + } + let h = cgroups_rs::hierarchies::auto(); + let pid = libc::pid_t::from(nix::unistd::getpid()) as u64; + let cg = Cgroup::new(h, String::from("test_tasks_iterator_cgroup_threaded_mode")).unwrap(); + let h = cgroups_rs::hierarchies::auto(); + let specified_controllers = vec![String::from("cpuset"), String::from("cpu")]; + let cg_threaded = Cgroup::new_with_specified_controllers( + h, + String::from("test_tasks_iterator_cgroup_threaded_mode/threaded"), + Some(specified_controllers), + ) + .unwrap(); + cg_threaded.set_cgroup_type("threaded").unwrap(); + { + // Add a task to the control group. + cg.add_task_by_tgid(CgroupPid::from(pid)).unwrap(); + + // Add a task to the sub control group. + cg_threaded.add_task(CgroupPid::from(pid)).unwrap(); + + use std::{thread, time}; + thread::sleep(time::Duration::from_millis(100)); + + let mut tasks = cg_threaded.tasks().into_iter(); + // Verify that the task is indeed in the xcontrol group + assert_eq!(tasks.next(), Some(CgroupPid::from(pid))); + assert_eq!(tasks.next(), None); + + // Now, try removing it. + cg_threaded + .move_task_to_parent(CgroupPid::from(pid)) + .unwrap(); + tasks = cg_threaded.tasks().into_iter(); + + // Verify that it was indeed removed. + assert_eq!(tasks.next(), None); + } + cg_threaded.delete().unwrap(); + cg.remove_task_by_tgid(CgroupPid::from(pid)).unwrap(); + cg.delete().unwrap(); +} diff --git a/tests/cpu.rs b/tests/cpu.rs index 959474e..2b6afb4 100644 --- a/tests/cpu.rs +++ b/tests/cpu.rs @@ -10,7 +10,7 @@ use cgroups_rs::Cgroup; #[test] fn test_cfs_quota_and_periods() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_cfs_quota_and_periods")); + let cg = Cgroup::new(h, String::from("test_cfs_quota_and_periods")).unwrap(); let cpu_controller: &CpuController = cg.controller_of().unwrap(); diff --git a/tests/cpuset.rs b/tests/cpuset.rs index 1f7b74d..cecfb63 100644 --- a/tests/cpuset.rs +++ b/tests/cpuset.rs @@ -13,7 +13,7 @@ use std::fs; #[test] fn test_cpuset_memory_pressure_root_cg() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_cpuset_memory_pressure_root_cg")); + let cg = Cgroup::new(h, String::from("test_cpuset_memory_pressure_root_cg")).unwrap(); { let cpuset: &CpuSetController = cg.controller_of().unwrap(); @@ -27,7 +27,7 @@ fn test_cpuset_memory_pressure_root_cg() { #[test] fn test_cpuset_set_cpus() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_cpuset_set_cpus")); + let cg = Cgroup::new(h, String::from("test_cpuset_set_cpus")).unwrap(); { let cpuset: &CpuSetController = cg.controller_of().unwrap(); @@ -64,7 +64,7 @@ fn test_cpuset_set_cpus() { #[test] fn test_cpuset_set_cpus_add_task() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_cpuset_set_cpus_add_task/sub-dir")); + let cg = Cgroup::new(h, String::from("test_cpuset_set_cpus_add_task/sub-dir")).unwrap(); let cpuset: &CpuSetController = cg.controller_of().unwrap(); let set = cpuset.cpuset(); @@ -77,13 +77,13 @@ fn test_cpuset_set_cpus_add_task() { // Add a task to the control group. let pid_i = libc::pid_t::from(nix::unistd::getpid()) as u64; - let _ = cg.add_task(CgroupPid::from(pid_i)); + let _ = cg.add_task_by_tgid(CgroupPid::from(pid_i)); let tasks = cg.tasks(); assert!(!tasks.is_empty()); println!("tasks after added: {:?}", tasks); // remove task - cg.remove_task(CgroupPid::from(pid_i)); + cg.remove_task_by_tgid(CgroupPid::from(pid_i)).unwrap(); let tasks = cg.tasks(); println!("tasks after deleted: {:?}", tasks); assert_eq!(0, tasks.len()); diff --git a/tests/devices.rs b/tests/devices.rs index 90c1bef..83bb309 100644 --- a/tests/devices.rs +++ b/tests/devices.rs @@ -17,7 +17,7 @@ fn test_devices_parsing() { } let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_devices_parsing")); + let cg = Cgroup::new(h, String::from("test_devices_parsing")).unwrap(); { let devices: &DevicesController = cg.controller_of().unwrap(); diff --git a/tests/hugetlb.rs b/tests/hugetlb.rs index 1def769..4319ee5 100644 --- a/tests/hugetlb.rs +++ b/tests/hugetlb.rs @@ -17,7 +17,7 @@ fn test_hugetlb_sizes() { } let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_hugetlb_sizes")); + let cg = Cgroup::new(h, String::from("test_hugetlb_sizes")).unwrap(); { let hugetlb_controller: &HugeTlbController = cg.controller_of().unwrap(); let _ = hugetlb_controller.get_sizes(); diff --git a/tests/memory.rs b/tests/memory.rs index 2decc97..14374cf 100644 --- a/tests/memory.rs +++ b/tests/memory.rs @@ -11,7 +11,7 @@ use cgroups_rs::{Cgroup, MaxValue}; #[test] fn test_disable_oom_killer() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_disable_oom_killer")); + let cg = Cgroup::new(h, String::from("test_disable_oom_killer")).unwrap(); { let mem_controller: &MemController = cg.controller_of().unwrap(); @@ -40,7 +40,7 @@ fn set_kmem_limit_v1() { return; } - let cg = Cgroup::new(h, String::from("set_kmem_limit_v1")); + let cg = Cgroup::new(h, String::from("set_kmem_limit_v1")).unwrap(); { let mem_controller: &MemController = cg.controller_of().unwrap(); mem_controller.set_kmem_limit(1).unwrap(); @@ -55,7 +55,7 @@ fn set_mem_v2() { return; } - let cg = Cgroup::new(h, String::from("set_mem_v2")); + let cg = Cgroup::new(h, String::from("set_mem_v2")).unwrap(); { let mem_controller: &MemController = cg.controller_of().unwrap(); diff --git a/tests/pids.rs b/tests/pids.rs index 27a2de7..c555ade 100644 --- a/tests/pids.rs +++ b/tests/pids.rs @@ -17,7 +17,7 @@ use libc::pid_t; #[test] fn create_and_delete_cgroup() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("create_and_delete_cgroup")); + let cg = Cgroup::new(h, String::from("create_and_delete_cgroup")).unwrap(); { let pidcontroller: &PidController = cg.controller_of().unwrap(); pidcontroller.set_pid_max(MaxValue::Value(1337)).unwrap(); @@ -31,7 +31,7 @@ fn create_and_delete_cgroup() { #[test] fn test_pids_current_is_zero() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_pids_current_is_zero")); + let cg = Cgroup::new(h, String::from("test_pids_current_is_zero")).unwrap(); { let pidcontroller: &PidController = cg.controller_of().unwrap(); let current = pidcontroller.get_pid_current(); @@ -43,7 +43,7 @@ fn test_pids_current_is_zero() { #[test] fn test_pids_events_is_zero() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_pids_events_is_zero")); + let cg = Cgroup::new(h, String::from("test_pids_events_is_zero")).unwrap(); { let pidcontroller: &PidController = cg.controller_of().unwrap(); let events = pidcontroller.get_pid_events(); @@ -56,7 +56,7 @@ fn test_pids_events_is_zero() { #[test] fn test_pid_events_is_not_zero() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("test_pid_events_is_not_zero")); + let cg = Cgroup::new(h, String::from("test_pid_events_is_not_zero")).unwrap(); { let pids: &PidController = cg.controller_of().unwrap(); let before = pids.get_pid_events(); @@ -65,7 +65,7 @@ fn test_pid_events_is_not_zero() { match unsafe { fork() } { Ok(ForkResult::Parent { child, .. }) => { // move the process into the control group - let _ = pids.add_task(&(pid_t::from(child) as u64).into()); + let _ = pids.add_task_by_tgid(&(pid_t::from(child) as u64).into()); println!("added task to cg: {:?}", child); diff --git a/tests/resources.rs b/tests/resources.rs index 801890a..d983cce 100644 --- a/tests/resources.rs +++ b/tests/resources.rs @@ -11,7 +11,7 @@ use cgroups_rs::{Cgroup, MaxValue, PidResources, Resources}; #[test] fn pid_resources() { let h = cgroups_rs::hierarchies::auto(); - let cg = Cgroup::new(h, String::from("pid_resources")); + let cg = Cgroup::new(h, String::from("pid_resources")).unwrap(); { let res = Resources { pid: PidResources {