diff --git a/src/cpuset.rs b/src/cpuset.rs index b7b679a..92e981d 100644 --- a/src/cpuset.rs +++ b/src/cpuset.rs @@ -2,6 +2,8 @@ //! //! See the Kernel's documentation for more information about this subsystem, found at: //! [Documentation/cgroup-v1/cpusets.txt](https://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt) + +use log::*; use std::fs::File; use std::io::{Read, Write}; use std::path::PathBuf; @@ -104,6 +106,69 @@ impl ControllerInternal for CpuSetController { Ok(()) } + + fn post_create(&self){ + let current = self.get_path(); + let parent = match current.parent() { + Some(p) => p, + None => return, + }; + + if current != self.get_base() { + match copy_from_parent(current.to_str().unwrap(), parent.to_str().unwrap()) { + Ok(_)=>(), + Err(err) => error!("error create_dir {:?}", err), + } + } + } +} + +/// copy_from_parent copy the cpuset.cpus and cpuset.mems from the parent +/// directory to the current directory if the file's contents are 0 +fn copy_from_parent(current: &str, parent: &str) -> Result<()> { + let cpus_str: &str = "cpuset.cpus"; + let mems_str: &str = "cpuset.mems"; + + let current_cpus_path = ::std::path::Path::new(current).join(cpus_str); + let current_mems_path = ::std::path::Path::new(current).join(mems_str); + let parent_cpus_path = ::std::path::Path::new(parent).join(cpus_str); + let parent_mems_path = ::std::path::Path::new(parent).join(mems_str); + + let current_cpus = match ::std::fs::read_to_string(current_cpus_path.to_str().unwrap()) { + Ok(cpus) => String::from(cpus.trim()), + Err(e) => return Err(Error::with_cause(ReadFailed, e)), + }; + + let current_mems = match ::std::fs::read_to_string(current_mems_path.to_str().unwrap()) { + Ok(mems) => String::from(mems.trim()), + Err(e) => return Err(Error::with_cause(ReadFailed, e)), + }; + + let parent_cpus = match ::std::fs::read_to_string(parent_cpus_path.to_str().unwrap()) { + Ok(cpus) => cpus, + Err(e) => return Err(Error::with_cause(ReadFailed, e)), + }; + + let parent_mems = match ::std::fs::read_to_string(parent_mems_path.to_str().unwrap()) { + Ok(mems) => mems, + Err(e) => return Err(Error::with_cause(ReadFailed, e)), + }; + + if current_cpus == "" { + match ::std::fs::write(current_cpus_path.to_str().unwrap(), parent_cpus.as_bytes()) { + Ok(_) => (), + Err(e) => return Err(Error::with_cause(WriteFailed, e)), + } + } + + if current_mems == "" { + match ::std::fs::write(current_mems_path.to_str().unwrap(), parent_mems.as_bytes()) { + Ok(_) => (), + Err(e) => return Err(Error::with_cause(WriteFailed, e)), + } + } + + Ok(()) } impl ControllIdentifier for CpuSetController { diff --git a/src/lib.rs b/src/lib.rs index e6ed645..c7b539b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -120,6 +120,11 @@ mod sealed { fn get_path_mut(&mut self) -> &mut PathBuf; fn get_base(&self) -> &PathBuf; + /// Hooks running after controller crated, if have + fn post_create(&self){ + } + + fn verify_path(&self) -> Result<()> { if self.get_path().starts_with(self.get_base()) { Ok(()) @@ -211,7 +216,7 @@ impl Controller for T where T: ControllerInternal { self.verify_path().expect("path should be valid"); match ::std::fs::create_dir(self.get_path()) { - Ok(_) => (), + Ok(_) => self.post_create(), Err(e) => warn!("error create_dir {:?}", e), } }