From 8ec5dbe237df72b522de4e4292122a8cabe3453e Mon Sep 17 00:00:00 2001 From: Martin Moessmer Date: Wed, 23 Sep 2020 12:49:07 +0200 Subject: [PATCH] Detect group mount points by parsing /proc/mounts --- Cargo.lock | 45 ++++++++++++++++++++++++++++++++++++++ north.toml | 4 ++-- north/Cargo.toml | 1 + north/src/linux/cgroups.rs | 19 ++++++++++++++-- north/src/settings.rs | 4 ++-- 5 files changed, 67 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e77495eee..5779ef872 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -643,6 +643,20 @@ dependencies = [ "termcolor", ] +[[package]] +name = "err-derive" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote 1.0.7", + "rustversion", + "syn", + "synstructure", +] + [[package]] name = "error-chain" version = "0.10.0" @@ -1133,6 +1147,7 @@ dependencies = [ "north_common", "pretty-bytes", "prettytable-rs", + "proc-mounts", "procinfo", "regex", "serde 1.0.114", @@ -1230,6 +1245,15 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c" +[[package]] +name = "partition-identity" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec13ba9a0eec5c10a89f6ec1b6e9e2ef7d29b810d771355abbd1c43cae003ed6" +dependencies = [ + "err-derive", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1372,6 +1396,16 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "proc-mounts" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad7e9c8d1b8c20f16a84d61d7c4c0325a5837c1307a2491b509cd92fb4e4442" +dependencies = [ + "lazy_static", + "partition-identity", +] + [[package]] name = "procinfo" version = "0.4.2" @@ -1532,6 +1566,17 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustversion" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9bdc5e856e51e685846fb6c13a1f5e5432946c2c90501bdc76a1319f19e29da" +dependencies = [ + "proc-macro2", + "quote 1.0.7", + "syn", +] + [[package]] name = "rustyline" version = "6.2.0" diff --git a/north.toml b/north.toml index 6b9cd79fa..473cd192a 100644 --- a/north.toml +++ b/north.toml @@ -7,8 +7,8 @@ data_dir = "target/north/data" key_dir = "target/north/keys" [cgroups] -memory = "/sys/fs/cgroup/memory/north" -cpu = "/sys/fs/cgroup/cpu/north" +memory = "north" +cpu = "north" [devices] unshare_root = "/" diff --git a/north/Cargo.toml b/north/Cargo.toml index b36a63a44..451773025 100644 --- a/north/Cargo.toml +++ b/north/Cargo.toml @@ -30,6 +30,7 @@ minijail = { path = "../minijail/minijail" } nix = "0.17.0" north_common = { path = "../north_common" } prettytable-rs = { version = "0.8.0", default-features = false } +proc-mounts = "0.2.4" regex = "1.3.9" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.56" diff --git a/north/src/linux/cgroups.rs b/north/src/linux/cgroups.rs index 2725978f2..087ddc032 100644 --- a/north/src/linux/cgroups.rs +++ b/north/src/linux/cgroups.rs @@ -24,6 +24,7 @@ use async_std::{ use futures::{future::FutureExt, select}; use log::{debug, warn}; use north_common::manifest; +use proc_mounts::MountIter; use std::time::Duration; const LIMIT_IN_BYTES: &str = "memory.limit_in_bytes"; @@ -76,7 +77,9 @@ impl CGroup for CGroupMem { impl CGroupMem { pub async fn new(name: &str, cgroup: &manifest::CGroupMem, tx: EventTx) -> Result { - let path = SETTINGS.cgroups.memory.join(name); + let mount_point = + get_mount_point("memory").context("Failed to detect cgroups memory mount point")?; + let path = mount_point.join(SETTINGS.cgroups.memory.join(name)); create(&path).await?; // Configure memory limit @@ -151,7 +154,9 @@ impl CGroup for CGroupCpu { impl CGroupCpu { pub async fn new(name: &str, cgroup: &manifest::CGroupCpu) -> Result { - let path = SETTINGS.cgroups.cpu.join(name); + let mount_point = + get_mount_point("cpu").context("Failed to detect cgroups cpu mount point")?; + let path = mount_point.join(SETTINGS.cgroups.cpu.join(name)); create(&path).await?; // Configure cpu shares @@ -247,3 +252,13 @@ async fn write(path: &Path, value: &str) -> Result<()> { .with_context(|| format!("Failed sync {}", path.display()))?; Ok(()) } + +fn get_mount_point(cgroup: &str) -> Result { + let cgroup = String::from(cgroup); + MountIter::new() + .context("Cannot access mount points")? + .filter_map(|m| m.ok()) + .find(|m| m.fstype == "cgroup" && m.options.contains(&cgroup)) + .map(|m| m.dest.into()) + .ok_or_else(|| anyhow!("No mount point for cgroup {}", &cgroup)) +} diff --git a/north/src/settings.rs b/north/src/settings.rs index 55b535f38..06e05afa7 100644 --- a/north/src/settings.rs +++ b/north/src/settings.rs @@ -183,13 +183,13 @@ struct CliOptions { #[structopt(long)] pub unshare_fstype: Option, - /// CGroups Memory dir. This can be a subdir of the root memory cgroup. + /// CGroups Memory dir. This is the subdir added to the root memory cgroup. /// The directory is created if it does not exist. /// This groups acts as the toplevel north memory cgroup. #[structopt(long)] pub cgroup_memory: Option, - /// CGroups CPU dir. This can be a subdir of the root memory cgroup. + /// CGroups CPU dir. This is the subdir added to the root cpu cgroup. /// The directory is created if it does not exist. /// This groups acts as the toplevel north cpu cgroup. #[structopt(long)]