diff --git a/src/blkio.rs b/src/blkio.rs index 9e702b5..8363d13 100644 --- a/src/blkio.rs +++ b/src/blkio.rs @@ -430,10 +430,10 @@ impl<'a> From<&'a Subsystem> for &'a BlkIoController { impl BlkIoController { /// Constructs a new `BlkIoController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } diff --git a/src/cgroup.rs b/src/cgroup.rs index 1a67795..24f3cc1 100644 --- a/src/cgroup.rs +++ b/src/cgroup.rs @@ -9,6 +9,7 @@ use crate::error::ErrorKind::*; use crate::error::*; +use crate::hierarchies::V1; use crate::{CgroupPid, ControllIdentifier, Controller, Hierarchy, Resources, Subsystem}; use std::collections::HashMap; @@ -588,6 +589,33 @@ pub fn get_cgroups_relative_paths_by_pid(pid: u32) -> Result String { + if mount_root == "/" { + mount_root = String::from(""); + } + pidpath.trim_start_matches(&mount_root).to_string() +} + +pub fn existing_path(paths: HashMap) -> Result> { + let mount_roots_v1 = V1::new(); + let mut mount_roots_subsystems_map = HashMap::new(); + + for s in mount_roots_v1.subsystems().iter() { + let controller_name = s.controller_name(); + let path_from_cgroup = paths + .get(&controller_name) + .ok_or(Error::new(Common(format!( + "controller {} found in mountinfo, but not found in cgroup.", + controller_name + ))))?; + let path_from_mountinfo = s.to_controller().base().to_string_lossy().to_string(); + + let des_path = get_cgroup_destination(path_from_mountinfo, path_from_cgroup.to_owned()); + mount_roots_subsystems_map.insert(controller_name, des_path); + } + Ok(mount_roots_subsystems_map) +} + fn get_cgroups_relative_paths_by_path(path: String) -> Result> { let mut m = HashMap::new(); let content = diff --git a/src/cpu.rs b/src/cpu.rs index 34cdfe9..50a334d 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -59,7 +59,6 @@ impl ControllerInternal for CpuController { fn get_path(&self) -> &PathBuf { &self.path } - fn get_path_mut(&mut self) -> &mut PathBuf { &mut self.path } @@ -113,10 +112,10 @@ impl<'a> From<&'a Subsystem> for &'a CpuController { impl CpuController { /// Contructs a new `CpuController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } diff --git a/src/cpuacct.rs b/src/cpuacct.rs index 8c238be..ee6ba3e 100644 --- a/src/cpuacct.rs +++ b/src/cpuacct.rs @@ -100,10 +100,10 @@ impl<'a> From<&'a Subsystem> for &'a CpuAcctController { impl CpuAcctController { /// Contructs a new `CpuAcctController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } diff --git a/src/cpuset.rs b/src/cpuset.rs index de411b2..bcf0a99 100644 --- a/src/cpuset.rs +++ b/src/cpuset.rs @@ -254,10 +254,10 @@ fn parse_range(s: String) -> Result> { impl CpuSetController { /// Contructs a new `CpuSetController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } diff --git a/src/devices.rs b/src/devices.rs index 9a10772..23b7f58 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -204,10 +204,10 @@ impl<'a> From<&'a Subsystem> for &'a DevicesController { impl DevicesController { /// Constructs a new `DevicesController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } diff --git a/src/freezer.rs b/src/freezer.rs index 310af30..0b1bf6c 100644 --- a/src/freezer.rs +++ b/src/freezer.rs @@ -84,14 +84,13 @@ impl<'a> From<&'a Subsystem> for &'a FreezerController { impl FreezerController { /// Contructs a new `FreezerController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } - /// Freezes the processes in the control group. pub fn freeze(&self) -> Result<()> { let mut file_name = "freezer.state"; diff --git a/src/hierarchies.rs b/src/hierarchies.rs index db505e7..cd06112 100644 --- a/src/hierarchies.rs +++ b/src/hierarchies.rs @@ -37,6 +37,8 @@ use crate::cgroup::Cgroup; /// See `proc(5)` for format details. #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct Mountinfo { + /// Mount root directory of the file system. + pub mount_root: PathBuf, /// Mount pathname relative to the process's root. pub mount_point: PathBuf, /// Filesystem type (main type with optional sub-type). @@ -57,6 +59,7 @@ pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option { return None; } let mount_point = PathBuf::from(s0_values[4]); + let mount_root = PathBuf::from(s0_values[3]); let fs_type_values: Vec<_> = s1_values[0].trim().split('.').collect(); let fs_type = match fs_type_values.len() { 1 => (fs_type_values[0].to_string(), None), @@ -69,6 +72,7 @@ pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option { let super_opts: Vec = s1_values[2].trim().split(',').map(String::from).collect(); Some(Mountinfo { + mount_root, mount_point, fs_type, super_opts, @@ -123,47 +127,53 @@ impl Hierarchy for V1 { // The cgroup writeback feature requires cooperation between memcgs and blkcgs // To avoid exceptions, we should add_task for blkcg before memcg(push BlkIo before Mem) // For more Information: https://www.alibabacloud.com/help/doc-detail/155509.htm - if let Some(root) = self.get_mount_point(Controllers::BlkIo) { - subs.push(Subsystem::BlkIo(BlkIoController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::BlkIo) { + subs.push(Subsystem::BlkIo(BlkIoController::new(point, root, false))); } - if let Some(root) = self.get_mount_point(Controllers::Mem) { - subs.push(Subsystem::Mem(MemController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::Mem) { + subs.push(Subsystem::Mem(MemController::new(point, root, false))); } - if let Some(root) = self.get_mount_point(Controllers::Pids) { - subs.push(Subsystem::Pid(PidController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::Pids) { + subs.push(Subsystem::Pid(PidController::new(point, root, false))); } - if let Some(root) = self.get_mount_point(Controllers::CpuSet) { - subs.push(Subsystem::CpuSet(CpuSetController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::CpuSet) { + subs.push(Subsystem::CpuSet(CpuSetController::new(point, root, false))); } - if let Some(root) = self.get_mount_point(Controllers::CpuAcct) { - subs.push(Subsystem::CpuAcct(CpuAcctController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::CpuAcct) { + subs.push(Subsystem::CpuAcct(CpuAcctController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::Cpu) { - subs.push(Subsystem::Cpu(CpuController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::Cpu) { + subs.push(Subsystem::Cpu(CpuController::new(point, root, false))); } - if let Some(root) = self.get_mount_point(Controllers::Devices) { - subs.push(Subsystem::Devices(DevicesController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::Devices) { + subs.push(Subsystem::Devices(DevicesController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::Freezer) { - subs.push(Subsystem::Freezer(FreezerController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::Freezer) { + subs.push(Subsystem::Freezer(FreezerController::new( + point, root, false, + ))); } - if let Some(root) = self.get_mount_point(Controllers::NetCls) { - subs.push(Subsystem::NetCls(NetClsController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::NetCls) { + subs.push(Subsystem::NetCls(NetClsController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::PerfEvent) { - subs.push(Subsystem::PerfEvent(PerfEventController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::PerfEvent) { + subs.push(Subsystem::PerfEvent(PerfEventController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::NetPrio) { - subs.push(Subsystem::NetPrio(NetPrioController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::NetPrio) { + subs.push(Subsystem::NetPrio(NetPrioController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::HugeTlb) { - subs.push(Subsystem::HugeTlb(HugeTlbController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::HugeTlb) { + subs.push(Subsystem::HugeTlb(HugeTlbController::new( + point, root, false, + ))); } - if let Some(root) = self.get_mount_point(Controllers::Rdma) { - subs.push(Subsystem::Rdma(RdmaController::new(root))); + if let Some((point, root)) = self.get_mount_point(Controllers::Rdma) { + subs.push(Subsystem::Rdma(RdmaController::new(point, root))); } - if let Some(root) = self.get_mount_point(Controllers::Systemd) { - subs.push(Subsystem::Systemd(SystemdController::new(root, false))); + if let Some((point, root)) = self.get_mount_point(Controllers::Systemd) { + subs.push(Subsystem::Systemd(SystemdController::new( + point, root, false, + ))); } subs @@ -218,29 +228,51 @@ impl Hierarchy for V2 { for s in controller_list { match s { "cpu" => { - subs.push(Subsystem::Cpu(CpuController::new(self.root(), true))); + subs.push(Subsystem::Cpu(CpuController::new( + self.root(), + PathBuf::from(""), + true, + ))); } "io" => { - subs.push(Subsystem::BlkIo(BlkIoController::new(self.root(), true))); + subs.push(Subsystem::BlkIo(BlkIoController::new( + self.root(), + PathBuf::from(""), + true, + ))); } "cpuset" => { - subs.push(Subsystem::CpuSet(CpuSetController::new(self.root(), true))); + subs.push(Subsystem::CpuSet(CpuSetController::new( + self.root(), + PathBuf::from(""), + true, + ))); } "memory" => { - subs.push(Subsystem::Mem(MemController::new(self.root(), true))); + subs.push(Subsystem::Mem(MemController::new( + self.root(), + PathBuf::from(""), + true, + ))); } "pids" => { - subs.push(Subsystem::Pid(PidController::new(self.root(), true))); + subs.push(Subsystem::Pid(PidController::new( + self.root(), + PathBuf::from(""), + true, + ))); } "freezer" => { subs.push(Subsystem::Freezer(FreezerController::new( self.root(), + PathBuf::from(""), true, ))); } "hugetlb" => { subs.push(Subsystem::HugeTlb(HugeTlbController::new( self.root(), + PathBuf::from(""), true, ))); } @@ -275,10 +307,10 @@ impl V1 { } } - pub fn get_mount_point(&self, controller: Controllers) -> Option { + pub fn get_mount_point(&self, controller: Controllers) -> Option<(PathBuf, PathBuf)> { self.mountinfo.iter().find_map(|m| { if m.fs_type.0 == "cgroup" && m.super_opts.contains(&controller.to_string()) { - return Some(m.mount_point.clone()); + return Some((m.mount_point.to_owned(), m.mount_root.to_owned())); } None }) @@ -337,19 +369,19 @@ mod tests { fn test_parse_mount() { let mountinfo = vec![ ("29 26 0:26 / /sys/fs/cgroup/cpuset,cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,cpuset,cpu,cpuacct", - Mountinfo{mount_point: PathBuf::from("/sys/fs/cgroup/cpuset,cpu,cpuacct"), fs_type: ("cgroup".to_string(), None), super_opts: vec![ + Mountinfo{mount_root: PathBuf::from("/"), mount_point: PathBuf::from("/sys/fs/cgroup/cpuset,cpu,cpuacct"), fs_type: ("cgroup".to_string(), None), super_opts: vec![ "rw".to_string(), "cpuset".to_string(), "cpu".to_string(), "cpuacct".to_string(), ]}), ("121 1731 0:42 / /shm rw,nosuid,nodev,noexec,relatime shared:68 master:66 - tmpfs shm rw,size=65536k", - Mountinfo{mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), None), super_opts: vec![ + Mountinfo{mount_root: PathBuf::from("/"), mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), None), super_opts: vec![ "rw".to_string(), "size=65536k".to_string(), ]}), ("121 1731 0:42 / /shm rw,nosuid,nodev,noexec,relatime shared:68 master:66 - tmpfs.123 shm rw,size=65536k", - Mountinfo{mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), Some("123".to_string())), super_opts: vec![ + Mountinfo{mount_root: PathBuf::from("/"), mount_point: PathBuf::from("/shm"), fs_type: ("tmpfs".to_string(), Some("123".to_string())), super_opts: vec![ "rw".to_string(), "size=65536k".to_string(), ]}), diff --git a/src/hugetlb.rs b/src/hugetlb.rs index a174c66..d25d9de 100644 --- a/src/hugetlb.rs +++ b/src/hugetlb.rs @@ -88,11 +88,11 @@ impl<'a> From<&'a Subsystem> for &'a HugeTlbController { impl HugeTlbController { /// Constructs a new `HugeTlbController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { let sizes = get_hugepage_sizes(); Self { - base: root.clone(), - path: root, + base: root, + path: point, sizes, v2, } diff --git a/src/lib.rs b/src/lib.rs index 5754a47..48393da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -255,6 +255,9 @@ pub trait Controller { /// The file system path to the controller. fn path(&self) -> &Path; + /// Root path of the file system to the controller. + fn base(&self) -> &Path; + /// Apply a set of resources to the Controller, invoking its internal functions to pass the /// kernel the information. fn apply(&self, res: &Resources) -> Result<()>; @@ -307,6 +310,10 @@ where self.get_path() } + fn base(&self) -> &Path { + self.get_base() + } + /// Apply a set of resources to the Controller, invoking its internal functions to pass the /// kernel the information. fn apply(&self, res: &Resources) -> Result<()> { diff --git a/src/memory.rs b/src/memory.rs index abfae27..66323d1 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -540,10 +540,10 @@ impl ControllerInternal for MemController { impl MemController { /// Contructs a new `MemController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } diff --git a/src/net_cls.rs b/src/net_cls.rs index dc5797e..a98ab8c 100644 --- a/src/net_cls.rs +++ b/src/net_cls.rs @@ -76,10 +76,10 @@ impl<'a> From<&'a Subsystem> for &'a NetClsController { impl NetClsController { /// Constructs a new `NetClsController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } diff --git a/src/net_prio.rs b/src/net_prio.rs index bd7eca9..170633d 100644 --- a/src/net_prio.rs +++ b/src/net_prio.rs @@ -79,10 +79,10 @@ impl<'a> From<&'a Subsystem> for &'a NetPrioController { impl NetPrioController { /// Constructs a new `NetPrioController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } diff --git a/src/perf_event.rs b/src/perf_event.rs index f0e9240..002cff6 100644 --- a/src/perf_event.rs +++ b/src/perf_event.rs @@ -65,10 +65,10 @@ impl<'a> From<&'a Subsystem> for &'a PerfEventController { impl PerfEventController { /// Constructs a new `PerfEventController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } } diff --git a/src/pid.rs b/src/pid.rs index 9585486..f98f4db 100644 --- a/src/pid.rs +++ b/src/pid.rs @@ -92,10 +92,10 @@ impl<'a> From<&'a Subsystem> for &'a PidController { impl PidController { /// Constructors a new `PidController` instance, with `root` serving as the controller's root /// directory. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, v2, } } diff --git a/src/rdma.rs b/src/rdma.rs index c053c78..7796944 100644 --- a/src/rdma.rs +++ b/src/rdma.rs @@ -68,10 +68,10 @@ impl<'a> From<&'a Subsystem> for &'a RdmaController { impl RdmaController { /// Constructs a new `RdmaController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf) -> Self { + pub fn new(point: PathBuf, root: PathBuf) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, } } diff --git a/src/systemd.rs b/src/systemd.rs index c1b22d1..6002c1c 100644 --- a/src/systemd.rs +++ b/src/systemd.rs @@ -62,10 +62,10 @@ impl<'a> From<&'a Subsystem> for &'a SystemdController { impl SystemdController { /// Constructs a new `SystemdController` with `root` serving as the root of the control group. - pub fn new(root: PathBuf, v2: bool) -> Self { + pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self { Self { - base: root.clone(), - path: root, + base: root, + path: point, _v2: v2, } }