main.c revision 9a0549093332880df47c4218209ce126b8586835
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen This file is part of systemd.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen Copyright 2010 Lennart Poettering
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen systemd is free software; you can redistribute it and/or modify it
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen under the terms of the GNU Lesser General Public License as published by
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen the Free Software Foundation; either version 2.1 of the License, or
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen (at your option) any later version.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen systemd is distributed in the hope that it will be useful, but
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen Lesser General Public License for more details.
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen You should have received a copy of the GNU Lesser General Public License
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek ACTION_DUMP_CONFIGURATION_ITEMS,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic char *arg_default_unit = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_dump_core = true;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_crash_shell = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_confirm_spawn = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_switched_root = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic char ***arg_join_controllers = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_runtime_watchdog = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic char **arg_default_environment = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic uint64_t arg_capability_bounding_set_drop = 0;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic nsec_t arg_timer_slack_nsec = (nsec_t) -1;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic Set* arg_syscall_archs = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic FILE* arg_serialization = NULL;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_default_cpu_accounting = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_default_blockio_accounting = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic bool arg_default_memory_accounting = false;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void nop_handler(int sig) {}
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmeknoreturn static void crash(int sig) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Pass this on immediately, if this is not PID 1 */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek .sa_flags = SA_NOCLDSTOP|SA_RESTART,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* We want to wait for the core process, hence let's enable SIGCHLD */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (pid == 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Enable default signal handler for core dump */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Don't limit the core dump size */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Just to be sure... */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Raise the signal again */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert_not_reached("We shouldn't be here...");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Order things nicely. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = wait_for_terminate(pid, &status);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (status.si_code != CLD_DUMPED)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Caught <%s>, dumped core as pid "PID_FMT".", signal_to_string(sig), pid);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_info("Executing crash shell in 10s...");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Let the kernel reap children for us */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to fork off crash shell: %m");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek else if (pid == 0) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek execl("/bin/sh", "/bin/sh", NULL);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("execl() failed: %m");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_info("Successfully spawned crash shell as pid "PID_FMT".", pid);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_info("Freezing execution.");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void install_crash_handler(void) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int console_setup(bool do_reset) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* If we are init, we connect stdin/stdout/stderr to /dev/null
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * and make sure we don't have a controlling tty. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* We don't want to force text mode.
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek * plymouth may be showing pictures already from initrd. */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = reset_terminal_fd(tty_fd, false);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_error("Failed to reset /dev/console: %s", strerror(-r));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int set_default_unit(const char *u) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int parse_proc_cmdline_item(const char *key, const char *value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek static const char * const rlmap[] = {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "emergency", SPECIAL_EMERGENCY_TARGET,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "single", SPECIAL_RESCUE_TARGET,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (streq(key, "systemd.unit") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "rd.systemd.unit") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.log_target") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (log_set_target_from_string(value) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse log target %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.log_level") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (log_set_max_level_from_string(value) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse log level %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.log_color") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (log_show_color_from_string(value) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse log color setting %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.log_location") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (log_show_location_from_string(value) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse log location setting %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.dump_core") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse dump core switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.crash_shell") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse crash shell switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.crash_chvt") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.confirm_spawn") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse confirm spawn switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.show_status") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = parse_show_status(value, &arg_show_status);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse show status switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.default_standard_output") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = exec_output_from_string(value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse default standard output switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.default_standard_error") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek r = exec_output_from_string(value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Failed to parse default standard error switch %s. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "systemd.setenv") && value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (env_assignment_is_valid(value)) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek env = strv_env_set(arg_default_environment, value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Setting environment variable '%s' failed, ignoring: %s", value, strerror(ENOMEM));
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Environment variable name '%s' is not valid. Ignoring.", value);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (!streq(key, "systemd.restore_state") &&
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek !streq(key, "systemd.gpt_auto") &&
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek (startswith(key, "systemd.") || startswith(key, "rd.systemd."))) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* Ignore systemd.journald.xyz and friends */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (c[strcspn(c, ".=")] != '.') {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning("Unknown kernel switch %s. Ignoring.", key);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_info("Supported kernel switches:\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.unit=UNIT Default unit to start\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "rd.systemd.unit=UNIT Default unit to start when run in initrd\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.dump_core=0|1 Dump core on crash\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.crash_shell=0|1 Run shell on crash\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.crash_chvt=N Change to VT #N on crash\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.show_status=0|1|auto Show status updates on the console during bootup\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.log_level=LEVEL Log level\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.log_color=0|1 Highlight important log messages\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.log_location=0|1 Include code location in log messages\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek " Set default log output for services\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek " Set default log error output for services\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n"
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "systemd.restore_state=0|1 Restore backlight/rfkill state at boot\n");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "quiet") && !value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (arg_show_status == _SHOW_STATUS_UNSET)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek arg_show_status = SHOW_STATUS_AUTO;
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (streq(key, "debug") && !value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_set_target(LOG_TARGET_CONSOLE);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek } else if (!in_initrd() && !value) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek /* SysV compatibility */
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek return set_default_unit(rlmap[i+1]);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek#define DEFINE_SETTER(name, func, descr) \
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek static int name(const char *unit, \
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r, \
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekDEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekDEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekDEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-SzmekDEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int config_parse_cpu_affinity2(
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek FOREACH_WORD_QUOTED(w, l, rvalue, state) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!(t = strndup(w, l)))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (!(c = cpu_set_malloc(&ncpus)))
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "Failed to parse CPU affinity '%s'", rvalue);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_warning_unit(unit, "Failed to set CPU affinity: %m");
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int config_parse_show_status(
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek k = parse_show_status(rvalue, b);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -k,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek "Failed to parse show status setting, ignoring: %s", rvalue);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void strv_free_free(char ***l) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (i = l; *i; i++)
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic void free_join_controllers(void) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek strv_free_free(arg_join_controllers);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmekstatic int config_parse_join_controllers(const char *unit,
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek FOREACH_WORD_QUOTED(w, length, rvalue, state) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek arg_join_controllers = new(char**, 2);
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek for (a = arg_join_controllers; *a; a++) {
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma if (strv_overlap(*a, l)) {
f47c5c47d1a7bcfa1842ff7cc52b1f7fc1d86bcfpoma if (strv_extend_strv(&l, *a) < 0) {
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersenstatic int parse_config_file(void) {
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "LogLevel", config_parse_level2, 0, NULL },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "LogTarget", config_parse_target, 0, NULL },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "LogColor", config_parse_color, 0, NULL },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "LogLocation", config_parse_location, 0, NULL },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "DefaultTimerAccuracySec", config_parse_sec, 0, &arg_default_timer_accuracy_usec },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
0a8a0fad010018be0f46d1c2e077ade0eb27c7dbTom Gundersen { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_default_timeout_start_usec },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_default_timeout_stop_usec },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU] },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE] },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA] },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK] },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE] },
798d3a524ea57aaf40cb53858aaa45ec702f012dZbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS] },
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE] },
eac684ef1c29684b1bcd27a89c38c202e568e469Tom Gundersen { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS] },
{ "Manager", "DefaultLimitSIGPENDING", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING] },
const char *fn;
r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, false, NULL);
opterr = 0;
case ARG_LOG_LEVEL:
case ARG_LOG_TARGET:
case ARG_LOG_COLOR:
if (optarg) {
log_show_color(true);
case ARG_LOG_LOCATION:
if (optarg) {
log_show_location(true);
case ARG_DEFAULT_STD_OUTPUT:
case ARG_DEFAULT_STD_ERROR:
case ARG_UNIT:
case ARG_SYSTEM:
case ARG_USER:
case ARG_TEST:
case ARG_VERSION:
case ARG_DUMP_CORE:
arg_dump_core = r;
case ARG_CRASH_SHELL:
arg_crash_shell = r;
case ARG_CONFIRM_SPAWN:
arg_confirm_spawn = r;
case ARG_SHOW_STATUS:
if (optarg) {
case ARG_DESERIALIZE: {
int fd;
FILE *f;
if (r < 0 || fd < 0) {
return r < 0 ? r : -EINVAL;
return -errno;
if (arg_serialization)
arg_serialization = f;
case ARG_SWITCHED_ROOT:
arg_switched_root = true;
return -EINVAL;
return -EINVAL;
_cleanup_free_ char *w;
char *value;
w = strdup(*a);
return log_oom();
if (value)
*(value++) = 0;
static int help(void) {
" --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
static int version(void) {
assert(m);
r = manager_open_serialization(m, &f);
goto fail;
m->n_reloading ++;
bus_manager_send_reloading(m, true);
if (!fds) {
r = -ENOMEM;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
*_f = f;
fail:
fclose(f);
return -errno;
if (!rl)
return log_oom();
static void test_mtab(void) {
free(p);
"Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
static void test_usr(void) {
log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
"Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
static int initialize_join_controllers(void) {
if (!arg_join_controllers)
return -ENOMEM;
return -ENOMEM;
#ifdef HAVE_SECCOMP
Iterator i;
void *id;
if (!seccomp)
return log_oom();
if (r == -EEXIST)
goto finish;
goto finish;
static int status_welcome(void) {
NULL);
if (r < 0 && r != -ENOENT)
bool reexecute = false;
bool skip_setup = false;
bool loaded_policy = false;
bool arm_reboot_watchdog = false;
bool queue_default_job = false;
#ifdef HAVE_SYSV_COMPAT
skip_setup = true;
skip_setup = false;
umask(0);
log_open();
if (in_initrd())
if (!skip_setup) {
goto finish;
if (ima_setup() < 0)
goto finish;
goto finish;
goto finish;
if (!skip_setup) {
if (hwclock_is_localtime() > 0) {
int min;
} else if (!in_initrd()) {
log_open();
log_open();
goto finish;
r = initialize_join_controllers();
goto finish;
goto finish;
if (parse_config_file() < 0)
goto finish;
goto finish;
goto finish;
geteuid() == 0) {
goto finish;
sd_booted() <= 0) {
goto finish;
running_in_chroot() > 0) {
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;
log_close();
goto finish;
if (arg_serialization)
setsid();
log_open();
goto finish;
if (virtualization)
if (in_initrd())
getuid(), t);
#ifdef HAVE_KMOD
kmod_setup();
test_mtab();
test_usr();
goto finish;
goto finish;
if (arg_syscall_archs) {
goto finish;
goto finish;
if (arg_serialization) {
if (queue_default_job) {
goto finish;
goto finish;
goto finish;
if (r == -EPERM) {
log_debug("Default target could not be isolated, starting instead: %s", bus_error_message(&error, r));
goto finish;
goto finish;
goto finish;
r = manager_loop(m);
goto finish;
switch (m->exit_code) {
case MANAGER_EXIT:
goto finish;
case MANAGER_RELOAD:
r = manager_reload(m);
case MANAGER_REEXECUTE:
goto finish;
reexecute = true;
goto finish;
case MANAGER_SWITCH_ROOT:
if (!switch_root_init)
goto finish;
reexecute = true;
goto finish;
case MANAGER_REBOOT:
case MANAGER_POWEROFF:
case MANAGER_HALT:
case MANAGER_KEXEC: {
goto finish;
manager_free(m);
m = NULL;
label_finish();
if (reexecute) {
const char **args;
unsigned i, args_size;
watchdog_close(true);
if (switch_root_dir) {
if (!switch_root_init) {
if (switch_root_dir)
if (switch_root_dir)
clearenv();
if (arg_serialization) {
if (fds) {
if (switch_root_init) {
if (arg_serialization) {
if (fds) {
#ifdef HAVE_VALGRIND_VALGRIND_H
if (shutdown_verb) {
switch (log_get_target()) {
case LOG_TARGET_KMSG:
case LOG_TARGET_CONSOLE:
if (log_get_show_color())
if (log_get_show_location())
watchdog_close(false);
watchdog_close(true);
freeze();
return retval;