Skip to content

Commit

Permalink
Merge pull request #132 from aa624545345/collect-cgroup-path
Browse files Browse the repository at this point in the history
Correct path of cgroup when running a container in a container
  • Loading branch information
Tim-Zhang committed May 13, 2024
2 parents 69ef63a + 4005ad8 commit eb3e37a
Show file tree
Hide file tree
Showing 17 changed files with 147 additions and 82 deletions.
6 changes: 3 additions & 3 deletions src/blkio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down
28 changes: 28 additions & 0 deletions src/cgroup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}

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>> {
let mut m = HashMap::new();
let content =
Expand Down
7 changes: 3 additions & 4 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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,
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/cpuacct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/cpuset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,10 @@ fn parse_range(s: String) -> Result<Vec<(u64, u64)>> {

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,
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/freezer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
108 changes: 70 additions & 38 deletions src/hierarchies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand All @@ -57,6 +59,7 @@ pub(crate) fn parse_mountinfo_for_line(line: &str) -> Option<Mountinfo> {
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),
Expand All @@ -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();
Some(Mountinfo {
mount_root,
mount_point,
fs_type,
super_opts,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
)));
}
Expand Down Expand Up @@ -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| {
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
})
Expand Down Expand Up @@ -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(),
]}),
Expand Down
6 changes: 3 additions & 3 deletions src/hugetlb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<()>;
Expand Down Expand Up @@ -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<()> {
Expand Down
6 changes: 3 additions & 3 deletions src/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Expand Down
Loading

0 comments on commit eb3e37a

Please sign in to comment.