main.c revision e21fea24ae2a7a04f6d5c9d2bbbaf5833d248952
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/***
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2010 Lennart Poettering
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer under the terms of the GNU Lesser General Public License as published by
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Lesser General Public License for more details.
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier***/
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <dbus/dbus.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <stdio.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <errno.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <string.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <unistd.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/types.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/stat.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <getopt.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <signal.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/wait.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <fcntl.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/prctl.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include <sys/mount.h>
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "manager.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "log.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "load-fragment.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "fdset.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "special.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "conf-parser.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "dbus-common.h"
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier#include "missing.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "label.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "build.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "strv.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "def.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "virt.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "watchdog.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "path-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "switch-root.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "capability.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "killall.h"
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt#include "env-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "hwclock.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "sd-daemon.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "sd-messages.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "mount-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "loopback-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#ifdef HAVE_KMOD
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "kmod-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#endif
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "hostname-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "machine-id-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "selinux-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "ima-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "fileio.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "smack-setup.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic enum {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier ACTION_RUN,
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek ACTION_HELP,
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek ACTION_VERSION,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier ACTION_TEST,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier ACTION_DUMP_CONFIGURATION_ITEMS,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier ACTION_DONE
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek} arg_action = ACTION_RUN;
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic char *arg_default_unit = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic bool arg_dump_core = true;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic bool arg_crash_shell = false;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int arg_crash_chvt = -1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic bool arg_confirm_spawn = false;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic bool arg_show_status = true;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic bool arg_switched_root = false;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic char ***arg_join_controllers = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic usec_t arg_runtime_watchdog = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic char **arg_default_environment = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic uint64_t arg_capability_bounding_set_drop = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic nsec_t arg_timer_slack_nsec = (nsec_t) -1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic FILE* serialization = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic void nop_handler(int sig) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier_noreturn_ static void crash(int sig) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (getpid() != 1)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Pass this on immediately, if this is not PID 1 */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier raise(sig);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (!arg_dump_core)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct sigaction sa = {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_handler = nop_handler,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_flags = SA_NOCLDSTOP|SA_RESTART,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pid_t pid;
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* We want to wait for the core process, hence let's enable SIGCHLD */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sigaction(SIGCHLD, &sa, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pid = fork();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (pid < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (pid == 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct rlimit rl = {};
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Enable default signal handler for core dump */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier zero(sa);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sa.sa_handler = SIG_DFL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sigaction(sig, &sa, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek /* Don't limit the core dump size */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier rl.rlim_cur = RLIM_INFINITY;
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek rl.rlim_max = RLIM_INFINITY;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier setrlimit(RLIMIT_CORE, &rl);
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Just to be sure... */
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek chdir("/");
b8667ee4162cd2510363602b417cecede9fd2ccaZbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Raise the signal again */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier raise(sig);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek assert_not_reached("We shouldn't be here...");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _exit(1);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier siginfo_t status;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Order things nicely. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = wait_for_terminate(pid, &status);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (status.si_code != CLD_DUMPED)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (arg_crash_chvt)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier chvt(arg_crash_chvt);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (arg_crash_shell) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct sigaction sa = {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_handler = SIG_IGN,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pid_t pid;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_info("Executing crash shell in 10s...");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sleep(10);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Let the kernel reap children for us */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier pid = fork();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (pid < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to fork off crash shell: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else if (pid == 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier make_console_stdio();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier execl("/bin/sh", "/bin/sh", NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("execl() failed: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _exit(1);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_info("Freezing execution.");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier freeze();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic void install_crash_handler(void) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier struct sigaction sa = {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_handler = crash,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier .sa_flags = SA_NODEFER,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int console_setup(bool do_reset) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int tty_fd, r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* If we are init, we connect stdin/stdout/stderr to /dev/null
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * and make sure we don't have a controlling tty. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier release_terminal();
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!do_reset)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (tty_fd < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -tty_fd;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* We don't want to force text mode.
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier * plymouth may be showing pictures already from initrd. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = reset_terminal_fd(tty_fd, false);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error("Failed to reset /dev/console: %s", strerror(-r));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier close_nointr_nofail(tty_fd);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int set_default_unit(const char *u) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier char *c;
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(u);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier c = strdup(u);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!c)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -ENOMEM;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier free(arg_default_unit);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier arg_default_unit = c;
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt return 0;
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt}
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int parse_proc_cmdline_word(const char *word) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier static const char * const rlmap[] = {
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt "emergency", SPECIAL_EMERGENCY_TARGET,
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt "-b", SPECIAL_EMERGENCY_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "single", SPECIAL_RESCUE_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "-s", SPECIAL_RESCUE_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "s", SPECIAL_RESCUE_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "S", SPECIAL_RESCUE_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "1", SPECIAL_RESCUE_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "2", SPECIAL_RUNLEVEL2_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "3", SPECIAL_RUNLEVEL3_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "4", SPECIAL_RUNLEVEL4_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "5", SPECIAL_RUNLEVEL5_TARGET,
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier };
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(word);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (startswith(word, "systemd.unit=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!in_initrd())
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return set_default_unit(word + 13);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "rd.systemd.unit=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (in_initrd())
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return set_default_unit(word + 16);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.log_target=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (log_set_target_from_string(word + 19) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_warning("Failed to parse log target %s. Ignoring.", word + 19);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.log_level=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (log_set_max_level_from_string(word + 18) < 0)
25b47f96d9601ff566257b2a31bfb5f4bd25d661Marko Myllynen log_warning("Failed to parse log level %s. Ignoring.", word + 18);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.log_color=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (log_show_color_from_string(word + 18) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.log_location=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (log_show_location_from_string(word + 21) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.dump_core=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt if ((r = parse_boolean(word + 18)) < 0)
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier arg_dump_core = r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.crash_shell=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if ((r = parse_boolean(word + 20)) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier arg_crash_shell = r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.confirm_spawn=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if ((r = parse_boolean(word + 22)) < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier else
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_confirm_spawn = r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (startswith(word, "systemd.crash_chvt=")) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int k;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (safe_atoi(word + 19, &k) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_crash_chvt = k;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (startswith(word, "systemd.show_status=")) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = parse_boolean(word + 20)) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_show_status = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (startswith(word, "systemd.default_standard_output=")) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = exec_output_from_string(word + 32)) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_std_output = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (startswith(word, "systemd.default_standard_error=")) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = exec_output_from_string(word + 31)) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_std_error = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (startswith(word, "systemd.setenv=")) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_free_ char *cenv = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer cenv = strdup(word + 15);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!cenv)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -ENOMEM;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (env_assignment_is_valid(cenv)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char **env;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer env = strv_env_set(arg_default_environment, cenv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (env)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_environment = env;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Setting environment variable '%s' failed, ignoring: %m", cenv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (startswith(word, "systemd.") ||
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer (in_initrd() && startswith(word, "rd.systemd."))) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *c;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Ignore systemd.journald.xyz and friends */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier c = word;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (startswith(c, "rd."))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer c += 3;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (startswith(c, "systemd."))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer c += 8;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (c[strcspn(c, ".=")] != '.') {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Unknown kernel switch %s. Ignoring.", word);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_info("Supported kernel switches:\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.unit=UNIT Default unit to start\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "rd.systemd.unit=UNIT Default unit to start when run in initrd\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.dump_core=0|1 Dump core on crash\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.crash_shell=0|1 Run shell on crash\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.crash_chvt=N Change to VT #N on crash\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.show_status=0|1 Show status updates on the console during bootup\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " Log target\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.log_level=LEVEL Log level\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.log_color=0|1 Highlight important log messages\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.log_location=0|1 Include code location in log messages\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " Set default log output for services\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer " Set default log error output for services\n"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else if (streq(word, "quiet"))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_show_status = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (streq(word, "debug"))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_set_max_level(LOG_DEBUG);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else if (!in_initrd()) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned i;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* SysV compatibility */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (streq(word, rlmap[i]))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return set_default_unit(rlmap[i+1]);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer#define DEFINE_SETTER(name, func, descr) \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer static int name(const char *unit, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *filename, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned line, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *section, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *lvalue, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int ltype, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *rvalue, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *data, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *userdata) { \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r; \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(filename); \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(lvalue); \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rvalue); \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = func(rvalue); \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_syntax(unit, LOG_ERR, filename, line, -r, \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Invalid " descr "'%s': %s", \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer rvalue, strerror(-r)); \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer \
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0; \
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald HoyerDEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald HoyerDEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald HoyerDEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald HoyerDEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int config_parse_cpu_affinity2(const char *unit,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *filename,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned line,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *section,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *lvalue,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int ltype,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *rvalue,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *data,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *userdata) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *w;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer size_t l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *state;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer cpu_set_t *c = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned ncpus = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(filename);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(lvalue);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rvalue);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer FOREACH_WORD_QUOTED(w, l, rvalue, state) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer char *t;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer unsigned cpu;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!(t = strndup(w, l)))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = safe_atou(t, &cpu);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!c)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!(c = cpu_set_malloc(&ncpus)))
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0 || cpu >= ncpus) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_syntax(unit, LOG_ERR, filename, line, -r,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Failed to parse CPU affinity '%s'", rvalue);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer CPU_FREE(c);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -EBADMSG;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (c) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning_unit(unit, "Failed to set CPU affinity: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer CPU_FREE(c);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void strv_free_free(char ***l) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char ***i;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!l)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (i = l; *i; i++)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(*i);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void free_join_controllers(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free_free(arg_join_controllers);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_join_controllers = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int config_parse_join_controllers(const char *unit,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *filename,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned line,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *section,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *lvalue,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int ltype,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *rvalue,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *data,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer void *userdata) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned n = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *state, *w;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer size_t length;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(filename);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(lvalue);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rvalue);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free_join_controllers();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer FOREACH_WORD_QUOTED(w, length, rvalue, state) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *s, **l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer s = strndup(w, length);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!s)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = strv_split(s, ",");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(s);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_uniq(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (strv_length(l) <= 1) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!arg_join_controllers) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_join_controllers = new(char**, 2);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!arg_join_controllers) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_join_controllers[0] = l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_join_controllers[1] = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer n = 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char ***a;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char ***t;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer t = new0(char**, n+2);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!t) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer n = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer for (a = arg_join_controllers; *a; a++) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (strv_overlap(*a, l)) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char **c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer c = strv_merge(*a, l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!c) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free_free(t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer l = c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char **c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer c = strv_copy(*a);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!c) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free_free(t);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer t[n++] = c;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer t[n++] = strv_uniq(l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer strv_free_free(arg_join_controllers);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_join_controllers = t;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int parse_config_file(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const ConfigTableItem items[] = {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "LogLevel", config_parse_level2, 0, NULL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "LogTarget", config_parse_target, 0, NULL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "LogColor", config_parse_color, 0, NULL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "LogLocation", config_parse_location, 0, NULL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { NULL, NULL, NULL, 0, NULL }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_fclose_ FILE *f;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *fn;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer f = fopen(fn, "re");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!f) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (errno == ENOENT)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to open configuration file '%s': %m", fn);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, false, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to parse configuration file: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int parse_proc_cmdline(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_free_ char *line = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *w, *state;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer size_t l;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Don't read /proc/cmdline if we are in a container, since
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * that is only relevant for the host system */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (detect_container(NULL) > 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = read_one_line_file("/proc/cmdline", &line);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer FOREACH_WORD_QUOTED(w, l, line, state) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_free_ char *word;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer word = strndup(w, l);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!word)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = parse_proc_cmdline_word(word);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int parse_argv(int argc, char *argv[]) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer enum {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_LOG_LEVEL = 0x100,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_LOG_TARGET,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_LOG_COLOR,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_LOG_LOCATION,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_UNIT,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_SYSTEM,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_USER,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_TEST,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_VERSION,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_DUMP_CONFIGURATION_ITEMS,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_DUMP_CORE,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_CRASH_SHELL,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_CONFIRM_SPAWN,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_SHOW_STATUS,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_DESERIALIZE,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_SWITCHED_ROOT,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_INTROSPECT,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_DEFAULT_STD_OUTPUT,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ARG_DEFAULT_STD_ERROR
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer static const struct option options[] = {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "log-target", required_argument, NULL, ARG_LOG_TARGET },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "unit", required_argument, NULL, ARG_UNIT },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "system", no_argument, NULL, ARG_SYSTEM },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "user", no_argument, NULL, ARG_USER },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "test", no_argument, NULL, ARG_TEST },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "help", no_argument, NULL, 'h' },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "version", no_argument, NULL, ARG_VERSION },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "introspect", optional_argument, NULL, ARG_INTROSPECT },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer { NULL, 0, NULL, 0 }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer };
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int c, r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argc >= 1);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(argv);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (getpid() == 1)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer opterr = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer switch (c) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_LOG_LEVEL:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = log_set_max_level_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse log level %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_LOG_TARGET:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = log_set_target_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse log target %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_LOG_COLOR:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (optarg) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = log_show_color_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse log color setting %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_show_color(true);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_LOG_LOCATION:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (optarg) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = log_show_location_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse log location setting %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_show_location(true);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_DEFAULT_STD_OUTPUT:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = exec_output_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse default standard output setting %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_std_output = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_DEFAULT_STD_ERROR:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = exec_output_from_string(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to parse default standard error output setting %s.", optarg);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer } else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_std_error = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_UNIT:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((r = set_default_unit(optarg)) < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_SYSTEM:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_running_as = SYSTEMD_SYSTEM;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_USER:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_running_as = SYSTEMD_USER;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_TEST:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_action = ACTION_TEST;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_VERSION:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_action = ACTION_VERSION;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case ARG_DUMP_CONFIGURATION_ITEMS:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_DUMP_CORE:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = optarg ? parse_boolean(optarg) : 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to parse dump core boolean %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_dump_core = r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_CRASH_SHELL:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = optarg ? parse_boolean(optarg) : 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to parse crash shell boolean %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_crash_shell = r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_CONFIRM_SPAWN:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = optarg ? parse_boolean(optarg) : 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to parse confirm spawn boolean %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_confirm_spawn = r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_SHOW_STATUS:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = optarg ? parse_boolean(optarg) : 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to parse show status boolean %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_show_status = r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_DESERIALIZE: {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int fd;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer FILE *f;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = safe_atoi(optarg, &fd);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0 || fd < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to parse deserialize option %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r < 0 ? r : -EINVAL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fd_cloexec(fd, true);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer f = fdopen(fd, "r");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!f) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to open serialization fd: %m");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return -errno;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (serialization)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fclose(serialization);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer serialization = f;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_SWITCHED_ROOT:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_switched_root = true;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case ARG_INTROSPECT: {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char * const * i = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer for (i = bus_interface_table; *i; i += 2)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!optarg || streq(i[0], optarg)) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer "<node>\n", stdout);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fputs(i[1], stdout);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fputs("</node>\n", stdout);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (optarg)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
c53158818d8cdaf46b3f1b5299b9bda118a1043fThomas Hindoe Paaboel Andersen }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!i[0] && optarg)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Unknown interface %s.", optarg);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_action = ACTION_DONE;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case 'h':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer arg_action = ACTION_HELP;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case 'D':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_set_max_level(LOG_DEBUG);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case 'b':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case 's':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case 'z':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Just to eat away the sysvinit kernel
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * cmdline args without getopt() error
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * messages that we'll parse in
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * parse_proc_cmdline_word() or ignore. */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer case '?':
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer default:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (getpid() != 1) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Unknown option code %c", c);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return -EINVAL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer break;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (optind < argc && getpid() != 1) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Hmm, when we aren't run as init system
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * let's complain about excess arguments */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Excess arguments.");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return -EINVAL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (detect_container(NULL) > 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer char **a;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* All /proc/cmdline arguments the kernel didn't
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * understand it passed to us. We're not really
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * interested in that usually since /proc/cmdline is
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * more interesting and complete. With one exception:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * if we are run in a container /proc/cmdline is not
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * relevant for the container, hence we rely on argv[]
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * instead. */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer for (a = argv; a < argv + argc; a++)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if ((r = parse_proc_cmdline_word(*a)) < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int help(void) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer printf("%s [OPTIONS...]\n\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer "Starts up and maintains the system or user services.\n\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " -h --help Show this help\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --test Determine startup sequence, dump it and exit\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --dump-configuration-items Dump understood unit configuration items\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --introspect[=INTERFACE] Extract D-Bus interface data\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --unit=UNIT Set default unit\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --system Run a system instance, even if PID != 1\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --user Run a user instance\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --dump-core[=0|1] Dump core on crash\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --crash-shell[=0|1] Run shell on crash\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --show-status[=0|1] Show status updates on the console during bootup\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --log-color[=0|1] Highlight important log messages\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --log-location[=0|1] Include code location in log messages\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --default-standard-output= Set default standard output for services\n"
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer " --default-standard-error= Set default standard error output for services\n",
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer program_invocation_short_name);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int version(void) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer puts(PACKAGE_STRING);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer puts(SYSTEMD_FEATURES);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching_root) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer FILE *f = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer FDSet *fds = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(m);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(_f);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(_fds);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = manager_open_serialization(m, &f);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to create serialization file: %s", strerror(-r));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Make sure nothing is really destructed when we shut down */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer m->n_reloading ++;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer bus_broadcast_reloading(m, true);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer fds = fdset_new();
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!fds) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = -ENOMEM;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to allocate fd set: %s", strerror(-r));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = manager_serialize(m, f, fds, switching_root);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to serialize state: %s", strerror(-r));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (fseeko(f, 0, SEEK_SET) < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to rewind serialization fd: %m");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = fd_cloexec(fileno(f), false);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = fdset_cloexec(fds, false);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto fail;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *_f = f;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer *_fds = fds;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfail:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer fdset_free(fds);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (f)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer fclose(f);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer struct rlimit nl;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(saved_rlimit);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Save the original RLIMIT_NOFILE so that we can reset it
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * later when transitioning from the initrd to the main
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * systemd or suchlike. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer log_error("Reading RLIMIT_NOFILE failed: %m");
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer return -errno;
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer }
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer /* Make sure forked processes get the default kernel setting */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!arg_default_rlimit[RLIMIT_NOFILE]) {
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer struct rlimit *rl;
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer rl = newdup(struct rlimit, saved_rlimit, 1);
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer if (!rl)
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer return log_oom();
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer arg_default_rlimit[RLIMIT_NOFILE] = rl;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Bump up the resource limit for ourselves substantially */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer nl.rlim_cur = nl.rlim_max = 64*1024;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = setrlimit_closest(RLIMIT_NOFILE, &nl);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void test_mtab(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer char *p;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Check that /etc/mtab is a symlink */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (readlink_malloc("/etc/mtab", &p) >= 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bool b;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer free(p);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (b)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "This is not supported anymore. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void test_usr(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Check that /usr is not a separate fs */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (dir_is_empty("/usr") <= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Some things will probably break (sometimes even silently) in mysterious ways. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void test_cgroups(void) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (access("/proc/cgroups", F_OK) >= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Systems without control groups are not supported. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "We will now sleep for 10s, and then continue boot-up. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Expect breakage and please do not file bugs. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Instead fix your kernel and enable CONFIG_CGROUPS. "
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
sleep(10);
}
static int initialize_join_controllers(void) {
/* By default, mount "cpu" + "cpuacct" together, and "net_cls"
* + "net_prio". We'd like to add "cpuset" to the mix, but
* "cpuset" does't really work for groups with no initialized
* attributes. */
arg_join_controllers = new(char**, 3);
if (!arg_join_controllers)
return -ENOMEM;
arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
arg_join_controllers[2] = NULL;
if (!arg_join_controllers[0] || !arg_join_controllers[1]) {
free_join_controllers();
return -ENOMEM;
}
return 0;
}
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r, retval = EXIT_FAILURE;
usec_t before_startup, after_startup;
char timespan[FORMAT_TIMESPAN_MAX];
FDSet *fds = NULL;
bool reexecute = false;
const char *shutdown_verb = NULL;
dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
dual_timestamp userspace_timestamp = { 0ULL, 0ULL };
dual_timestamp kernel_timestamp = { 0ULL, 0ULL };
static char systemd[] = "systemd";
bool skip_setup = false;
int j;
bool loaded_policy = false;
bool arm_reboot_watchdog = false;
bool queue_default_job = false;
char *switch_root_dir = NULL, *switch_root_init = NULL;
static struct rlimit saved_rlimit_nofile = { 0, 0 };
#ifdef HAVE_SYSV_COMPAT
if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
/* This is compatibility support for SysV, where
* calling init as a user is identical to telinit. */
errno = -ENOENT;
execv(SYSTEMCTL_BINARY_PATH, argv);
log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
return 1;
}
#endif
dual_timestamp_from_monotonic(&kernel_timestamp, 0);
dual_timestamp_get(&userspace_timestamp);
/* Determine if this is a reexecution or normal bootup. We do
* the full command line parsing much later, so let's just
* have a quick peek here. */
if (strv_find(argv+1, "--deserialize"))
skip_setup = true;
/* If we have switched root, do all the special setup
* things */
if (strv_find(argv+1, "--switched-root"))
skip_setup = false;
/* If we get started via the /sbin/init symlink then we are
called 'init'. After a subsequent reexecution we are then
called 'systemd'. That is confusing, hence let's call us
systemd right-away. */
program_invocation_short_name = systemd;
prctl(PR_SET_NAME, systemd);
saved_argv = argv;
saved_argc = argc;
log_show_color(isatty(STDERR_FILENO) > 0);
if (getpid() == 1 && detect_container(NULL) <= 0) {
/* Running outside of a container as PID 1 */
arg_running_as = SYSTEMD_SYSTEM;
make_null_stdio();
log_set_target(LOG_TARGET_KMSG);
log_open();
if (in_initrd())
initrd_timestamp = userspace_timestamp;
if (!skip_setup) {
mount_setup_early();
if (selinux_setup(&loaded_policy) < 0)
goto finish;
if (ima_setup() < 0)
goto finish;
if (smack_setup() < 0)
goto finish;
}
if (label_init(NULL) < 0)
goto finish;
if (!skip_setup) {
if (hwclock_is_localtime() > 0) {
int min;
/* The first-time call to settimeofday() does a time warp in the kernel */
r = hwclock_set_timezone(&min);
if (r < 0)
log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
else
log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
} else if (!in_initrd()) {
/*
* Do dummy first-time call to seal the kernel's time warp magic
*
* Do not call this this from inside the initrd. The initrd might not
* carry /etc/adjtime with LOCAL, but the real system could be set up
* that way. In such case, we need to delay the time-warp or the sealing
* until we reach the real system.
*/
hwclock_reset_timezone();
/* Tell the kernel our timezone */
r = hwclock_set_timezone(NULL);
if (r < 0)
log_error("Failed to set the kernel's timezone, ignoring: %s", strerror(-r));
}
}
/* Set the default for later on, but don't actually
* open the logs like this for now. Note that if we
* are transitioning from the initrd there might still
* be journal fd open, and we shouldn't attempt
* opening that before we parsed /proc/cmdline which
* might redirect output elsewhere. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
} else if (getpid() == 1) {
/* Running inside a container, as PID 1 */
arg_running_as = SYSTEMD_SYSTEM;
log_set_target(LOG_TARGET_CONSOLE);
log_open();
/* For the later on, see above... */
log_set_target(LOG_TARGET_JOURNAL);
/* clear the kernel timestamp,
* because we are in a container */
kernel_timestamp.monotonic = 0ULL;
kernel_timestamp.realtime = 0ULL;
} else {
/* Running as user instance */
arg_running_as = SYSTEMD_USER;
log_set_target(LOG_TARGET_AUTO);
log_open();
/* clear the kernel timestamp,
* because we are not PID 1 */
kernel_timestamp.monotonic = 0ULL;
kernel_timestamp.realtime = 0ULL;
}
/* Initialize default unit */
r = set_default_unit(SPECIAL_DEFAULT_TARGET);
if (r < 0) {
log_error("Failed to set default unit %s: %s", SPECIAL_DEFAULT_TARGET, strerror(-r));
goto finish;
}
r = initialize_join_controllers();
if (r < 0)
goto finish;
/* Mount /proc, /sys and friends, so that /proc/cmdline and
* /proc/$PID/fd is available. */
if (getpid() == 1) {
r = mount_setup(loaded_policy);
if (r < 0)
goto finish;
}
/* Reset all signal handlers. */
assert_se(reset_all_signal_handlers() == 0);
ignore_signals(SIGNALS_IGNORE, -1);
if (parse_config_file() < 0)
goto finish;
if (arg_running_as == SYSTEMD_SYSTEM)
if (parse_proc_cmdline() < 0)
goto finish;
log_parse_environment();
if (parse_argv(argc, argv) < 0)
goto finish;
if (arg_action == ACTION_TEST &&
geteuid() == 0) {
log_error("Don't run test mode as root.");
goto finish;
}
if (arg_running_as == SYSTEMD_USER &&
arg_action == ACTION_RUN &&
sd_booted() <= 0) {
log_error("Trying to run as user instance, but the system has not been booted with systemd.");
goto finish;
}
if (arg_running_as == SYSTEMD_SYSTEM &&
arg_action == ACTION_RUN &&
running_in_chroot() > 0) {
log_error("Cannot be run in a chroot() environment.");
goto finish;
}
if (arg_action == ACTION_HELP) {
retval = help();
goto finish;
} else if (arg_action == ACTION_VERSION) {
retval = version();
goto finish;
} else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
unit_dump_config_items(stdout);
retval = EXIT_SUCCESS;
goto finish;
} else if (arg_action == ACTION_DONE) {
retval = EXIT_SUCCESS;
goto finish;
}
assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
/* Close logging fds, in order not to confuse fdset below */
log_close();
/* Remember open file descriptors for later deserialization */
r = fdset_new_fill(&fds);
if (r < 0) {
log_error("Failed to allocate fd set: %s", strerror(-r));
goto finish;
} else
fdset_cloexec(fds, true);
if (serialization)
assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
if (arg_running_as == SYSTEMD_SYSTEM) {
/* Become a session leader if we aren't one yet. */
setsid();
/* Disable the umask logic */
umask(0);
}
/* Move out of the way, so that we won't block unmounts */
assert_se(chdir("/") == 0);
/* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
dbus_connection_set_change_sigpipe(FALSE);
/* Reset the console, but only if this is really init and we
* are freshly booted */
if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
console_setup(getpid() == 1 && !skip_setup);
/* Open the logging devices, if possible and necessary */
log_open();
/* Make sure we leave a core dump without panicing the
* kernel. */
if (getpid() == 1) {
install_crash_handler();
r = mount_cgroup_controllers(arg_join_controllers);
if (r < 0)
goto finish;
}
if (arg_running_as == SYSTEMD_SYSTEM) {
const char *virtualization = NULL;
log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
detect_virtualization(&virtualization);
if (virtualization)
log_info("Detected virtualization '%s'.", virtualization);
if (in_initrd())
log_info("Running in initial RAM disk.");
} else
log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
if (arg_show_status || plymouth_running())
status_welcome();
#ifdef HAVE_KMOD
kmod_setup();
#endif
hostname_setup();
machine_id_setup();
loopback_setup();
test_mtab();
test_usr();
test_cgroups();
}
if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
watchdog_set_timeout(&arg_runtime_watchdog);
if (arg_timer_slack_nsec != (nsec_t) -1)
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_error("Failed to adjust timer slack: %m");
if (arg_capability_bounding_set_drop) {
r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
if (r < 0) {
log_error("Failed to drop capability bounding set: %s", strerror(-r));
goto finish;
}
r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
if (r < 0) {
log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
goto finish;
}
}
if (arg_running_as == SYSTEMD_USER) {
/* Become reaper of our children */
if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
log_warning("Failed to make us a subreaper: %m");
if (errno == EINVAL)
log_info("Perhaps the kernel version is too old (< 3.4?)");
}
}
if (arg_running_as == SYSTEMD_SYSTEM)
bump_rlimit_nofile(&saved_rlimit_nofile);
r = manager_new(arg_running_as, !!serialization, &m);
if (r < 0) {
log_error("Failed to allocate manager object: %s", strerror(-r));
goto finish;
}
m->confirm_spawn = arg_confirm_spawn;
m->default_std_output = arg_default_std_output;
m->default_std_error = arg_default_std_error;
m->runtime_watchdog = arg_runtime_watchdog;
m->shutdown_watchdog = arg_shutdown_watchdog;
m->userspace_timestamp = userspace_timestamp;
m->kernel_timestamp = kernel_timestamp;
m->initrd_timestamp = initrd_timestamp;
manager_set_default_rlimits(m, arg_default_rlimit);
if (arg_default_environment)
manager_environment_add(m, arg_default_environment);
manager_set_show_status(m, arg_show_status);
/* Remember whether we should queue the default job */
queue_default_job = !serialization || arg_switched_root;
before_startup = now(CLOCK_MONOTONIC);
r = manager_startup(m, serialization, fds);
if (r < 0)
log_error("Failed to fully start up daemon: %s", strerror(-r));
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
fdset_free(fds);
if (serialization) {
fclose(serialization);
serialization = NULL;
}
if (queue_default_job) {
DBusError error;
Unit *target = NULL;
Job *default_unit_job;
dbus_error_init(&error);
log_debug("Activating default unit: %s", arg_default_unit);
r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
if (r < 0) {
log_error("Failed to load default target: %s", bus_error(&error, r));
dbus_error_free(&error);
} else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND)
log_error("Failed to load default target: %s", strerror(-target->load_error));
else if (target->load_state == UNIT_MASKED)
log_error("Default target masked.");
if (!target || target->load_state != UNIT_LOADED) {
log_info("Trying to load rescue target...");
r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
if (r < 0) {
log_error("Failed to load rescue target: %s", bus_error(&error, r));
dbus_error_free(&error);
goto finish;
} else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND) {
log_error("Failed to load rescue target: %s", strerror(-target->load_error));
goto finish;
} else if (target->load_state == UNIT_MASKED) {
log_error("Rescue target masked.");
goto finish;
}
}
assert(target->load_state == UNIT_LOADED);
if (arg_action == ACTION_TEST) {
printf("-> By units:\n");
manager_dump_units(m, stdout, "\t");
}
r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, false, &error, &default_unit_job);
if (r == -EPERM) {
log_debug("Default target could not be isolated, starting instead: %s", bus_error(&error, r));
dbus_error_free(&error);
r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
if (r < 0) {
log_error("Failed to start default target: %s", bus_error(&error, r));
dbus_error_free(&error);
goto finish;
}
} else if (r < 0) {
log_error("Failed to isolate default target: %s", bus_error(&error, r));
dbus_error_free(&error);
goto finish;
}
m->default_unit_job_id = default_unit_job->id;
after_startup = now(CLOCK_MONOTONIC);
log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
"Loaded units and determined initial transaction in %s.",
format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 0));
if (arg_action == ACTION_TEST) {
printf("-> By jobs:\n");
manager_dump_jobs(m, stdout, "\t");
retval = EXIT_SUCCESS;
goto finish;
}
}
for (;;) {
r = manager_loop(m);
if (r < 0) {
log_error("Failed to run mainloop: %s", strerror(-r));
goto finish;
}
switch (m->exit_code) {
case MANAGER_EXIT:
retval = EXIT_SUCCESS;
log_debug("Exit.");
goto finish;
case MANAGER_RELOAD:
log_info("Reloading.");
r = manager_reload(m);
if (r < 0)
log_error("Failed to reload: %s", strerror(-r));
break;
case MANAGER_REEXECUTE:
if (prepare_reexecute(m, &serialization, &fds, false) < 0)
goto finish;
reexecute = true;
log_notice("Reexecuting.");
goto finish;
case MANAGER_SWITCH_ROOT:
/* Steal the switch root parameters */
switch_root_dir = m->switch_root;
switch_root_init = m->switch_root_init;
m->switch_root = m->switch_root_init = NULL;
if (!switch_root_init)
if (prepare_reexecute(m, &serialization, &fds, true) < 0)
goto finish;
reexecute = true;
log_notice("Switching root.");
goto finish;
case MANAGER_REBOOT:
case MANAGER_POWEROFF:
case MANAGER_HALT:
case MANAGER_KEXEC: {
static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
[MANAGER_REBOOT] = "reboot",
[MANAGER_POWEROFF] = "poweroff",
[MANAGER_HALT] = "halt",
[MANAGER_KEXEC] = "kexec"
};
assert_se(shutdown_verb = table[m->exit_code]);
arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
log_notice("Shutting down.");
goto finish;
}
default:
assert_not_reached("Unknown exit code.");
}
}
finish:
if (m)
manager_free(m);
for (j = 0; j < RLIMIT_NLIMITS; j++)
free(arg_default_rlimit[j]);
free(arg_default_unit);
free_join_controllers();
dbus_shutdown();
label_finish();
if (reexecute) {
const char **args;
unsigned i, args_size;
/* Close and disarm the watchdog, so that the new
* instance can reinitialize it, but doesn't get
* rebooted while we do that */
watchdog_close(true);
/* Reset the RLIMIT_NOFILE to the kernel default, so
* that the new systemd can pass the kernel default to
* its child processes */
if (saved_rlimit_nofile.rlim_cur > 0)
setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
if (switch_root_dir) {
/* Kill all remaining processes from the
* initrd, but don't wait for them, so that we
* can handle the SIGCHLD for them after
* deserializing. */
broadcast_signal(SIGTERM, false);
/* And switch root */
r = switch_root(switch_root_dir);
if (r < 0)
log_error("Failed to switch root, ignoring: %s", strerror(-r));
}
args_size = MAX(6, argc+1);
args = newa(const char*, args_size);
if (!switch_root_init) {
char sfd[16];
/* First try to spawn ourselves with the right
* path, and with full serialization. We do
* this only if the user didn't specify an
* explicit init to spawn. */
assert(serialization);
assert(fds);
snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
char_array_0(sfd);
i = 0;
args[i++] = SYSTEMD_BINARY_PATH;
if (switch_root_dir)
args[i++] = "--switched-root";
args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user";
args[i++] = "--deserialize";
args[i++] = sfd;
args[i++] = NULL;
assert(i <= args_size);
execv(args[0], (char* const*) args);
}
/* Try the fallback, if there is any, without any
* serialization. We pass the original argv[] and
* envp[]. (Well, modulo the ordering changes due to
* getopt() in argv[], and some cleanups in envp[],
* but let's hope that doesn't matter.) */
if (serialization) {
fclose(serialization);
serialization = NULL;
}
if (fds) {
fdset_free(fds);
fds = NULL;
}
/* Reopen the console */
make_console_stdio();
for (j = 1, i = 1; j < argc; j++)
args[i++] = argv[j];
args[i++] = NULL;
assert(i <= args_size);
if (switch_root_init) {
args[0] = switch_root_init;
execv(args[0], (char* const*) args);
log_warning("Failed to execute configured init, trying fallback: %m");
}
args[0] = "/sbin/init";
execv(args[0], (char* const*) args);
if (errno == ENOENT) {
log_warning("No /sbin/init, trying fallback");
args[0] = "/bin/sh";
args[1] = NULL;
execv(args[0], (char* const*) args);
log_error("Failed to execute /bin/sh, giving up: %m");
} else
log_warning("Failed to execute /sbin/init, giving up: %m");
}
if (serialization)
fclose(serialization);
if (fds)
fdset_free(fds);
if (shutdown_verb) {
const char * command_line[] = {
SYSTEMD_SHUTDOWN_BINARY_PATH,
shutdown_verb,
NULL
};
char **env_block;
if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
char e[32];
/* If we reboot let's set the shutdown
* watchdog and tell the shutdown binary to
* repeatedly ping it */
watchdog_set_timeout(&arg_shutdown_watchdog);
watchdog_close(false);
/* Tell the binary how often to ping */
snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
char_array_0(e);
env_block = strv_append(environ, e);
} else {
env_block = strv_copy(environ);
watchdog_close(true);
}
/* Avoid the creation of new processes forked by the
* kernel; at this point, we will not listen to the
* signals anyway */
if (detect_container(NULL) <= 0)
cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
free(env_block);
log_error("Failed to execute shutdown binary, freezing: %m");
}
if (getpid() == 1)
freeze();
return retval;
}