summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/limits-util.c156
-rw-r--r--src/basic/limits-util.h10
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/util.c148
-rw-r--r--src/basic/util.h6
-rw-r--r--src/core/dbus-cgroup.c1
-rw-r--r--src/core/load-fragment.c1
-rw-r--r--src/core/main.c1
-rw-r--r--src/login/logind-core.c1
-rw-r--r--src/login/logind-user.c1
-rw-r--r--src/test/test-util.c1
-rw-r--r--src/udev/udevd.c1
12 files changed, 175 insertions, 154 deletions
diff --git a/src/basic/limits-util.c b/src/basic/limits-util.c
new file mode 100644
index 0000000000..0cd59f97ac
--- /dev/null
+++ b/src/basic/limits-util.c
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "alloc-util.h"
+#include "cgroup-util.h"
+#include "limits-util.h"
+#include "parse-util.h"
+#include "process-util.h"
+#include "procfs-util.h"
+#include "string-util.h"
+
+uint64_t physical_memory(void) {
+ _cleanup_free_ char *root = NULL, *value = NULL;
+ 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.
+ *
+ * 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;
+
+ 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;
+ }
+
+ 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 (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 */
+ lim /= ps;
+ lim *= ps;
+
+ return MIN(mem, lim);
+}
+
+uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
+ uint64_t p, m, ps, r;
+
+ assert(max > 0);
+
+ /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
+ * the result is a multiple of the page size (rounds down). */
+
+ ps = page_size();
+ assert(ps > 0);
+
+ p = physical_memory() / ps;
+ assert(p > 0);
+
+ m = p * v;
+ if (m / p != v)
+ return UINT64_MAX;
+
+ m /= max;
+
+ r = m * ps;
+ if (r / ps != m)
+ return UINT64_MAX;
+
+ return r;
+}
+
+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:
+ *
+ * a) the maximum tasks value the kernel allows on this architecture
+ * b) the cgroups pids_max attribute for the system
+ * c) the kernel's configured maximum PID value
+ *
+ * And then pick the smallest of the three */
+
+ r = procfs_tasks_get_limit(&a);
+ if (r < 0)
+ log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m");
+
+ 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;
+
+ 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,
+ a <= 0 ? TASKS_MAX : a,
+ b <= 0 ? TASKS_MAX : b);
+}
+
+uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
+ uint64_t t, m;
+
+ assert(max > 0);
+
+ /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
+ * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
+
+ t = system_tasks_max();
+ assert(t > 0);
+
+ m = t * v;
+ if (m / t != v) /* overflow? */
+ return UINT64_MAX;
+
+ return m / max;
+}
diff --git a/src/basic/limits-util.h b/src/basic/limits-util.h
new file mode 100644
index 0000000000..77895cbad4
--- /dev/null
+++ b/src/basic/limits-util.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <inttypes.h>
+
+uint64_t physical_memory(void);
+uint64_t physical_memory_scale(uint64_t v, uint64_t max);
+
+uint64_t system_tasks_max(void);
+uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
diff --git a/src/basic/meson.build b/src/basic/meson.build
index 4cfd3c861d..f7556b4198 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -79,6 +79,8 @@ basic_sources = files('''
khash.h
label.c
label.h
+ limits-util.c
+ limits-util.h
list.h
locale-util.c
locale-util.h
diff --git a/src/basic/util.c b/src/basic/util.c
index 6f68bc404e..b275570618 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -19,7 +19,6 @@
#include "alloc-util.h"
#include "btrfs-util.h"
#include "build.h"
-#include "cgroup-util.h"
#include "def.h"
#include "device-nodes.h"
#include "dirent-util.h"
@@ -294,153 +293,6 @@ int container_get_leader(const char *machine, pid_t *pid) {
return 0;
}
-uint64_t physical_memory(void) {
- _cleanup_free_ char *root = NULL, *value = NULL;
- 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.
- *
- * 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;
-
- 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;
- }
-
- 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 (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 */
- lim /= ps;
- lim *= ps;
-
- return MIN(mem, lim);
-}
-
-uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
- uint64_t p, m, ps, r;
-
- assert(max > 0);
-
- /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
- * the result is a multiple of the page size (rounds down). */
-
- ps = page_size();
- assert(ps > 0);
-
- p = physical_memory() / ps;
- assert(p > 0);
-
- m = p * v;
- if (m / p != v)
- return UINT64_MAX;
-
- m /= max;
-
- r = m * ps;
- if (r / ps != m)
- return UINT64_MAX;
-
- return r;
-}
-
-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:
- *
- * a) the maximum tasks value the kernel allows on this architecture
- * b) the cgroups pids_max attribute for the system
- * c) the kernel's configured maximum PID value
- *
- * And then pick the smallest of the three */
-
- r = procfs_tasks_get_limit(&a);
- if (r < 0)
- log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m");
-
- 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;
-
- 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,
- a <= 0 ? TASKS_MAX : a,
- b <= 0 ? TASKS_MAX : b);
-}
-
-uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
- uint64_t t, m;
-
- assert(max > 0);
-
- /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
- * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
-
- t = system_tasks_max();
- assert(t > 0);
-
- m = t * v;
- if (m / t != v) /* overflow? */
- return UINT64_MAX;
-
- return m / max;
-}
-
int version(void) {
puts("systemd " STRINGIFY(PROJECT_VERSION) " (" GIT_VERSION ")\n"
SYSTEMD_FEATURES);
diff --git a/src/basic/util.h b/src/basic/util.h
index 82851e910c..dd0f6e5cc8 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -237,12 +237,6 @@ static inline unsigned log2u_round_up(unsigned x) {
int container_get_leader(const char *machine, pid_t *pid);
-uint64_t physical_memory(void);
-uint64_t physical_memory_scale(uint64_t v, uint64_t max);
-
-uint64_t system_tasks_max(void);
-uint64_t system_tasks_max_scale(uint64_t v, uint64_t max);
-
int version(void);
int str_verscmp(const char *s1, const char *s2);
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index 7ab53a1c2a..4615aeaf66 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -13,6 +13,7 @@
#include "dbus-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "limits-util.h"
#include "path-util.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 084c61d982..805bdbca9b 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -36,6 +36,7 @@
#include "ioprio.h"
#include "ip-protocol-list.h"
#include "journal-util.h"
+#include "limits-util.h"
#include "load-fragment.h"
#include "log.h"
#include "missing.h"
diff --git a/src/core/main.c b/src/core/main.c
index 47a976ad0f..c0fa33bab4 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -47,6 +47,7 @@
#include "ima-setup.h"
#include "killall.h"
#include "kmod-setup.h"
+#include "limits-util.h"
#include "load-fragment.h"
#include "log.h"
#include "loopback-setup.h"
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index f3d8de4f14..2467da18ee 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -18,6 +18,7 @@
#include "conf-parser.h"
#include "device-util.h"
#include "fd-util.h"
+#include "limits-util.h"
#include "logind.h"
#include "parse-util.h"
#include "path-util.h"
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
index 2b327cbe19..045b6f0e17 100644
--- a/src/login/logind-user.c
+++ b/src/login/logind-user.c
@@ -19,6 +19,7 @@
#include "fs-util.h"
#include "hashmap.h"
#include "label.h"
+#include "limits-util.h"
#include "logind-user.h"
#include "mkdir.h"
#include "parse-util.h"
diff --git a/src/test/test-util.c b/src/test/test-util.c
index ffacd65669..056708650d 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -8,6 +8,7 @@
#include "def.h"
#include "fileio.h"
#include "fs-util.h"
+#include "limits-util.h"
#include "missing_syscall.h"
#include "parse-util.h"
#include "process-util.h"
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 0da82dca55..eab2b46250 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -46,6 +46,7 @@
#include "hashmap.h"
#include "io-util.h"
#include "libudev-device-internal.h"
+#include "limits-util.h"
#include "list.h"
#include "main-func.h"
#include "mkdir.h"