From eadbf5314052da685b95e53a9e0ded93e6fd55bc Mon Sep 17 00:00:00 2001 From: Ruini Xue Date: Fri, 14 Apr 2023 10:16:35 +0800 Subject: [PATCH] memory: Use default memory stats instead of panic. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 kata-containers#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 Signed-off-by: Ruini Xue Signed-off-by: Alex Man Signed-off-by: Fabiano FidĂȘncio --- src/memory.rs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/memory.rs b/src/memory.rs index 66323d1..831fc07 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -573,18 +573,33 @@ 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))?; + let m = SetMemory { + high: self + .get_max_value("memory.high") + .map_or(Some(MaxValue::default()), Some), + low: self + .get_max_value("memory.low") + .map_or(Some(MaxValue::Value(0)), Some), + max: self + .get_max_value("memory.max") + .map_or(Some(MaxValue::default()), Some), + min: self + .get_max_value("memory.min") + .map_or(Some(MaxValue::Value(0)), Some), + }; Ok(m) } fn memory_stat_v2(&self) -> Memory { - let set = self.get_mem().unwrap(); + // NOTE: get_mem() always returns T, but let's + // still do `unwrap_or` for safety. + let set = self.get_mem().unwrap_or(SetMemory { + low: Some(MaxValue::Value(0)), + high: Some(MaxValue::default()), + max: Some(MaxValue::default()), + min: Some(MaxValue::Value(0)), + }); Memory { fail_cnt: 0,