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 <dov.murik1@il.ibm.com>
This commit is contained in:
Dov Murik
2022-06-27 08:21:59 +00:00
parent 556dea62b9
commit 0c908cddf8
3 changed files with 27 additions and 3 deletions

View File

@@ -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)),
}
})
}

View File

@@ -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);

View File

@@ -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();