diff options
Diffstat (limited to 'src/basic/util.c')
-rw-r--r-- | src/basic/util.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/basic/util.c b/src/basic/util.c index f2f92fb3b7..88d58cd94a 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -36,6 +36,7 @@ #include "alloc-util.h" #include "build.h" +#include "cgroup-util.h" #include "def.h" #include "dirent-util.h" #include "fd-util.h" @@ -771,15 +772,37 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int } uint64_t physical_memory(void) { - long mem; + _cleanup_free_ char *root = NULL, *value = NULL; + uint64_t mem, lim; + size_t ps; + long sc; - /* We return this as uint64_t in case we are running as 32bit - * process on a 64bit kernel with huge amounts of memory */ + /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of + * memory. + * + * In order to support containers nicely that have a configured memory limit we'll take the minimum of the + * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */ + + sc = sysconf(_SC_PHYS_PAGES); + assert(sc > 0); + + ps = page_size(); + mem = (uint64_t) sc * (uint64_t) ps; + + if (cg_get_root_path(&root) < 0) + return mem; + + if (cg_get_attribute("memory", root, "memory.limit_in_bytes", &value)) + return mem; + + if (safe_atou64(value, &lim) < 0) + return mem; - mem = sysconf(_SC_PHYS_PAGES); - assert(mem > 0); + /* Make sure the limit is a multiple of our own page size */ + lim /= ps; + lim *= ps; - return (uint64_t) mem * (uint64_t) page_size(); + return MIN(mem, lim); } int update_reboot_parameter_and_warn(const char *param) { |