1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 #include <linux/magic.h>
31 #include <linux/oom.h>
32 #include <linux/sched.h>
43 #include <sys/ioctl.h>
45 #include <sys/mount.h>
46 #include <sys/personality.h>
47 #include <sys/prctl.h>
49 #include <sys/statvfs.h>
51 #include <sys/types.h>
52 #include <sys/utsname.h>
58 /* When we include libgen.h because we need dirname() we immediately
59 * undefine basename() since libgen.h defines it as a macro to the
60 * POSIX version which is really broken. We prefer GNU basename(). */
64 #ifdef HAVE_SYS_AUXV_H
68 /* We include linux/fs.h as last of the system headers, as it
69 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
72 #include "alloc-util.h"
75 //#include "device-nodes.h"
76 #include "dirent-util.h"
77 //#include "env-util.h"
79 //#include "exit-status.h"
82 #include "formats-util.h"
85 #include "hexdecoct.h"
86 #include "hostname-util.h"
92 #include "parse-util.h"
93 #include "path-util.h"
94 #include "process-util.h"
95 #include "random-util.h"
96 #include "signal-util.h"
98 #include "sparse-endian.h"
99 #include "stat-util.h"
100 #include "string-table.h"
101 #include "string-util.h"
103 #include "terminal-util.h"
104 #include "user-util.h"
109 /* Put this test here for a lack of better place */
110 assert_cc(EAGAIN == EWOULDBLOCK);
113 char **saved_argv = NULL;
115 size_t page_size(void) {
116 static thread_local size_t pgsz = 0;
119 if (_likely_(pgsz > 0))
122 r = sysconf(_SC_PAGESIZE);
129 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
130 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
131 _cleanup_set_free_free_ Set *seen = NULL;
134 /* We fork this all off from a child process so that we can
135 * somewhat cleanly make use of SIGALRM to set a time limit */
137 (void) reset_all_signal_handlers();
138 (void) reset_signal_mask();
140 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
142 pids = hashmap_new(NULL);
146 seen = set_new(&string_hash_ops);
150 STRV_FOREACH(directory, directories) {
151 _cleanup_closedir_ DIR *d;
154 d = opendir(*directory);
159 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
162 FOREACH_DIRENT(de, d, break) {
163 _cleanup_free_ char *path = NULL;
167 if (!dirent_is_file(de))
170 if (set_contains(seen, de->d_name)) {
171 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
175 r = set_put_strdup(seen, de->d_name);
179 path = strjoin(*directory, "/", de->d_name, NULL);
183 if (null_or_empty_path(path)) {
184 log_debug("%s is empty (a mask).", path);
190 log_error_errno(errno, "Failed to fork: %m");
192 } else if (pid == 0) {
195 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
205 return log_error_errno(errno, "Failed to execute %s: %m", path);
208 log_debug("Spawned %s as " PID_FMT ".", path, pid);
210 r = hashmap_put(pids, PID_TO_PTR(pid), path);
217 /* Abort execution of this process after the timout. We simply
218 * rely on SIGALRM as default action terminating the process,
219 * and turn on alarm(). */
221 if (timeout != USEC_INFINITY)
222 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
224 while (!hashmap_isempty(pids)) {
225 _cleanup_free_ char *path = NULL;
228 pid = PTR_TO_PID(hashmap_first_key(pids));
231 path = hashmap_remove(pids, PID_TO_PTR(pid));
234 wait_for_terminate_and_warn(path, pid, true);
240 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
244 char **dirs = (char**) directories;
246 assert(!strv_isempty(dirs));
248 name = basename(dirs[0]);
249 assert(!isempty(name));
251 /* Executes all binaries in the directories in parallel and waits
252 * for them to finish. Optionally a timeout is applied. If a file
253 * with the same name exists in more than one directory, the
254 * earliest one wins. */
256 executor_pid = fork();
257 if (executor_pid < 0) {
258 log_error_errno(errno, "Failed to fork: %m");
261 } else if (executor_pid == 0) {
262 r = do_execute(dirs, timeout, argv);
263 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
266 wait_for_terminate_and_warn(name, executor_pid, true);
269 bool plymouth_running(void) {
270 return access("/run/plymouth/pid", F_OK) >= 0;
273 bool display_is_local(const char *display) {
282 int socket_from_display(const char *display, char **path) {
289 if (!display_is_local(display))
292 k = strspn(display+1, "0123456789");
294 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
298 c = stpcpy(f, "/tmp/.X11-unix/X");
299 memcpy(c, display+1, k);
307 int block_get_whole_disk(dev_t d, dev_t *ret) {
314 /* If it has a queue this is good enough for us */
315 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
326 /* If it is a partition find the originating device */
327 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
336 /* Get parent dev_t */
337 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
340 r = read_one_line_file(p, &s);
346 r = sscanf(s, "%u:%u", &m, &n);
352 /* Only return this if it is really good enough for us. */
353 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
360 *ret = makedev(m, n);
367 bool kexec_loaded(void) {
371 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
379 int prot_from_flags(int flags) {
381 switch (flags & O_ACCMODE) {
390 return PROT_READ|PROT_WRITE;
397 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
398 bool stdout_is_tty, stderr_is_tty;
399 pid_t parent_pid, agent_pid;
400 sigset_t ss, saved_ss;
408 /* Spawns a temporary TTY agent, making sure it goes away when
411 parent_pid = getpid();
413 /* First we temporarily block all signals, so that the new
414 * child has them blocked initially. This way, we can be sure
415 * that SIGTERMs are not lost we might send to the agent. */
416 assert_se(sigfillset(&ss) >= 0);
417 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
421 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
425 if (agent_pid != 0) {
426 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
433 * Make sure the agent goes away when the parent dies */
434 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
437 /* Make sure we actually can kill the agent, if we need to, in
438 * case somebody invoked us from a shell script that trapped
439 * SIGTERM or so... */
440 (void) reset_all_signal_handlers();
441 (void) reset_signal_mask();
443 /* Check whether our parent died before we were able
444 * to set the death signal and unblock the signals */
445 if (getppid() != parent_pid)
448 /* Don't leak fds to the agent */
449 close_all_fds(except, n_except);
451 stdout_is_tty = isatty(STDOUT_FILENO);
452 stderr_is_tty = isatty(STDERR_FILENO);
454 if (!stdout_is_tty || !stderr_is_tty) {
457 /* Detach from stdout/stderr. and reopen
458 * /dev/tty for them. This is important to
459 * ensure that when systemctl is started via
460 * popen() or a similar call that expects to
461 * read EOF we actually do generate EOF and
462 * not delay this indefinitely by because we
463 * keep an unused copy of stdin around. */
464 fd = open("/dev/tty", O_WRONLY);
466 log_error_errno(errno, "Failed to open /dev/tty: %m");
471 dup2(fd, STDOUT_FILENO);
474 dup2(fd, STDERR_FILENO);
480 /* Count arguments */
482 for (n = 0; va_arg(ap, char*); n++)
487 l = alloca(sizeof(char *) * (n + 1));
489 /* Fill in arguments */
491 for (i = 0; i <= n; i++)
492 l[i] = va_arg(ap, char*);
499 bool in_initrd(void) {
500 static int saved = -1;
506 /* We make two checks here:
508 * 1. the flag file /etc/initrd-release must exist
509 * 2. the root file system must be a memory file system
511 * The second check is extra paranoia, since misdetecting an
512 * initrd can have bad bad consequences due the initrd
513 * emptying when transititioning to the main systemd.
516 saved = access("/etc/initrd-release", F_OK) >= 0 &&
517 statfs("/", &s) >= 0 &&
523 /* hey glibc, APIs with callbacks without a user pointer are so useless */
524 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
525 int (*compar) (const void *, const void *, void *), void *arg) {
534 p = (void *)(((const char *) base) + (idx * size));
535 comparison = compar(key, p, arg);
538 else if (comparison > 0)
546 int on_ac_power(void) {
547 bool found_offline = false, found_online = false;
548 _cleanup_closedir_ DIR *d = NULL;
550 d = opendir("/sys/class/power_supply");
552 return errno == ENOENT ? true : -errno;
556 _cleanup_close_ int fd = -1, device = -1;
562 if (!de && errno != 0)
568 if (hidden_file(de->d_name))
571 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
573 if (errno == ENOENT || errno == ENOTDIR)
579 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
587 n = read(fd, contents, sizeof(contents));
591 if (n != 6 || memcmp(contents, "Mains\n", 6))
595 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
603 n = read(fd, contents, sizeof(contents));
607 if (n != 2 || contents[1] != '\n')
610 if (contents[0] == '1') {
613 } else if (contents[0] == '0')
614 found_offline = true;
619 return found_online || !found_offline;
622 bool id128_is_valid(const char *s) {
628 /* Simple formatted 128bit hex string */
630 for (i = 0; i < l; i++) {
633 if (!(c >= '0' && c <= '9') &&
634 !(c >= 'a' && c <= 'z') &&
635 !(c >= 'A' && c <= 'Z'))
639 } else if (l == 36) {
643 for (i = 0; i < l; i++) {
646 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
650 if (!(c >= '0' && c <= '9') &&
651 !(c >= 'a' && c <= 'z') &&
652 !(c >= 'A' && c <= 'Z'))
663 int container_get_leader(const char *machine, pid_t *pid) {
664 _cleanup_free_ char *s = NULL, *class = NULL;
672 if (!machine_name_is_valid(machine))
675 p = strjoina("/run/systemd/machines/", machine);
676 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
684 if (!streq_ptr(class, "container"))
687 r = parse_pid(s, &leader);
697 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
698 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
706 mntns = procfs_file_alloca(pid, "ns/mnt");
707 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
715 pidns = procfs_file_alloca(pid, "ns/pid");
716 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
724 netns = procfs_file_alloca(pid, "ns/net");
725 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
733 userns = procfs_file_alloca(pid, "ns/user");
734 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
735 if (usernsfd < 0 && errno != ENOENT)
742 root = procfs_file_alloca(pid, "root");
743 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
758 *userns_fd = usernsfd;
763 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
768 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
769 if (userns_fd >= 0) {
770 /* Can't setns to your own userns, since then you could
771 * escalate from non-root to root in your own namespace, so
772 * check if namespaces equal before attempting to enter. */
773 _cleanup_free_ char *userns_fd_path = NULL;
775 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
778 r = files_same(userns_fd_path, "/proc/self/ns/user");
786 if (setns(pidns_fd, CLONE_NEWPID) < 0)
790 if (setns(mntns_fd, CLONE_NEWNS) < 0)
794 if (setns(netns_fd, CLONE_NEWNET) < 0)
798 if (setns(userns_fd, CLONE_NEWUSER) < 0)
802 if (fchdir(root_fd) < 0)
809 return reset_uid_gid();
812 uint64_t physical_memory(void) {
815 /* We return this as uint64_t in case we are running as 32bit
816 * process on a 64bit kernel with huge amounts of memory */
818 mem = sysconf(_SC_PHYS_PAGES);
821 return (uint64_t) mem * (uint64_t) page_size();
824 int update_reboot_param_file(const char *param) {
828 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
830 return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
832 (void) unlink(REBOOT_PARAM_FILE);
838 puts(PACKAGE_STRING "\n"