main.c revision 06af2a04fb34c3e8f99734571c0c5d2203d6a265
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2010 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic bool arg_dump_core = true;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic bool arg_crash_shell = false;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic bool arg_confirm_spawn = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_switched_root = false;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poetteringstatic char ***arg_join_controllers = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic uint64_t arg_capability_bounding_set_drop = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenstatic usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_default_cpu_accounting = false;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poetteringstatic bool arg_default_blockio_accounting = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_default_memory_accounting = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void pager_open_if_enabled(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Pass this on immediately, if this is not PID 1 */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency("Caught <%s>, not dumping core.", signal_to_string(sig));
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen /* We want to wait for the core process, hence let's enable SIGCHLD */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency_errno(errno, "Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else if (pid == 0) {
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen /* Enable default signal handler for core dump */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Don't limit the core dump size */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Just to be sure... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Raise the signal again */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering kill(pid, sig); /* raise() would kill the parent */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_not_reached("We shouldn't be here...");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Order things nicely. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency_errno(r, "Caught <%s>, waitpid() failed: %m", signal_to_string(sig));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency("Caught <%s>, core dump failed (child "PID_FMT", code=%s, status=%i/%s).",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering pid, sigchld_code_to_string(status.si_code),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ? exit_status_to_string(status.si_status, EXIT_STATUS_FULL)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency("Caught <%s>, dumped core as pid "PID_FMT".", signal_to_string(sig), pid);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø log_info("Executing crash shell in 10s...");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Let the kernel reap children for us */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_emergency_errno(errno, "Failed to fork off crash shell: %m");
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen else if (pid == 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering execle("/bin/sh", "/bin/sh", NULL, environ);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen log_emergency_errno(errno, "execle() failed: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_info("Successfully spawned crash shell as PID "PID_FMT".", pid);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void install_crash_handler(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering .sa_flags = SA_NODEFER, /* So that we can raise the signal again from the signal handler */
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen /* We ignore the return value here, since, we don't mind if we
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * cannot set up a crash handler */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen log_debug_errno(r, "I had trouble setting up the crash handler, ignoring: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int console_setup(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(tty_fd, "Failed to open /dev/console: %m");
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen /* We don't want to force text mode. plymouth may be showing
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * pictures already from initrd. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return log_error_errno(r, "Failed to reset /dev/console: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int set_default_unit(const char *u) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int parse_proc_cmdline_item(const char *key, const char *value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering static const char * const rlmap[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (streq(key, "systemd.unit") && value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "rd.systemd.unit") && value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "systemd.dump_core") && value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to parse dump core switch %s. Ignoring.", value);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "systemd.crash_shell") && value) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to parse crash shell switch %s. Ignoring.", value);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (streq(key, "systemd.crash_chvt") && value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning("Failed to parse crash chvt switch %s. Ignoring.", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else if (streq(key, "systemd.confirm_spawn") && value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning("Failed to parse confirm spawn switch %s. Ignoring.", value);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else if (streq(key, "systemd.show_status") && value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = parse_show_status(value, &arg_show_status);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning("Failed to parse show status switch %s. Ignoring.", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else if (streq(key, "systemd.default_standard_output") && value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning("Failed to parse default standard output switch %s. Ignoring.", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else if (streq(key, "systemd.default_standard_error") && value) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_warning("Failed to parse default standard error switch %s. Ignoring.", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else if (streq(key, "systemd.setenv") && value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering env = strv_env_set(arg_default_environment, value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning_errno(ENOMEM, "Setting environment variable '%s' failed, ignoring: %m", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning("Environment variable name '%s' is not valid. Ignoring.", value);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering } else if (streq(key, "quiet") && !value) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (arg_show_status == _SHOW_STATUS_UNSET)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering } else if (streq(key, "debug") && !value) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Note that log_parse_environment() handles 'debug'
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering * too, and sets the log level to LOG_DEBUG. */
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering /* SysV compatibility */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering#define DEFINE_SETTER(name, func, descr) \
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const char *lvalue, \
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering const char *rvalue, \
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r, \
8d3d7072e609ef0e0fb37e1d19a29307d58146c3Michal SchmidtDEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart PoetteringDEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart PoetteringDEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart PoetteringDEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering FOREACH_WORD_QUOTED(word, l, rvalue, state) {
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r,
4d506d6bb757af3b99e0876234c465e6898c5ea4Lennart Poettering "Failed to parse CPU affinity '%s'", rvalue);
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_syntax(unit, LOG_ERR, filename, line, EINVAL,
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen "Trailing garbage, ignoring.");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_warning("Failed to set CPU affinity: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -k,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Failed to parse show status setting, ignoring: %s", rvalue);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic void strv_free_free(char ***l) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering for (i = l; *i; i++)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poetteringstatic void free_join_controllers(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int config_parse_join_controllers(const char *unit,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned n = 0;
096b6773886bd7a0c8c97aa684b0b67dfae58355Lennart Poettering FOREACH_WORD_QUOTED(word, length, rvalue, state) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (a = arg_join_controllers; *a; a++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (strv_extend_strv(&l, *a) < 0) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, EINVAL,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "Trailing garbage, ignoring.");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int parse_config_file(void) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "LogLevel", config_parse_level2, 0, NULL },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "LogTarget", config_parse_target, 0, NULL },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "LogColor", config_parse_color, 0, NULL },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "LogLocation", config_parse_location, 0, NULL },
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
2a1288ff89322a2f49c79f6d1832c8164c14a05cLennart Poettering { "Manager", "DefaultTimerAccuracySec", config_parse_sec, 0, &arg_default_timer_accuracy_usec },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_default_timeout_start_usec },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_default_timeout_stop_usec },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_default_restart_usec },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_default_start_limit_interval },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_default_start_limit_burst },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU] },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE] },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA] },
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE] },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS] },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultLimitSIGPENDING", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO] },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME] },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultCPUAccounting", config_parse_bool, 0, &arg_default_cpu_accounting },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "Manager", "DefaultBlockIOAccounting", config_parse_bool, 0, &arg_default_blockio_accounting },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering { "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_default_memory_accounting },
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering fn = arg_running_as == MANAGER_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? CONF_DIRS_NULSTR("systemd/system.conf") : CONF_DIRS_NULSTR("systemd/user.conf");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering config_parse_many(fn, conf_dirs_nulstr, "Manager\0",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering config_item_table_lookup, items, false, NULL);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poetteringstatic void manager_set_defaults(Manager *m) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->default_timer_accuracy_usec = arg_default_timer_accuracy_usec;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->default_std_output = arg_default_std_output;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->default_std_error = arg_default_std_error;
a5f035960006556beab51c42e6948985635e261aLennart Poettering m->default_timeout_start_usec = arg_default_timeout_start_usec;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->default_timeout_stop_usec = arg_default_timeout_stop_usec;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering m->default_restart_usec = arg_default_restart_usec;
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen m->default_start_limit_interval = arg_default_start_limit_interval;
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen m->default_start_limit_burst = arg_default_start_limit_burst;
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen m->default_cpu_accounting = arg_default_cpu_accounting;
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen m->default_blockio_accounting = arg_default_blockio_accounting;
86ad4cd709ced8daf2b75ab564dece1ce82ffed9Tom Gundersen m->default_memory_accounting = arg_default_memory_accounting;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering manager_set_default_rlimits(m, arg_default_rlimit);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering manager_environment_add(m, NULL, arg_default_environment);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering { "log-target", required_argument, NULL, ARG_LOG_TARGET },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "unit", required_argument, NULL, ARG_UNIT },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "no-pager", no_argument, NULL, ARG_NO_PAGER },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "version", no_argument, NULL, ARG_VERSION },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
72290734be81e83e6ef9520c07692f68095eb5b2Tom Gundersen while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_error("Failed to parse log level %s.", optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to parse log target %s.", optarg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_error("Failed to parse log color setting %s.", optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = log_show_location_from_string(optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to parse log location setting %s.", optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to parse default standard output setting %s.", optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to parse default standard error output setting %s.", optarg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering return log_error_errno(r, "Failed to set default unit %s: %m", optarg);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to parse dump core boolean %s.", optarg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_error("Failed to parse crash shell boolean %s.", optarg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering log_error("Failed to parse confirm spawn boolean %s.", optarg);
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering r = parse_show_status(optarg, &arg_show_status);
e1c959948c0e31d6997bcdfbabfbd077784b2baeLennart Poettering log_error("Failed to parse show status boolean %s.", optarg);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0 || fd < 0) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering log_error("Failed to parse deserialize option %s.", optarg);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return r < 0 ? r : -EINVAL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return log_error_errno(errno, "Failed to open serialization fd: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering /* Just to eat away the sysvinit kernel
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering * cmdline args without getopt() error
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering * messages that we'll parse in
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering * parse_proc_cmdline_word() or ignore. */
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering assert_not_reached("Unhandled option code.");
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering /* Hmm, when we aren't run as init system
556a22945fcc88ca27ae7ecc46c9bb2727e37895Lennart Poettering * let's complain about excess arguments */
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int help(void) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering "Starts up and maintains the system or user services.\n\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " -h --help Show this help\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --test Determine startup sequence, dump it and exit\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --no-pager Do not pipe output into a pager\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --dump-configuration-items Dump understood unit configuration items\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --unit=UNIT Set default unit\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --system Run a system instance, even if PID != 1\n"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering " --user Run a user instance\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --dump-core[=0|1] Dump core on crash\n"
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering " --crash-shell[=0|1] Run shell on crash\n"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering " --show-status[=0|1] Show status updates on the console during bootup\n"
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering " --log-target=TARGET Set log target (console, journal, kmsg, journal-or-kmsg, null)\n"
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering " --log-color[=0|1] Highlight important log messages\n"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering " --log-location[=0|1] Include code location in log messages\n"
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering " --default-standard-output= Set default standard output for services\n"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering " --default-standard-error= Set default standard error output for services\n",
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringstatic int version(void) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringstatic int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching_root) {
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering log_error_errno(r, "Failed to create serialization file: %m");
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering /* Make sure nothing is really destructed when we shut down */
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering log_error_errno(r, "Failed to allocate fd set: %m");
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering r = manager_serialize(m, f, fds, switching_root);
a407657425a3e47fd2b559cd3bc800f791303f63Lennart Poettering log_error_errno(r, "Failed to serialize state: %m");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering log_error_errno(errno, "Failed to rewind serialization fd: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error_errno(r, "Failed to disable O_CLOEXEC for serialization: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_error_errno(r, "Failed to disable O_CLOEXEC for serialization fds: %m");
if (!rl)
return log_oom();
static void test_mtab(void) {
static const char ok[] =
if (r == -ENOENT)
"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 filesystem 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 == -ENOENT) {
NULL);
if (r < 0 && r != -ENOENT)
static int write_container_id(void) {
if (isempty(c))
bool reexecute = false;
bool skip_setup = false;
bool loaded_policy = false;
bool arm_reboot_watchdog = false;
bool queue_default_job = false;
bool empty_etc = false;
#ifdef HAVE_SYSV_COMPAT
skip_setup = true;
skip_setup = false;
umask(0);
log_open();
if (in_initrd())
if (!skip_setup) {
goto finish;
} else if (ima_setup() < 0) {
goto finish;
goto finish;
goto finish;
if (!skip_setup) {
if (clock_is_localtime() > 0) {
int min;
} else if (!in_initrd()) {
log_open();
log_open();
goto finish;
r = initialize_join_controllers();
goto finish;
if (!skip_setup)
kmod_setup();
goto finish;
(void) reset_all_signal_handlers();
if (parse_config_file() < 0) {
goto finish;
goto finish;
geteuid() == 0) {
goto finish;
sd_booted() <= 0) {
goto finish;
running_in_chroot() > 0) {
goto finish;
skip_setup = true;
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())
* /etc/machine-id as flag file. This allows container
if (empty_etc)
_cleanup_free_ char *t;
if (arg_show_status > 0)
test_mtab();
test_usr();
goto finish;
goto finish;
if (arg_syscall_archs) {
goto finish;
if (empty_etc) {
r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, NULL, UNIT_FILE_PRESET_ENABLE_ONLY, false, NULL, 0);
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 = parse_config_file();
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;
pager_close();
m = manager_free(m);
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) {
(void) reset_all_signal_handlers();
(void) reset_signal_mask();
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_NULL:
case LOG_TARGET_CONSOLE:
if (log_get_show_color())
if (log_get_show_location())
watchdog_close(r < 0);
watchdog_close(true);
if (error_message)
freeze();
return retval;