Merge pull request #132 from aa624545345/collect-cgroup-path

Correct path of cgroup when running a container in a container
This commit is contained in:
Tim Zhang
2024-05-13 17:38:52 +08:00
committed by GitHub
17 changed files with 147 additions and 82 deletions

View File

@@ -430,10 +430,10 @@ impl<'a> From<&'a Subsystem> for &'a BlkIoController {
impl BlkIoController { impl BlkIoController {
/// Constructs a new `BlkIoController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }

View File

@@ -9,6 +9,7 @@
use crate::error::ErrorKind::*; use crate::error::ErrorKind::*;
use crate::error::*; use crate::error::*;
use crate::hierarchies::V1;
use crate::{CgroupPid, ControllIdentifier, Controller, Hierarchy, Resources, Subsystem}; use crate::{CgroupPid, ControllIdentifier, Controller, Hierarchy, Resources, Subsystem};
use std::collections::HashMap; use std::collections::HashMap;
@@ -588,6 +589,33 @@ pub fn get_cgroups_relative_paths_by_pid(pid: u32) -> Result<HashMap<String, Str
get_cgroups_relative_paths_by_path(path) get_cgroups_relative_paths_by_path(path)
} }
fn get_cgroup_destination(mut mount_root: String, pidpath: String) -> String {
if mount_root == "/" {
mount_root = String::from("");
}
pidpath.trim_start_matches(&mount_root).to_string()
}
pub fn existing_path(paths: HashMap<String, String>) -> Result<HashMap<String, String>> {
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<HashMap<String, String>> { fn get_cgroups_relative_paths_by_path(path: String) -> Result<HashMap<String, String>> {
let mut m = HashMap::new(); let mut m = HashMap::new();
let content = let content =

View File

@@ -59,7 +59,6 @@ impl ControllerInternal for CpuController {
fn get_path(&self) -> &PathBuf { fn get_path(&self) -> &PathBuf {
&self.path &self.path
} }
fn get_path_mut(&mut self) -> &mut PathBuf { fn get_path_mut(&mut self) -> &mut PathBuf {
&mut self.path &mut self.path
} }
@@ -113,10 +112,10 @@ impl<'a> From<&'a Subsystem> for &'a CpuController {
impl CpuController { impl CpuController {
/// Contructs a new `CpuController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }

View File

@@ -100,10 +100,10 @@ impl<'a> From<&'a Subsystem> for &'a CpuAcctController {
impl CpuAcctController { impl CpuAcctController {
/// Contructs a new `CpuAcctController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }

View File

@@ -254,10 +254,10 @@ fn parse_range(s: String) -> Result<Vec<(u64, u64)>> {
impl CpuSetController { impl CpuSetController {
/// Contructs a new `CpuSetController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }

View File

@@ -204,10 +204,10 @@ impl<'a> From<&'a Subsystem> for &'a DevicesController {
impl DevicesController { impl DevicesController {
/// Constructs a new `DevicesController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }

View File

@@ -84,14 +84,13 @@ impl<'a> From<&'a Subsystem> for &'a FreezerController {
impl FreezerController { impl FreezerController {
/// Contructs a new `FreezerController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }
/// Freezes the processes in the control group. /// Freezes the processes in the control group.
pub fn freeze(&self) -> Result<()> { pub fn freeze(&self) -> Result<()> {
let mut file_name = "freezer.state"; let mut file_name = "freezer.state";

View File

@@ -37,6 +37,8 @@ use crate::cgroup::Cgroup;
/// See `proc(5)` for format details. /// See `proc(5)` for format details.
#[derive(Debug, PartialEq, Eq, Hash, Clone)] #[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub struct Mountinfo { pub struct Mountinfo {
/// Mount root directory of the file system.
pub mount_root: PathBuf,
/// Mount pathname relative to the process's root. /// Mount pathname relative to the process's root.
pub mount_point: PathBuf, pub mount_point: PathBuf,
/// Filesystem type (main type with optional sub-type). /// Filesystem type (main type with optional sub-type).
@@ -57,6 +59,7 @@ pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option<Mountinfo> {
return None; return None;
} }
let mount_point = PathBuf::from(s0_values[4]); 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_values: Vec<_> = s1_values[0].trim().split('.').collect();
let fs_type = match fs_type_values.len() { let fs_type = match fs_type_values.len() {
1 => (fs_type_values[0].to_string(), None), 1 => (fs_type_values[0].to_string(), None),
@@ -69,6 +72,7 @@ pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option<Mountinfo> {
let super_opts: Vec<String> = s1_values[2].trim().split(',').map(String::from).collect(); let super_opts: Vec<String> = s1_values[2].trim().split(',').map(String::from).collect();
Some(Mountinfo { Some(Mountinfo {
mount_root,
mount_point, mount_point,
fs_type, fs_type,
super_opts, super_opts,
@@ -123,47 +127,53 @@ impl Hierarchy for V1 {
// The cgroup writeback feature requires cooperation between memcgs and blkcgs // 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) // 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 // For more Information: https://www.alibabacloud.com/help/doc-detail/155509.htm
if let Some(root) = self.get_mount_point(Controllers::BlkIo) { if let Some((point, root)) = self.get_mount_point(Controllers::BlkIo) {
subs.push(Subsystem::BlkIo(BlkIoController::new(root, false))); subs.push(Subsystem::BlkIo(BlkIoController::new(point, root, false)));
} }
if let Some(root) = self.get_mount_point(Controllers::Mem) { if let Some((point, root)) = self.get_mount_point(Controllers::Mem) {
subs.push(Subsystem::Mem(MemController::new(root, false))); subs.push(Subsystem::Mem(MemController::new(point, root, false)));
} }
if let Some(root) = self.get_mount_point(Controllers::Pids) { if let Some((point, root)) = self.get_mount_point(Controllers::Pids) {
subs.push(Subsystem::Pid(PidController::new(root, false))); subs.push(Subsystem::Pid(PidController::new(point, root, false)));
} }
if let Some(root) = self.get_mount_point(Controllers::CpuSet) { if let Some((point, root)) = self.get_mount_point(Controllers::CpuSet) {
subs.push(Subsystem::CpuSet(CpuSetController::new(root, false))); subs.push(Subsystem::CpuSet(CpuSetController::new(point, root, false)));
} }
if let Some(root) = self.get_mount_point(Controllers::CpuAcct) { if let Some((point, root)) = self.get_mount_point(Controllers::CpuAcct) {
subs.push(Subsystem::CpuAcct(CpuAcctController::new(root))); subs.push(Subsystem::CpuAcct(CpuAcctController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::Cpu) { if let Some((point, root)) = self.get_mount_point(Controllers::Cpu) {
subs.push(Subsystem::Cpu(CpuController::new(root, false))); subs.push(Subsystem::Cpu(CpuController::new(point, root, false)));
} }
if let Some(root) = self.get_mount_point(Controllers::Devices) { if let Some((point, root)) = self.get_mount_point(Controllers::Devices) {
subs.push(Subsystem::Devices(DevicesController::new(root))); subs.push(Subsystem::Devices(DevicesController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::Freezer) { if let Some((point, root)) = self.get_mount_point(Controllers::Freezer) {
subs.push(Subsystem::Freezer(FreezerController::new(root, false))); subs.push(Subsystem::Freezer(FreezerController::new(
point, root, false,
)));
} }
if let Some(root) = self.get_mount_point(Controllers::NetCls) { if let Some((point, root)) = self.get_mount_point(Controllers::NetCls) {
subs.push(Subsystem::NetCls(NetClsController::new(root))); subs.push(Subsystem::NetCls(NetClsController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::PerfEvent) { if let Some((point, root)) = self.get_mount_point(Controllers::PerfEvent) {
subs.push(Subsystem::PerfEvent(PerfEventController::new(root))); subs.push(Subsystem::PerfEvent(PerfEventController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::NetPrio) { if let Some((point, root)) = self.get_mount_point(Controllers::NetPrio) {
subs.push(Subsystem::NetPrio(NetPrioController::new(root))); subs.push(Subsystem::NetPrio(NetPrioController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::HugeTlb) { if let Some((point, root)) = self.get_mount_point(Controllers::HugeTlb) {
subs.push(Subsystem::HugeTlb(HugeTlbController::new(root, false))); subs.push(Subsystem::HugeTlb(HugeTlbController::new(
point, root, false,
)));
} }
if let Some(root) = self.get_mount_point(Controllers::Rdma) { if let Some((point, root)) = self.get_mount_point(Controllers::Rdma) {
subs.push(Subsystem::Rdma(RdmaController::new(root))); subs.push(Subsystem::Rdma(RdmaController::new(point, root)));
} }
if let Some(root) = self.get_mount_point(Controllers::Systemd) { if let Some((point, root)) = self.get_mount_point(Controllers::Systemd) {
subs.push(Subsystem::Systemd(SystemdController::new(root, false))); subs.push(Subsystem::Systemd(SystemdController::new(
point, root, false,
)));
} }
subs subs
@@ -218,29 +228,51 @@ impl Hierarchy for V2 {
for s in controller_list { for s in controller_list {
match s { match s {
"cpu" => { "cpu" => {
subs.push(Subsystem::Cpu(CpuController::new(self.root(), true))); subs.push(Subsystem::Cpu(CpuController::new(
self.root(),
PathBuf::from(""),
true,
)));
} }
"io" => { "io" => {
subs.push(Subsystem::BlkIo(BlkIoController::new(self.root(), true))); subs.push(Subsystem::BlkIo(BlkIoController::new(
self.root(),
PathBuf::from(""),
true,
)));
} }
"cpuset" => { "cpuset" => {
subs.push(Subsystem::CpuSet(CpuSetController::new(self.root(), true))); subs.push(Subsystem::CpuSet(CpuSetController::new(
self.root(),
PathBuf::from(""),
true,
)));
} }
"memory" => { "memory" => {
subs.push(Subsystem::Mem(MemController::new(self.root(), true))); subs.push(Subsystem::Mem(MemController::new(
self.root(),
PathBuf::from(""),
true,
)));
} }
"pids" => { "pids" => {
subs.push(Subsystem::Pid(PidController::new(self.root(), true))); subs.push(Subsystem::Pid(PidController::new(
self.root(),
PathBuf::from(""),
true,
)));
} }
"freezer" => { "freezer" => {
subs.push(Subsystem::Freezer(FreezerController::new( subs.push(Subsystem::Freezer(FreezerController::new(
self.root(), self.root(),
PathBuf::from(""),
true, true,
))); )));
} }
"hugetlb" => { "hugetlb" => {
subs.push(Subsystem::HugeTlb(HugeTlbController::new( subs.push(Subsystem::HugeTlb(HugeTlbController::new(
self.root(), self.root(),
PathBuf::from(""),
true, true,
))); )));
} }
@@ -275,10 +307,10 @@ impl V1 {
} }
} }
pub fn get_mount_point(&self, controller: Controllers) -> Option<PathBuf> { pub fn get_mount_point(&self, controller: Controllers) -> Option<(PathBuf, PathBuf)> {
self.mountinfo.iter().find_map(|m| { self.mountinfo.iter().find_map(|m| {
if m.fs_type.0 == "cgroup" && m.super_opts.contains(&controller.to_string()) { 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 None
}) })
@@ -337,19 +369,19 @@ mod tests {
fn test_parse_mount() { fn test_parse_mount() {
let mountinfo = vec![ 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", ("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(), "rw".to_string(),
"cpuset".to_string(), "cpuset".to_string(),
"cpu".to_string(), "cpu".to_string(),
"cpuacct".to_string(), "cpuacct".to_string(),
]}), ]}),
("121 1731 0:42 / /shm rw,nosuid,nodev,noexec,relatime shared:68 master:66 - tmpfs shm rw,size=65536k", ("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(), "rw".to_string(),
"size=65536k".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", ("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(), "rw".to_string(),
"size=65536k".to_string(), "size=65536k".to_string(),
]}), ]}),

View File

@@ -88,11 +88,11 @@ impl<'a> From<&'a Subsystem> for &'a HugeTlbController {
impl HugeTlbController { impl HugeTlbController {
/// Constructs a new `HugeTlbController` with `root` serving as the root of the control group. /// 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(); let sizes = get_hugepage_sizes();
Self { Self {
base: root.clone(), base: root,
path: root, path: point,
sizes, sizes,
v2, v2,
} }

View File

@@ -255,6 +255,9 @@ pub trait Controller {
/// The file system path to the controller. /// The file system path to the controller.
fn path(&self) -> &Path; 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 /// Apply a set of resources to the Controller, invoking its internal functions to pass the
/// kernel the information. /// kernel the information.
fn apply(&self, res: &Resources) -> Result<()>; fn apply(&self, res: &Resources) -> Result<()>;
@@ -307,6 +310,10 @@ where
self.get_path() 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 /// Apply a set of resources to the Controller, invoking its internal functions to pass the
/// kernel the information. /// kernel the information.
fn apply(&self, res: &Resources) -> Result<()> { fn apply(&self, res: &Resources) -> Result<()> {

View File

@@ -540,10 +540,10 @@ impl ControllerInternal for MemController {
impl MemController { impl MemController {
/// Contructs a new `MemController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }

View File

@@ -76,10 +76,10 @@ impl<'a> From<&'a Subsystem> for &'a NetClsController {
impl NetClsController { impl NetClsController {
/// Constructs a new `NetClsController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }

View File

@@ -79,10 +79,10 @@ impl<'a> From<&'a Subsystem> for &'a NetPrioController {
impl NetPrioController { impl NetPrioController {
/// Constructs a new `NetPrioController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }

View File

@@ -65,10 +65,10 @@ impl<'a> From<&'a Subsystem> for &'a PerfEventController {
impl PerfEventController { impl PerfEventController {
/// Constructs a new `PerfEventController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }
} }

View File

@@ -92,10 +92,10 @@ impl<'a> From<&'a Subsystem> for &'a PidController {
impl PidController { impl PidController {
/// Constructors a new `PidController` instance, with `root` serving as the controller's root /// Constructors a new `PidController` instance, with `root` serving as the controller's root
/// directory. /// directory.
pub fn new(root: PathBuf, v2: bool) -> Self { pub fn new(point: PathBuf, root: PathBuf, v2: bool) -> Self {
Self { Self {
base: root.clone(), base: root,
path: root, path: point,
v2, v2,
} }
} }

View File

@@ -68,10 +68,10 @@ impl<'a> From<&'a Subsystem> for &'a RdmaController {
impl RdmaController { impl RdmaController {
/// Constructs a new `RdmaController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
} }
} }

View File

@@ -62,10 +62,10 @@ impl<'a> From<&'a Subsystem> for &'a SystemdController {
impl SystemdController { impl SystemdController {
/// Constructs a new `SystemdController` with `root` serving as the root of the control group. /// 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 { Self {
base: root.clone(), base: root,
path: root, path: point,
_v2: v2, _v2: v2,
} }
} }