chiark / gitweb /
tree-wide: drop 'This file is part of systemd' blurb
[elogind.git] / src / basic / util.c
index f60f60b02cbc4c71e46349a20aff009d2884bfcf..8bd0bff75a5095a603a3b9ebf79c9b07977cb189 100644 (file)
@@ -1,21 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 /***
-  This file is part of systemd.
-
   Copyright 2010 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
 #include <alloca.h>
@@ -52,6 +37,7 @@
 #include "parse-util.h"
 //#include "path-util.h"
 #include "process-util.h"
+#include "procfs-util.h"
 #include "set.h"
 #include "signal-util.h"
 #include "stat-util.h"
@@ -173,11 +159,11 @@ bool in_initrd(void) {
         return saved_in_initrd;
 }
 
+#if 0 /// UNNEEDED by elogind
 void in_initrd_force(bool value) {
         saved_in_initrd = value;
 }
 
-#if 0 /// UNNEEDED by elogind
 /* hey glibc, APIs with callbacks without a user pointer are so useless */
 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
                  int (*compar) (const void *, const void *, void *), void *arg) {
@@ -185,11 +171,13 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
         const void *p;
         int comparison;
 
+        assert(!size_multiply_overflow(nmemb, size));
+
         l = 0;
         u = nmemb;
         while (l < u) {
                 idx = (l + u) / 2;
-                p = (const char *) base + idx * size;
+                p = (const uint8_t*) base + idx * size;
                 comparison = compar(key, p, arg);
                 if (comparison < 0)
                         u = idx;
@@ -200,6 +188,7 @@ void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
         }
         return NULL;
 }
+#endif // 0
 
 int on_ac_power(void) {
         bool found_offline = false, found_online = false;
@@ -266,7 +255,6 @@ int on_ac_power(void) {
         return found_online || !found_offline;
 }
 
-#endif // 0
 int container_get_leader(const char *machine, pid_t *pid) {
         _cleanup_free_ char *s = NULL, *class = NULL;
         const char *p;
@@ -280,7 +268,7 @@ int container_get_leader(const char *machine, pid_t *pid) {
                 return -EINVAL;
 
         p = strjoina("/run/systemd/machines/", machine);
-        r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
+        r = parse_env_file(NULL, p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
         if (r == -ENOENT)
                 return -EHOSTDOWN;
         if (r < 0)
@@ -421,6 +409,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.
@@ -434,13 +423,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 (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;
+                }
+        }
 
-        if (safe_atou64(value, &lim) < 0)
+        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 */
@@ -479,34 +495,37 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) {
 
 uint64_t system_tasks_max(void) {
 
-#if SIZEOF_PID_T == 4
-#define TASKS_MAX ((uint64_t) (INT32_MAX-1))
-#elif SIZEOF_PID_T == 2
-#define TASKS_MAX ((uint64_t) (INT16_MAX-1))
-#else
-#error "Unknown pid_t size"
-#endif
-
-        _cleanup_free_ char *value = NULL, *root = NULL;
         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 value for the pid_t type
+         * a) the maximum tasks value the kernel allows on this architecture
          * b) the cgroups pids_max attribute for the system
-         * c) the kernel's configure maximum PID value
+         * c) the kernel's configured maximum PID value
          *
          * And then pick the smallest of the three */
 
-        if (read_one_line_file("/proc/sys/kernel/pid_max", &value) >= 0)
-                (void) safe_atou64(value, &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) {
-                value = mfree(value);
+        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,
@@ -532,31 +551,6 @@ uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) {
         return m / max;
 }
 
-#if 0 /// UNNEEDED by elogind
-int update_reboot_parameter_and_warn(const char *param) {
-        int r;
-
-        if (isempty(param)) {
-                if (unlink("/run/systemd/reboot-param") < 0) {
-                        if (errno == ENOENT)
-                                return 0;
-
-                        return log_warning_errno(errno, "Failed to unlink reboot parameter file: %m");
-                }
-
-                return 0;
-        }
-
-        RUN_WITH_UMASK(0022) {
-                r = write_string_file("/run/systemd/reboot-param", param, WRITE_STRING_FILE_CREATE);
-                if (r < 0)
-                        return log_warning_errno(r, "Failed to write reboot parameter file: %m");
-        }
-
-        return 0;
-}
-#endif // 0
-
 int version(void) {
         puts(PACKAGE_STRING "\n"
              SYSTEMD_FEATURES);
@@ -564,7 +558,6 @@ int version(void) {
 }
 
 #if 0 /// UNNEEDED by elogind
-#endif // 0
 /* This is a direct translation of str_verscmp from boot.c */
 static bool is_digit(int c) {
         return c >= '0' && c <= '9';
@@ -628,7 +621,14 @@ int str_verscmp(const char *s1, const char *s2) {
 }
 
 /* Turn off core dumps but only if we're running outside of a container. */
-void disable_core_dumps(void) {
-        if (detect_container() <= 0)
-                (void) write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+void disable_coredumps(void) {
+        int r;
+
+        if (detect_container() > 0)
+                return;
+
+        r = write_string_file("/proc/sys/kernel/core_pattern", "|/bin/false", 0);
+        if (r < 0)
+                log_debug_errno(r, "Failed to turn off coredumps, ignoring: %m");
 }
+#endif // 0