From bd969ee6ef2bf7698c0800ccf872f5cb6e183613 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 May 2018 22:27:58 -0400 Subject: [PATCH 1/3] 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. --- src/basic/util.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/basic/util.c b/src/basic/util.c index aa4a3f3ed6..6f68b84231 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 */ From 0f578ea2ea4b8af12f09c9ec49f9613b242f1e9b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 May 2018 22:32:15 -0400 Subject: [PATCH 2/3] util: add debug logging to system_tasks_max() We should always do debug logging when we eat up error conditions. Let's do so here too. --- src/basic/util.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/basic/util.c b/src/basic/util.c index 6f68b84231..68aaa21a8d 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -493,6 +493,7 @@ uint64_t system_tasks_max(void) { uint64_t a = TASKS_MAX, b = TASKS_MAX; _cleanup_free_ char *root = NULL; + int r; /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this * limit: @@ -503,13 +504,24 @@ uint64_t system_tasks_max(void) { * * And then pick the smallest of the three */ - (void) procfs_tasks_get_limit(&a); + r = procfs_tasks_get_limit(&a); + if (r < 0) + log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m"); - if (cg_get_root_path(&root) >= 0) { + r = cg_get_root_path(&root); + if (r < 0) + log_debug_errno(r, "Failed to determine cgroup root path, ignoring: %m"); + else { _cleanup_free_ char *value = NULL; - if (cg_get_attribute("pids", root, "pids.max", &value) >= 0) - (void) safe_atou64(value, &b); + r = cg_get_attribute("pids", root, "pids.max", &value); + if (r < 0) + log_debug_errno(r, "Failed to read pids.max attribute of cgroup root, ignoring: %m"); + else if (!streq(value, "max")) { + r = safe_atou64(value, &b); + if (r < 0) + log_debug_errno(r, "Failed to parse pids.max attribute of cgroup root, ignoring: %m"); + } } return MIN3(TASKS_MAX, From a7b46b7d724a6dea0e025e6e26bf50b74ab2284c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 16 May 2018 22:33:13 -0400 Subject: [PATCH 3/3] logind: let's change the type of the runtime directory size to uint64_t Externally it's an uint64_t anyway, and internally we most just initialize it to physical_memory() which returns uint64_t, hence there's exactly zero value in using it as size_t internally. Hence, let's fix that, and use uint64_t everywhere. --- src/login/logind-dbus.c | 2 +- src/login/logind-user.c | 2 +- src/login/logind.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 79a5be8af9..7d7db0d823 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2664,7 +2664,7 @@ const sd_bus_vtable manager_vtable[] = { SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0), SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0), SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimeDirectorySize", "t", bus_property_get_size, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("NCurrentInhibitors", "t", property_get_hashmap_size, offsetof(Manager, inhibitors), 0), SD_BUS_PROPERTY("SessionsMax", "t", NULL, offsetof(Manager, sessions_max), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/login/logind-user.c b/src/login/logind-user.c index f513555142..8d3af6948c 100644 --- a/src/login/logind-user.c +++ b/src/login/logind-user.c @@ -707,7 +707,7 @@ int config_parse_tmpfs_size( void *data, void *userdata) { - size_t *sz = data; + uint64_t *sz = data; int r; assert(filename); diff --git a/src/login/logind.h b/src/login/logind.h index bc6e696550..4a80a0977e 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -121,7 +121,7 @@ struct Manager { usec_t holdoff_timeout_usec; sd_event_source *lid_switch_ignore_event_source; - size_t runtime_dir_size; + uint64_t runtime_dir_size; uint64_t user_tasks_max; uint64_t sessions_max; uint64_t inhibitors_max;