get relative paths at new/load func default.

Signed-off-by: bin liu <bin@hyper.sh>
This commit is contained in:
bin liu
2020-09-07 17:50:02 +08:00
parent cd2c748a74
commit 5d51e50bec
2 changed files with 60 additions and 33 deletions

View File

@@ -1,6 +1,7 @@
//! This module handles cgroup operations. Start here!
use crate::error::*;
use crate::error::ErrorKind::*;
use crate::libc_rmdir;
@@ -37,7 +38,7 @@ impl<'b> Cgroup<'b> {
fn create(&self) {
if self.hier.v2() {
create_v2_cgroup(self.hier.root().clone(), &self.path);
}else{
} else {
for subsystem in &self.subsystems {
subsystem.to_controller().create();
}
@@ -55,9 +56,8 @@ impl<'b> Cgroup<'b> {
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn new<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P) -> Cgroup<'b> {
let cg = Cgroup::load(hier, path);
cg.create();
cg
let relative_paths = get_cgroups_relative_paths().unwrap();
Cgroup::new_with_relative_paths(hier, path, relative_paths)
}
/// Create a handle for a control group in the hierarchy `hier`, with name `path`.
@@ -68,30 +68,31 @@ impl<'b> Cgroup<'b> {
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn load<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P) -> Cgroup<'b> {
let path = path.as_ref();
let mut subsystems = hier.subsystems();
if path.as_os_str() != "" {
subsystems = subsystems
.into_iter()
.map(|x| x.enter(path))
.collect::<Vec<_>>();
}
let cg = Cgroup {
subsystems: subsystems,
hier: hier,
path: path.to_str().unwrap().to_string(),
};
cg
let relative_paths = get_cgroups_relative_paths().unwrap();
Cgroup::load_with_relative_paths(hier, path, relative_paths)
}
/// Create a new control group in the hierarchy `hier`, with name `path`.
/// and relative paths from `/proc/self/cgroup`
///
/// Returns a handle to the control group that can be used to manipulate it.
///
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn new_with_relative_paths<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P, relative_paths: HashMap<String, String>) -> Cgroup<'b> {
let cg = Cgroup::load_with_relative_paths(hier, path, relative_paths);
cg.create();
cg
}
/// Create a handle for a control group in the hierarchy `hier`, with name `path`,
/// and relative paths from `/proc/self/cgroup`
///
/// Returns a handle to the control group (that possibly does not exist until `create()` has
/// been called on the cgroup.
///
/// Note that if the handle goes out of scope and is dropped, the control group is _not_
/// destroyed.
pub fn load_with_relative_paths<P: AsRef<Path>>(hier: Box<&'b dyn Hierarchy>, path: P, relative_paths: HashMap<String, String>) -> Cgroup<'b> {
let path = path.as_ref();
let mut subsystems = hier.subsystems();
@@ -206,7 +207,7 @@ impl<'b> Cgroup<'b> {
if subsystems.len() > 0 {
let c = subsystems[0].to_controller();
c.add_task(&pid)
} else{
} else {
Ok(())
}
} else {
@@ -252,7 +253,6 @@ fn enable_controllers(controllers: &Vec<String>, path: &PathBuf) {
f.push("cgroup.subtree_control");
for c in controllers{
let body = format!("+{}", c);
// FIXME set mode to 0644
let _rest = fs::write(f.as_path(), body.as_bytes());
}
}
@@ -265,7 +265,7 @@ fn supported_controllers(p: &PathBuf) -> Vec<String>{
fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
// controler list ["memory", "cpu"]
let controllers = supported_controllers(&root);
let controllers = supported_controllers(&root);
let mut fp = root;
// enable for root
@@ -279,7 +279,6 @@ fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
fp.push(ele);
// create dir, need not check if is a file or directory
if !fp.exists(){
// FIXME set mode to 0755
match ::std::fs::create_dir(fp.clone()) {
Err(e) => return Err(Error::with_cause(ErrorKind::FsError, e)),
Ok(_) => {},
@@ -293,4 +292,27 @@ fn create_v2_cgroup(root: PathBuf, path: &str) -> Result<()> {
}
Ok(())
}
}
pub fn get_cgroups_relative_paths() -> Result<HashMap<String, String>> {
let mut m = HashMap::new();
let content = fs::read_to_string("/proc/self/cgroup").map_err(|e| Error::with_cause(ReadFailed, e))?;
for l in content.lines() {
let fl: Vec<&str> = l.split(':').collect();
if fl.len() != 3 {
continue;
}
let keys: Vec<&str> = fl[1].split(',').collect();
for key in &keys {
// this is a workaround, cgroup file are using `name=systemd`,
// but if file system the name is `systemd`
if *key == "name=systemd" {
m.insert("systemd".to_string(), fl[2].to_string());
} else {
m.insert(key.to_string(), fl[2].to_string());
}
}
}
Ok(m)
}

View File

@@ -39,22 +39,27 @@ fn test_cgroup_with_relative_paths() {
return
}
let h = cgroups::hierarchies::auto();
let cgroup_root = h.root();
let h = Box::new(&*h);
let mut relative_paths = HashMap::new();
relative_paths.insert("memory".to_string(), "/mmm/abc/def".to_string());
let cg = Cgroup::new_with_relative_paths(h, String::from("test_cgroup_with_prefix"), relative_paths);
let mem_relative_path = "/mmm/abc/def";
relative_paths.insert("memory".to_string(), mem_relative_path.to_string());
let cgroup_name = "test_cgroup_with_relative_paths";
let cg = Cgroup::new_with_relative_paths(h, String::from(cgroup_name), relative_paths);
{
let subsystems = cg.subsystems();
subsystems.into_iter().for_each(|sub| match sub {
Subsystem::Pid(c) => {
let p = c.path().to_str().unwrap();
let rel_path = p.trim_start_matches("/sys/fs/cgroup/pids");
assert_eq!(rel_path, "/test_cgroup_with_prefix")
let cgroup_path = c.path().to_str().unwrap();
let relative_path = "/pids/";
// cgroup_path = cgroup_root + relative_path + cgroup_name
assert_eq!(cgroup_path, format!("{}{}{}", cgroup_root.to_str().unwrap(), relative_path, cgroup_name));
},
Subsystem::Mem(c) => {
let p = c.path().to_str().unwrap();
let rel_path = p.trim_start_matches("/sys/fs/cgroup/memory");
assert_eq!(rel_path, "/mmm/abc/def/test_cgroup_with_prefix")
let cgroup_path = c.path().to_str().unwrap();
// cgroup_path = cgroup_root + relative_path + cgroup_name
assert_eq!(cgroup_path, format!("{}/memory{}/{}", cgroup_root.to_str().unwrap(), mem_relative_path, cgroup_name));
},
_ => {},
});