main.c revision c72aadd1851096ea979f68b4e32cca71746ccdc4
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2010 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
36d9205d669bcdcb04fa730d1f3549a9fc9a9001Tom Gundersenstatic SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic bool arg_dump_core = true;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic bool arg_crash_shell = false;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic bool arg_confirm_spawn = false;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic bool arg_show_status = true;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic bool arg_switched_root = false;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic char ***arg_join_controllers = NULL;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
dc477e7385e8ab29efb8fadb72ec994077a105c6Lennart Poetteringstatic ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic char **arg_default_environment = NULL;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic uint64_t arg_capability_bounding_set_drop = 0;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic nsec_t arg_timer_slack_nsec = (nsec_t) -1;
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering /* Pass this on immediately, if this is not PID 1 */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* We want to wait for the core process, hence let's enable SIGCHLD */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering else if (pid == 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Enable default signal handler for core dump */
1b4f6e79ec51a57003896a0b605fba427b4a98d2Lennart Poettering /* Don't limit the core dump size */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Just to be sure... */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Raise the signal again */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering assert_not_reached("We shouldn't be here...");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Order things nicely. */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
28b9b7640603f88cb49f95609331fa5072715f15Lennart Poettering log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_info("Executing crash shell in 10s...");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering /* Let the kernel reap children for us */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Failed to fork off crash shell: %m");
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering else if (pid == 0) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poetteringstatic void install_crash_handler(void) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering /* If we are init, we connect stdin/stdout/stderr to /dev/null
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering * and make sure we don't have a controlling tty. */
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering /* We don't want to force text mode.
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering * plymouth may be showing pictures already from initrd. */
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_error("Failed to reset /dev/console: %s", strerror(-r));
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersenstatic int set_default_unit(const char *u) {
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersenstatic int parse_proc_cmdline_word(const char *word) {
5d27351f8546530cf779847b0b04b0172c09f9d0Tom Gundersen static const char * const rlmap[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (startswith(word, "rd.systemd.unit=")) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else if (startswith(word, "systemd.log_target=")) {
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen if (log_set_target_from_string(word + 19) < 0)
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen log_warning("Failed to parse log target %s. Ignoring.", word + 19);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else if (startswith(word, "systemd.log_level=")) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (log_set_max_level_from_string(word + 18) < 0)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_warning("Failed to parse log level %s. Ignoring.", word + 18);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else if (startswith(word, "systemd.log_color=")) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (log_show_color_from_string(word + 18) < 0)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else if (startswith(word, "systemd.log_location=")) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if (log_show_location_from_string(word + 21) < 0)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering } else if (startswith(word, "systemd.dump_core=")) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt } else if (startswith(word, "systemd.crash_shell=")) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering } else if (startswith(word, "systemd.confirm_spawn=")) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering } else if (startswith(word, "systemd.crash_chvt=")) {
d23a27a964748967e1ad20e86de869a753af555bTom Gundersen log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
c52a97b896c914e17ba5be73c0e806455fd9ad4dLennart Poettering } else if (startswith(word, "systemd.show_status=")) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else if (startswith(word, "systemd.default_standard_output=")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if ((r = exec_output_from_string(word + 32)) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (startswith(word, "systemd.default_standard_error=")) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if ((r = exec_output_from_string(word + 31)) < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
8bf52d3d17d364438191077d0750b8b80b5dc53aLennart Poettering } else if (startswith(word, "systemd.setenv=")) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (startswith(word, "systemd.") ||
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (in_initrd() && startswith(word, "rd.systemd."))) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering /* Ignore systemd.journald.xyz and friends */
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek if (c[strcspn(c, ".=")] != '.') {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering log_warning("Unknown kernel switch %s. Ignoring.", word);
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek "systemd.unit=UNIT Default unit to start\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "rd.systemd.unit=UNIT Default unit to start when run in initrd\n"
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering "systemd.dump_core=0|1 Dump core on crash\n"
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek "systemd.crash_shell=0|1 Run shell on crash\n"
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering "systemd.crash_chvt=N Change to VT #N on crash\n"
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering "systemd.show_status=0|1 Show status updates on the console during bootup\n"
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering "systemd.log_level=LEVEL Log level\n"
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek "systemd.log_color=0|1 Highlight important log messages\n"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering "systemd.log_location=0|1 Include code location in log messages\n"
7e8e0422aeb16f2a09a40546c61df753d10029b6Lennart Poettering "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek " Set default log output for services\n"
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek " Set default log error output for services\n"
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n");
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering /* SysV compatibility */
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek return set_default_unit(rlmap[i+1]);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek#define DEFINE_SETTER(name, func, descr) \
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen const char *filename, \
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen const char *section, \
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen const char *lvalue, \
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen const char *rvalue, \
9de3e3294065e8697ff10130b53f274319cdcf6fZbigniew Jędrzejewski-Szmek log_syntax(unit, LOG_ERR, filename, line, -r, \
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart PoetteringDEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart PoetteringDEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart PoetteringDEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart PoetteringDEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringstatic int config_parse_cpu_affinity2(const char *unit,
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering FOREACH_WORD_QUOTED(w, l, rvalue, state) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!(t = strndup(w, l)))
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_syntax(unit, LOG_ERR, filename, line, -r,
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering "Failed to parse CPU affinity '%s'", rvalue);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering log_warning_unit(unit, "Failed to set CPU affinity: %m");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic void strv_free_free(char ***l) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering for (i = l; *i; i++)
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poetteringstatic void free_join_controllers(void) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poetteringstatic int config_parse_join_controllers(const char *unit,
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering unsigned n = 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering FOREACH_WORD_QUOTED(w, length, rvalue, state) {
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek for (a = arg_join_controllers; *a; a++) {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmekstatic int parse_config_file(void) {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek const ConfigTableItem items[] = {
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek { "Manager", "LogLevel", config_parse_level2, 0, NULL },
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek { "Manager", "LogTarget", config_parse_target, 0, NULL },
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen { "Manager", "LogColor", config_parse_color, 0, NULL },
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen { "Manager", "LogLocation", config_parse_location, 0, NULL },
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek log_warning("Failed to open configuration file '%s': %m", fn);
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, false, NULL);
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen log_warning("Failed to parse configuration file: %s", strerror(-r));
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersenstatic int parse_proc_cmdline(void) {
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen /* Don't read /proc/cmdline if we are in a container, since
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen * that is only relevant for the host system */
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen r = read_one_line_file("/proc/cmdline", &line);
cb57dd41595adddb08095298bb1ed258c8ea4877Tom Gundersen log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersenstatic int parse_argv(int argc, char *argv[]) {
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "log-target", required_argument, NULL, ARG_LOG_TARGET },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "unit", required_argument, NULL, ARG_UNIT },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "system", no_argument, NULL, ARG_SYSTEM },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "introspect", optional_argument, NULL, ARG_INTROSPECT },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering if ((r = log_set_max_level_from_string(optarg)) < 0) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering log_error("Failed to parse log level %s.", optarg);
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering if ((r = log_set_target_from_string(optarg)) < 0) {
9c92ce6d67f88beb31dd6555d12ae3f632218a39Lennart Poettering log_error("Failed to parse log target %s.", optarg);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if ((r = log_show_color_from_string(optarg)) < 0) {
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering log_error("Failed to parse log color setting %s.", optarg);
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering if ((r = log_show_location_from_string(optarg)) < 0) {
2e276efc7b0398a3086629a52970bdd4ab7252f9Zbigniew Jędrzejewski-Szmek log_error("Failed to parse log location setting %s.", optarg);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if ((r = exec_output_from_string(optarg)) < 0) {
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering log_error("Failed to parse default standard output setting %s.", optarg);
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek if ((r = exec_output_from_string(optarg)) < 0) {
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek log_error("Failed to parse default standard error output setting %s.", optarg);
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering if ((r = set_default_unit(optarg)) < 0) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
946c70944ebdf428ffeb9991a7449edbd4011461Zbigniew Jędrzejewski-Szmek case ARG_DUMP_CONFIGURATION_ITEMS:
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek r = optarg ? parse_boolean(optarg) : 1;
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek log_error("Failed to parse dump core boolean %s.", optarg);
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek r = optarg ? parse_boolean(optarg) : 1;
0dae31d468b1a0e22d98921f7b0dbd92fd217167Zbigniew Jędrzejewski-Szmek log_error("Failed to parse crash shell boolean %s.", optarg);
abf126a355e2f2b62b6c51ab3bb37895d1e3eee7Tom Gundersen log_error("Failed to parse confirm spawn boolean %s.", optarg);
549c1a2564b56f2bb38f1203d59c747ea15817f3Tom Gundersen log_error("Failed to parse show status boolean %s.", optarg);
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering if (r < 0 || fd < 0) {
42cc2eebb01056beb7acd3ecfe8e533558237f84Lennart Poettering log_error("Failed to parse deserialize option %s.", optarg);
ff3d6560bead6879a2fed1bf99bfe8273b3723f1Zbigniew Jędrzejewski-Szmek return r < 0 ? r : -EINVAL;
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering log_error("Failed to open serialization fd: %m");
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek const char * const * i = NULL;
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek for (i = bus_interface_table; *i; i += 2)
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek if (!optarg || streq(i[0], optarg)) {
1bf968f36393666f2c57953b1748e6219c027deeTom Gundersen fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
7c6423e19136a7b7b6ef3fe06b94822e582dda27Tom Gundersen if (!i[0] && optarg)
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering log_error("Unknown interface %s.", optarg);
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek /* Just to eat away the sysvinit kernel
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek * cmdline args without getopt() error
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering * messages that we'll parse in
151226ab4bf276d60d51864330a99f886b923697Zbigniew Jędrzejewski-Szmek * parse_proc_cmdline_word() or ignore. */
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering /* Hmm, when we aren't run as init system
50f1e641a93cacfc693b0c3d300bee5df0c8c460Tom Gundersen * let's complain about excess arguments */
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen /* All /proc/cmdline arguments the kernel didn't
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen * understand it passed to us. We're not really
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen * interested in that usually since /proc/cmdline is
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen * more interesting and complete. With one exception:
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering * if we are run in a container /proc/cmdline is not
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen * relevant for the container, hence we rely on argv[]
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen * instead. */
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen if ((r = parse_proc_cmdline_word(*a)) < 0) {
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersenstatic int help(void) {
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen "Starts up and maintains the system or user services.\n\n"
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen " -h --help Show this help\n"
5d45a8808431987c370706d365fb0cc95cf03d52Tom Gundersen " --test Determine startup sequence, dump it and exit\n"
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek " --dump-configuration-items Dump understood unit configuration items\n"
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek " --introspect[=INTERFACE] Extract D-Bus interface data\n"
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek " --unit=UNIT Set default unit\n"
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering " --system Run a system instance, even if PID != 1\n"
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek " --user Run a user instance\n"
6af47493de0ef2b66d4c3fbcdd4a2e12fec4bfbaLennart Poettering " --dump-core[=0|1] Dump core on crash\n"
f5430a3ef308f3a102899fcaf7fbece757082f2aLennart Poettering " --crash-shell[=0|1] Run shell on crash\n"
d23a27a964748967e1ad20e86de869a753af555bTom Gundersen " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering " --show-status[=0|1] Show status updates on the console during bootup\n"
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
8db0d2f5c37e7e8f5bfce016cfdad7947a3ea939Zbigniew Jędrzejewski-Szmek " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering " --log-color[=0|1] Highlight important log messages\n"
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering " --log-location[=0|1] Include code location in log messages\n"
7b50eb2efa122200e39646c19a29abab302f7d24Lennart Poettering " --default-standard-output= Set default standard output for services\n"
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering " --default-standard-error= Set default standard error output for services\n",
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poetteringstatic int version(void) {
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poetteringstatic int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching_root) {
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering log_error("Failed to create serialization file: %s", strerror(-r));
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering /* Make sure nothing is really destructed when we shut down */
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering log_error("Failed to allocate fd set: %s", strerror(-r));
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering r = manager_serialize(m, f, fds, switching_root);
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering log_error("Failed to serialize state: %s", strerror(-r));
a8812dd7f161a3e459c1730ac92ff2bbc9986ff1Lennart Poettering log_error("Failed to rewind serialization fd: %m");
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poettering log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
2001c80560e3dae69e14fd994d3978c187af48b8Lennart Poetteringstatic int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering /* Save the original RLIMIT_NOFILE so that we can reset it
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering * later when transitioning from the initrd to the main
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering * systemd or suchlike. */
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering log_error("Reading RLIMIT_NOFILE failed: %m");
6f717d0817573a76c3e586eae02793d8b23a0581Lennart Poettering /* Make sure forked processes get the default kernel setting */
6f717d0817573a76c3e586eae02793d8b23a0581Lennart Poettering if (!arg_default_rlimit[RLIMIT_NOFILE]) {
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering rl = newdup(struct rlimit, saved_rlimit, 1);
6f717d0817573a76c3e586eae02793d8b23a0581Lennart Poettering /* Bump up the resource limit for ourselves substantially */
6f717d0817573a76c3e586eae02793d8b23a0581Lennart Poettering r = setrlimit_closest(RLIMIT_NOFILE, &nl);
8730bccfc59fe507bd3e0a3abcf411b497ac4f0eLennart Poettering log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
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 void test_cgroups(void) {
"Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
static int initialize_join_controllers(void) {
if (!arg_join_controllers)
return -ENOMEM;
return -ENOMEM;
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;
log_open();
if (in_initrd()) {
if (rd_timestamp) {
if (!skip_setup) {
goto finish;
if (ima_setup() < 0)
goto finish;
if (smack_setup() < 0)
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;
if (parse_proc_cmdline() < 0)
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;
log_close();
goto finish;
if (serialization)
#ifdef HAVE_SPLIT_USR
setsid();
umask(0);
log_open();
goto finish;
if (virtualization)
if (in_initrd())
locale_setup();
#ifdef HAVE_KMOD
kmod_setup();
test_mtab();
test_usr();
test_cgroups();
goto finish;
goto finish;
goto finish;
if (serialization) {
if (queue_default_job) {
goto finish;
goto finish;
goto finish;
if (r == -EPERM) {
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);
for (j = 0; j < RLIMIT_NLIMITS; j++)
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 (serialization) {
if (fds) {
if (switch_root_init) {
if (serialization)
if (fds)
if (shutdown_verb) {
const char * command_line[] = {
char **env_block;
watchdog_close(false);
char_array_0(e);
watchdog_close(true);
freeze();
return retval;