From 0ecd74fd83dd1dffa9174717f91be5182ecda6ff Mon Sep 17 00:00:00 2001 From: Alex Man Date: Mon, 9 Sep 2024 17:10:50 -0700 Subject: [PATCH] Fix cgroup v2 memory stat related panics When containers are terminated, cgroup v2 memory metrics under /sys/fs/cgroup may disappear. Previously, kata-agent assumed these metrics always exist, leading to panics as reported in #138. This commit returns default value (0) when memory metric files are missing. This behaviour aligns with cgroup v1, which also defaults to 0 memory metric files are missing: - Memory.limit_in_bytes which maps to m.max https://github.com/kata-containers/cgroups-rs/blob/main/src/memory.rs#L635 - Memory.soft_limit_in_bytes which maps to m.low https://github.com/kata-containers/cgroups-rs/blob/main/src/memory.rs#L661 - MemSwap.fail_cnt: https://github.com/kata-containers/cgroups-rs/blob/main/src/memory.rs#L631 Submitting a new PR because #116 does not handle MemSwap.fail_cnt, which will also cause panic. --- src/memory.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index 66323d1..2614d9c 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -574,12 +574,18 @@ impl MemController { // for v2 pub fn get_mem(&self) -> Result { let mut m: SetMemory = Default::default(); - self.get_max_value("memory.high") - .map(|x| m.high = Some(x))?; - self.get_max_value("memory.low").map(|x| m.low = Some(x))?; - self.get_max_value("memory.max").map(|x| m.max = Some(x))?; - self.get_max_value("memory.min").map(|x| m.min = Some(x))?; - + m.high = self + .get_max_value("memory.high") + .map_or(Some(MaxValue::Value(0)), |x| Some(x)); + m.low = self + .get_max_value("memory.low") + .map_or(Some(MaxValue::Value(0)), |x| Some(x)); + m.max = self + .get_max_value("memory.max") + .map_or(Some(MaxValue::Value(0)), |x| Some(x)); + m.min = self + .get_max_value("memory.min") + .map_or(Some(MaxValue::Value(0)), |x| Some(x)); Ok(m) } @@ -730,7 +736,7 @@ impl MemController { .open_path("memory.swap.events", false) .and_then(flat_keyed_to_hashmap) .map(|x| *x.get("fail").unwrap_or(&0) as u64) - .unwrap(), + .unwrap_or(0), limit_in_bytes: self .open_path("memory.swap.max", false) .and_then(read_i64_from)