From 0c908cddf897670bd364874c55ad86063a3f82c8 Mon Sep 17 00:00:00 2001 From: Dov Murik Date: Mon, 27 Jun 2022 08:21:59 +0000 Subject: [PATCH] memory: set_kmem_limit: ignore Unsupported error Setting (writing into) `memory.kmem.limit_in_bytes` is not supported in Linux kernel >= 5.16 (see kernel commit 58056f77502: "memcg, kmem: further deprecate kmem.limit_in_bytes"): https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=58056f77502 If the write call in `set_kmem_limit()` returns EOPNOTSUPP, log a warning message but ignore the error (do nothing). Add a unit-test for `set_kmem_limit` in cgroups v1. Fix #81 Signed-off-by: Dov Murik --- src/memory.rs | 12 ++++++++++-- tests/builder.rs | 3 ++- tests/memory.rs | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index 7b02e1f..216af30 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -8,6 +8,7 @@ //! //! See the Kernel's documentation for more information about this subsystem, found at: //! [Documentation/cgroup-v1/memory.txt](https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt) +use log::warn; use std::collections::HashMap; use std::io::Write; use std::path::PathBuf; @@ -840,8 +841,15 @@ impl MemController { self.open_path("memory.kmem.limit_in_bytes", true) .and_then(|mut file| { - file.write_all(limit.to_string().as_ref()) - .map_err(|e| Error::with_cause(WriteFailed, e)) + let r = file.write_all(limit.to_string().as_ref()); + match r { + Ok(()) => Ok(()), + Err(ref e) if e.raw_os_error() == Some(libc::EOPNOTSUPP) => { + warn!("memory.kmem.limit_in_bytes is unsupported by the kernel"); + Ok(()) + } + Err(e) => Err(Error::with_cause(WriteFailed, e)), + } }) } diff --git a/tests/builder.rs b/tests/builder.rs index 0650806..e91d3c9 100644 --- a/tests/builder.rs +++ b/tests/builder.rs @@ -47,7 +47,8 @@ pub fn test_memory_res_build() { { let c: &MemController = cg.controller_of().unwrap(); if !c.v2() { - assert_eq!(c.kmem_stat().limit_in_bytes, 128 * 1024 * 1024); + // Note: we don't tests the value of c.kmem_stat().limit_in_bytes because on Linux + // kernel >= 5.16 setting this value is unsupported. assert_eq!(c.memory_stat().swappiness, 70); } assert_eq!(c.memory_stat().limit_in_bytes, 1024 * 1024 * 1024); diff --git a/tests/memory.rs b/tests/memory.rs index 6667ed4..2decc97 100644 --- a/tests/memory.rs +++ b/tests/memory.rs @@ -33,6 +33,21 @@ fn test_disable_oom_killer() { cg.delete().unwrap(); } +#[test] +fn set_kmem_limit_v1() { + let h = cgroups_rs::hierarchies::auto(); + if h.v2() { + return; + } + + let cg = Cgroup::new(h, String::from("set_kmem_limit_v1")); + { + let mem_controller: &MemController = cg.controller_of().unwrap(); + mem_controller.set_kmem_limit(1).unwrap(); + } + cg.delete().unwrap(); +} + #[test] fn set_mem_v2() { let h = cgroups_rs::hierarchies::auto();