From: Lennart Poettering Date: Thu, 17 May 2018 02:27:58 +0000 (-0400) Subject: util: fix physical_memory() to work correctly on cgroupsv2 X-Git-Tag: v239~212^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd969ee6ef2bf7698c0800ccf872f5cb6e183613;p=thirdparty%2Fsystemd.git util: fix physical_memory() to work correctly on cgroupsv2 Let's look into the right cgroupsv2 attribute. Also, while we are at it, add debug logging for all error conditions we eat up silently otherwise. --- diff --git a/src/basic/util.c b/src/basic/util.c index aa4a3f3ed60..6f68b842315 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -405,6 +405,7 @@ uint64_t physical_memory(void) { uint64_t mem, lim; size_t ps; long sc; + int r; /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of * memory. @@ -418,13 +419,40 @@ uint64_t physical_memory(void) { ps = page_size(); mem = (uint64_t) sc * (uint64_t) ps; - if (cg_get_root_path(&root) < 0) + r = cg_get_root_path(&root); + if (r < 0) { + log_debug_errno(r, "Failed to determine root cgroup, ignoring cgroup memory limit: %m"); return mem; + } - if (cg_get_attribute("memory", root, "memory.limit_in_bytes", &value)) + r = cg_all_unified(); + if (r < 0) { + log_debug_errno(r, "Failed to determine root unified mode, ignoring cgroup memory limit: %m"); return mem; + } + if (r > 0) { + r = cg_get_attribute("memory", root, "memory.max", &value); + if (r < 0) { + log_debug_errno(r, "Failed to read memory.max cgroup attribute, ignoring cgroup memory limit: %m"); + return mem; + } - if (safe_atou64(value, &lim) < 0) + if (streq(value, "max")) + return mem; + } else { + r = cg_get_attribute("memory", root, "memory.limit_in_bytes", &value); + if (r < 0) { + log_debug_errno(r, "Failed to read memory.limit_in_bytes cgroup attribute, ignoring cgroup memory limit: %m"); + return mem; + } + } + + r = safe_atou64(value, &lim); + if (r < 0) { + log_debug_errno(r, "Failed to parse cgroup memory limit '%s', ignoring: %m", value); + return mem; + } + if (lim == UINT64_MAX) return mem; /* Make sure the limit is a multiple of our own page size */