]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include <sys/prctl.h>
32 #include <sys/statfs.h>
33 #include <sys/sysmacros.h>
34 #include <sys/types.h>
37 #include "alloc-util.h"
38 #include "btrfs-util.h"
40 #include "cgroup-util.h"
42 #include "device-nodes.h"
43 #include "dirent-util.h"
46 #include "format-util.h"
48 #include "hostname-util.h"
52 #include "parse-util.h"
53 #include "path-util.h"
54 #include "process-util.h"
56 #include "signal-util.h"
57 #include "stat-util.h"
58 #include "string-util.h"
60 #include "time-util.h"
61 #include "umask-util.h"
62 #include "user-util.h"
66 char **saved_argv
= NULL
;
67 static int saved_in_initrd
= -1;
69 size_t page_size(void) {
70 static thread_local
size_t pgsz
= 0;
73 if (_likely_(pgsz
> 0))
76 r
= sysconf(_SC_PAGESIZE
);
83 bool plymouth_running(void) {
84 return access("/run/plymouth/pid", F_OK
) >= 0;
87 bool display_is_local(const char *display
) {
96 int socket_from_display(const char *display
, char **path
) {
103 if (!display_is_local(display
))
106 k
= strspn(display
+1, "0123456789");
108 f
= new(char, STRLEN("/tmp/.X11-unix/X") + k
+ 1);
112 c
= stpcpy(f
, "/tmp/.X11-unix/X");
113 memcpy(c
, display
+1, k
);
121 int block_get_whole_disk(dev_t d
, dev_t
*ret
) {
122 char p
[SYS_BLOCK_PATH_MAX("/partition")];
123 _cleanup_free_
char *s
= NULL
;
129 /* If it has a queue this is good enough for us */
130 xsprintf_sys_block_path(p
, "/queue", d
);
131 if (access(p
, F_OK
) >= 0) {
136 /* If it is a partition find the originating device */
137 xsprintf_sys_block_path(p
, "/partition", d
);
138 if (access(p
, F_OK
) < 0)
141 /* Get parent dev_t */
142 xsprintf_sys_block_path(p
, "/../dev", d
);
143 r
= read_one_line_file(p
, &s
);
147 r
= sscanf(s
, "%u:%u", &m
, &n
);
151 /* Only return this if it is really good enough for us. */
152 xsprintf_sys_block_path(p
, "/queue", makedev(m
, n
));
153 if (access(p
, F_OK
) < 0)
156 *ret
= makedev(m
, n
);
160 bool kexec_loaded(void) {
161 _cleanup_free_
char *s
= NULL
;
163 if (read_one_line_file("/sys/kernel/kexec_loaded", &s
) < 0)
169 int prot_from_flags(int flags
) {
171 switch (flags
& O_ACCMODE
) {
180 return PROT_READ
|PROT_WRITE
;
187 int fork_agent(pid_t
*pid
, const int except
[], unsigned n_except
, const char *path
, ...) {
188 bool stdout_is_tty
, stderr_is_tty
;
198 /* Spawns a temporary TTY agent, making sure it goes away when
201 r
= safe_fork_full("(sd-agent)", except
, n_except
, FORK_RESET_SIGNALS
|FORK_DEATHSIG
|FORK_CLOSE_ALL_FDS
, &agent_pid
);
209 stdout_is_tty
= isatty(STDOUT_FILENO
);
210 stderr_is_tty
= isatty(STDERR_FILENO
);
212 if (!stdout_is_tty
|| !stderr_is_tty
) {
215 /* Detach from stdout/stderr. and reopen
216 * /dev/tty for them. This is important to
217 * ensure that when systemctl is started via
218 * popen() or a similar call that expects to
219 * read EOF we actually do generate EOF and
220 * not delay this indefinitely by because we
221 * keep an unused copy of stdin around. */
222 fd
= open("/dev/tty", O_WRONLY
);
224 log_error_errno(errno
, "Failed to open /dev/tty: %m");
228 if (!stdout_is_tty
&& dup2(fd
, STDOUT_FILENO
) < 0) {
229 log_error_errno(errno
, "Failed to dup2 /dev/tty: %m");
233 if (!stderr_is_tty
&& dup2(fd
, STDERR_FILENO
) < 0) {
234 log_error_errno(errno
, "Failed to dup2 /dev/tty: %m");
238 if (fd
> STDERR_FILENO
)
242 /* Count arguments */
244 for (n
= 0; va_arg(ap
, char*); n
++)
249 l
= alloca(sizeof(char *) * (n
+ 1));
251 /* Fill in arguments */
253 for (i
= 0; i
<= n
; i
++)
254 l
[i
] = va_arg(ap
, char*);
261 bool in_initrd(void) {
264 if (saved_in_initrd
>= 0)
265 return saved_in_initrd
;
267 /* We make two checks here:
269 * 1. the flag file /etc/initrd-release must exist
270 * 2. the root file system must be a memory file system
272 * The second check is extra paranoia, since misdetecting an
273 * initrd can have bad consequences due the initrd
274 * emptying when transititioning to the main systemd.
277 saved_in_initrd
= access("/etc/initrd-release", F_OK
) >= 0 &&
278 statfs("/", &s
) >= 0 &&
281 return saved_in_initrd
;
284 void in_initrd_force(bool value
) {
285 saved_in_initrd
= value
;
288 /* hey glibc, APIs with callbacks without a user pointer are so useless */
289 void *xbsearch_r(const void *key
, const void *base
, size_t nmemb
, size_t size
,
290 int (*compar
) (const void *, const void *, void *), void *arg
) {
299 p
= (const char *) base
+ idx
* size
;
300 comparison
= compar(key
, p
, arg
);
303 else if (comparison
> 0)
311 int on_ac_power(void) {
312 bool found_offline
= false, found_online
= false;
313 _cleanup_closedir_
DIR *d
= NULL
;
316 d
= opendir("/sys/class/power_supply");
318 return errno
== ENOENT
? true : -errno
;
320 FOREACH_DIRENT(de
, d
, return -errno
) {
321 _cleanup_close_
int fd
= -1, device
= -1;
325 device
= openat(dirfd(d
), de
->d_name
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
327 if (IN_SET(errno
, ENOENT
, ENOTDIR
))
333 fd
= openat(device
, "type", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
341 n
= read(fd
, contents
, sizeof(contents
));
345 if (n
!= 6 || memcmp(contents
, "Mains\n", 6))
349 fd
= openat(device
, "online", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
357 n
= read(fd
, contents
, sizeof(contents
));
361 if (n
!= 2 || contents
[1] != '\n')
364 if (contents
[0] == '1') {
367 } else if (contents
[0] == '0')
368 found_offline
= true;
373 return found_online
|| !found_offline
;
376 int container_get_leader(const char *machine
, pid_t
*pid
) {
377 _cleanup_free_
char *s
= NULL
, *class = NULL
;
385 if (!machine_name_is_valid(machine
))
388 p
= strjoina("/run/systemd/machines/", machine
);
389 r
= parse_env_file(p
, NEWLINE
, "LEADER", &s
, "CLASS", &class, NULL
);
397 if (!streq_ptr(class, "container"))
400 r
= parse_pid(s
, &leader
);
410 int namespace_open(pid_t pid
, int *pidns_fd
, int *mntns_fd
, int *netns_fd
, int *userns_fd
, int *root_fd
) {
411 _cleanup_close_
int pidnsfd
= -1, mntnsfd
= -1, netnsfd
= -1, usernsfd
= -1;
419 mntns
= procfs_file_alloca(pid
, "ns/mnt");
420 mntnsfd
= open(mntns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
428 pidns
= procfs_file_alloca(pid
, "ns/pid");
429 pidnsfd
= open(pidns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
437 netns
= procfs_file_alloca(pid
, "ns/net");
438 netnsfd
= open(netns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
446 userns
= procfs_file_alloca(pid
, "ns/user");
447 usernsfd
= open(userns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
448 if (usernsfd
< 0 && errno
!= ENOENT
)
455 root
= procfs_file_alloca(pid
, "root");
456 rfd
= open(root
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
|O_DIRECTORY
);
471 *userns_fd
= usernsfd
;
476 pidnsfd
= mntnsfd
= netnsfd
= usernsfd
= -1;
481 int namespace_enter(int pidns_fd
, int mntns_fd
, int netns_fd
, int userns_fd
, int root_fd
) {
482 if (userns_fd
>= 0) {
483 /* Can't setns to your own userns, since then you could
484 * escalate from non-root to root in your own namespace, so
485 * check if namespaces equal before attempting to enter. */
486 _cleanup_free_
char *userns_fd_path
= NULL
;
488 if (asprintf(&userns_fd_path
, "/proc/self/fd/%d", userns_fd
) < 0)
491 r
= files_same(userns_fd_path
, "/proc/self/ns/user", 0);
499 if (setns(pidns_fd
, CLONE_NEWPID
) < 0)
503 if (setns(mntns_fd
, CLONE_NEWNS
) < 0)
507 if (setns(netns_fd
, CLONE_NEWNET
) < 0)
511 if (setns(userns_fd
, CLONE_NEWUSER
) < 0)
515 if (fchdir(root_fd
) < 0)
522 return reset_uid_gid();
525 uint64_t physical_memory(void) {
526 _cleanup_free_
char *root
= NULL
, *value
= NULL
;
531 /* We return this as uint64_t in case we are running as 32bit process on a 64bit kernel with huge amounts of
534 * In order to support containers nicely that have a configured memory limit we'll take the minimum of the
535 * physically reported amount of memory and the limit configured for the root cgroup, if there is any. */
537 sc
= sysconf(_SC_PHYS_PAGES
);
541 mem
= (uint64_t) sc
* (uint64_t) ps
;
543 if (cg_get_root_path(&root
) < 0)
546 if (cg_get_attribute("memory", root
, "memory.limit_in_bytes", &value
))
549 if (safe_atou64(value
, &lim
) < 0)
552 /* Make sure the limit is a multiple of our own page size */
556 return MIN(mem
, lim
);
559 uint64_t physical_memory_scale(uint64_t v
, uint64_t max
) {
560 uint64_t p
, m
, ps
, r
;
564 /* Returns the physical memory size, multiplied by v divided by max. Returns UINT64_MAX on overflow. On success
565 * the result is a multiple of the page size (rounds down). */
570 p
= physical_memory() / ps
;
586 uint64_t system_tasks_max(void) {
588 #if SIZEOF_PID_T == 4
589 #define TASKS_MAX ((uint64_t) (INT32_MAX-1))
590 #elif SIZEOF_PID_T == 2
591 #define TASKS_MAX ((uint64_t) (INT16_MAX-1))
593 #error "Unknown pid_t size"
596 _cleanup_free_
char *value
= NULL
, *root
= NULL
;
597 uint64_t a
= TASKS_MAX
, b
= TASKS_MAX
;
599 /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this
602 * a) the maximum value for the pid_t type
603 * b) the cgroups pids_max attribute for the system
604 * c) the kernel's configure maximum PID value
606 * And then pick the smallest of the three */
608 if (read_one_line_file("/proc/sys/kernel/pid_max", &value
) >= 0)
609 (void) safe_atou64(value
, &a
);
611 if (cg_get_root_path(&root
) >= 0) {
612 value
= mfree(value
);
614 if (cg_get_attribute("pids", root
, "pids.max", &value
) >= 0)
615 (void) safe_atou64(value
, &b
);
618 return MIN3(TASKS_MAX
,
619 a
<= 0 ? TASKS_MAX
: a
,
620 b
<= 0 ? TASKS_MAX
: b
);
623 uint64_t system_tasks_max_scale(uint64_t v
, uint64_t max
) {
628 /* Multiply the system's task value by the fraction v/max. Hence, if max==100 this calculates percentages
629 * relative to the system's maximum number of tasks. Returns UINT64_MAX on overflow. */
631 t
= system_tasks_max();
635 if (m
/ t
!= v
) /* overflow? */
641 int update_reboot_parameter_and_warn(const char *param
) {
644 if (isempty(param
)) {
645 if (unlink("/run/systemd/reboot-param") < 0) {
649 return log_warning_errno(errno
, "Failed to unlink reboot parameter file: %m");
655 RUN_WITH_UMASK(0022) {
656 r
= write_string_file("/run/systemd/reboot-param", param
, WRITE_STRING_FILE_CREATE
);
658 return log_warning_errno(r
, "Failed to write reboot parameter file: %m");
665 puts(PACKAGE_STRING
"\n"
670 int get_block_device(const char *path
, dev_t
*dev
) {
677 /* Get's the block device directly backing a file system. If
678 * the block device is encrypted, returns the device mapper
681 if (lstat(path
, &st
))
684 if (major(st
.st_dev
) != 0) {
689 if (statfs(path
, &sfs
) < 0)
692 if (F_TYPE_EQUAL(sfs
.f_type
, BTRFS_SUPER_MAGIC
))
693 return btrfs_get_block_device(path
, dev
);
698 int get_block_device_harder(const char *path
, dev_t
*dev
) {
699 _cleanup_closedir_
DIR *d
= NULL
;
700 _cleanup_free_
char *t
= NULL
;
701 char p
[SYS_BLOCK_PATH_MAX("/slaves")];
702 struct dirent
*de
, *found
= NULL
;
711 /* Gets the backing block device for a file system, and
712 * handles LUKS encrypted file systems, looking for its
713 * immediate parent, if there is one. */
715 r
= get_block_device(path
, &dt
);
719 xsprintf_sys_block_path(p
, "/slaves", dt
);
728 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
730 if (dot_or_dot_dot(de
->d_name
))
733 if (!IN_SET(de
->d_type
, DT_LNK
, DT_UNKNOWN
))
737 _cleanup_free_
char *u
= NULL
, *v
= NULL
, *a
= NULL
, *b
= NULL
;
739 /* We found a device backed by multiple other devices. We don't really support automatic
740 * discovery on such setups, with the exception of dm-verity partitions. In this case there are
741 * two backing devices: the data partition and the hash partition. We are fine with such
742 * setups, however, only if both partitions are on the same physical device. Hence, let's
745 u
= strjoin(p
, "/", de
->d_name
, "/../dev");
749 v
= strjoin(p
, "/", found
->d_name
, "/../dev");
753 r
= read_one_line_file(u
, &a
);
755 log_debug_errno(r
, "Failed to read %s: %m", u
);
759 r
= read_one_line_file(v
, &b
);
761 log_debug_errno(r
, "Failed to read %s: %m", v
);
765 /* Check if the parent device is the same. If not, then the two backing devices are on
766 * different physical devices, and we don't support that. */
777 q
= strjoina(p
, "/", found
->d_name
, "/dev");
779 r
= read_one_line_file(q
, &t
);
785 if (sscanf(t
, "%u:%u", &maj
, &min
) != 2)
791 *dev
= makedev(maj
, min
);