1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <dbus/dbus.h>
28 #include <sys/types.h>
34 #include <sys/prctl.h>
35 #include <sys/mount.h>
39 #include "load-fragment.h"
42 #include "conf-parser.h"
43 #include "bus-errors.h"
51 #include "path-util.h"
52 #include "switch-root.h"
54 #include "mount-setup.h"
55 #include "loopback-setup.h"
56 #include "kmod-setup.h"
57 #include "hostname-setup.h"
58 #include "machine-id-setup.h"
59 #include "locale-setup.h"
61 #include "selinux-setup.h"
62 #include "ima-setup.h"
68 ACTION_DUMP_CONFIGURATION_ITEMS,
70 } arg_action = ACTION_RUN;
72 static char *arg_default_unit = NULL;
73 static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
75 static bool arg_dump_core = true;
76 static bool arg_crash_shell = false;
77 static int arg_crash_chvt = -1;
78 static bool arg_confirm_spawn = false;
79 static bool arg_show_status = true;
80 #ifdef HAVE_SYSV_COMPAT
81 static bool arg_sysv_console = true;
83 static char **arg_default_controllers = NULL;
84 static char ***arg_join_controllers = NULL;
85 static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
86 static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
87 static usec_t arg_runtime_watchdog = 0;
88 static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
89 static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
91 static FILE* serialization = NULL;
93 static void nop_handler(int sig) {
96 _noreturn_ static void crash(int sig) {
99 log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
104 /* We want to wait for the core process, hence let's enable SIGCHLD */
106 sa.sa_handler = nop_handler;
107 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
108 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
110 if ((pid = fork()) < 0)
111 log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
116 /* Enable default signal handler for core dump */
118 sa.sa_handler = SIG_DFL;
119 assert_se(sigaction(sig, &sa, NULL) == 0);
121 /* Don't limit the core dump size */
123 rl.rlim_cur = RLIM_INFINITY;
124 rl.rlim_max = RLIM_INFINITY;
125 setrlimit(RLIMIT_CORE, &rl);
127 /* Just to be sure... */
128 assert_se(chdir("/") == 0);
130 /* Raise the signal again */
133 assert_not_reached("We shouldn't be here...");
140 /* Order things nicely. */
141 if ((r = wait_for_terminate(pid, &status)) < 0)
142 log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
143 else if (status.si_code != CLD_DUMPED)
144 log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
146 log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
151 chvt(arg_crash_chvt);
153 if (arg_crash_shell) {
157 log_info("Executing crash shell in 10s...");
160 /* Let the kernel reap children for us */
162 sa.sa_handler = SIG_IGN;
163 sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART;
164 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
166 if ((pid = fork()) < 0)
167 log_error("Failed to fork off crash shell: %s", strerror(errno));
171 if ((fd = acquire_terminal("/dev/console", false, true, true)) < 0)
172 log_error("Failed to acquire terminal: %s", strerror(-fd));
173 else if ((r = make_stdio(fd)) < 0)
174 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
176 execl("/bin/sh", "/bin/sh", NULL);
178 log_error("execl() failed: %s", strerror(errno));
182 log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
185 log_info("Freezing execution.");
189 static void install_crash_handler(void) {
194 sa.sa_handler = crash;
195 sa.sa_flags = SA_NODEFER;
197 sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
200 static int console_setup(bool do_reset) {
203 /* If we are init, we connect stdin/stdout/stderr to /dev/null
204 * and make sure we don't have a controlling tty. */
211 tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
213 log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
217 /* We don't want to force text mode.
218 * plymouth may be showing pictures already from initrd. */
219 r = reset_terminal_fd(tty_fd, false);
221 log_error("Failed to reset /dev/console: %s", strerror(-r));
223 close_nointr_nofail(tty_fd);
227 static int set_default_unit(const char *u) {
232 if (!(c = strdup(u)))
235 free(arg_default_unit);
236 arg_default_unit = c;
240 static int parse_proc_cmdline_word(const char *word) {
242 static const char * const rlmap[] = {
243 "emergency", SPECIAL_EMERGENCY_TARGET,
244 "-b", SPECIAL_EMERGENCY_TARGET,
245 "single", SPECIAL_RESCUE_TARGET,
246 "-s", SPECIAL_RESCUE_TARGET,
247 "s", SPECIAL_RESCUE_TARGET,
248 "S", SPECIAL_RESCUE_TARGET,
249 "1", SPECIAL_RESCUE_TARGET,
250 "2", SPECIAL_RUNLEVEL2_TARGET,
251 "3", SPECIAL_RUNLEVEL3_TARGET,
252 "4", SPECIAL_RUNLEVEL4_TARGET,
253 "5", SPECIAL_RUNLEVEL5_TARGET,
258 if (startswith(word, "systemd.unit="))
259 return set_default_unit(word + 13);
261 else if (startswith(word, "systemd.log_target=")) {
263 if (log_set_target_from_string(word + 19) < 0)
264 log_warning("Failed to parse log target %s. Ignoring.", word + 19);
266 } else if (startswith(word, "systemd.log_level=")) {
268 if (log_set_max_level_from_string(word + 18) < 0)
269 log_warning("Failed to parse log level %s. Ignoring.", word + 18);
271 } else if (startswith(word, "systemd.log_color=")) {
273 if (log_show_color_from_string(word + 18) < 0)
274 log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
276 } else if (startswith(word, "systemd.log_location=")) {
278 if (log_show_location_from_string(word + 21) < 0)
279 log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
281 } else if (startswith(word, "systemd.dump_core=")) {
284 if ((r = parse_boolean(word + 18)) < 0)
285 log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
289 } else if (startswith(word, "systemd.crash_shell=")) {
292 if ((r = parse_boolean(word + 20)) < 0)
293 log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
297 } else if (startswith(word, "systemd.confirm_spawn=")) {
300 if ((r = parse_boolean(word + 22)) < 0)
301 log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
303 arg_confirm_spawn = r;
305 } else if (startswith(word, "systemd.crash_chvt=")) {
308 if (safe_atoi(word + 19, &k) < 0)
309 log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
313 } else if (startswith(word, "systemd.show_status=")) {
316 if ((r = parse_boolean(word + 20)) < 0)
317 log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
320 } else if (startswith(word, "systemd.default_standard_output=")) {
323 if ((r = exec_output_from_string(word + 32)) < 0)
324 log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
326 arg_default_std_output = r;
327 } else if (startswith(word, "systemd.default_standard_error=")) {
330 if ((r = exec_output_from_string(word + 31)) < 0)
331 log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
333 arg_default_std_error = r;
334 } else if (startswith(word, "systemd.setenv=")) {
338 cenv = strdup(word + 15);
342 eq = strchr(cenv, '=');
346 log_warning("unsetenv failed %s. Ignoring.", strerror(errno));
349 r = setenv(cenv, eq + 1, 1);
351 log_warning("setenv failed %s. Ignoring.", strerror(errno));
354 #ifdef HAVE_SYSV_COMPAT
355 } else if (startswith(word, "systemd.sysv_console=")) {
358 if ((r = parse_boolean(word + 21)) < 0)
359 log_warning("Failed to parse SysV console switch %s. Ignoring.", word + 20);
361 arg_sysv_console = r;
364 } else if (startswith(word, "systemd.")) {
366 log_warning("Unknown kernel switch %s. Ignoring.", word);
368 log_info("Supported kernel switches:\n"
369 "systemd.unit=UNIT Default unit to start\n"
370 "systemd.dump_core=0|1 Dump core on crash\n"
371 "systemd.crash_shell=0|1 Run shell on crash\n"
372 "systemd.crash_chvt=N Change to VT #N on crash\n"
373 "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
374 "systemd.show_status=0|1 Show status updates on the console during bootup\n"
375 #ifdef HAVE_SYSV_COMPAT
376 "systemd.sysv_console=0|1 Connect output of SysV scripts to console\n"
378 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
380 "systemd.log_level=LEVEL Log level\n"
381 "systemd.log_color=0|1 Highlight important log messages\n"
382 "systemd.log_location=0|1 Include code location in log messages\n"
383 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
384 " Set default log output for services\n"
385 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
386 " Set default log error output for services\n");
388 } else if (streq(word, "quiet")) {
389 arg_show_status = false;
390 #ifdef HAVE_SYSV_COMPAT
391 arg_sysv_console = false;
396 /* SysV compatibility */
397 for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
398 if (streq(word, rlmap[i]))
399 return set_default_unit(rlmap[i+1]);
405 static int config_parse_level2(
406 const char *filename,
419 log_set_max_level_from_string(rvalue);
423 static int config_parse_target(
424 const char *filename,
437 log_set_target_from_string(rvalue);
441 static int config_parse_color(
442 const char *filename,
455 log_show_color_from_string(rvalue);
459 static int config_parse_location(
460 const char *filename,
473 log_show_location_from_string(rvalue);
477 static int config_parse_cpu_affinity2(
478 const char *filename,
497 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
502 if (!(t = strndup(w, l)))
505 r = safe_atou(t, &cpu);
509 if (!(c = cpu_set_malloc(&ncpus)))
512 if (r < 0 || cpu >= ncpus) {
513 log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
518 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
522 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
523 log_warning("Failed to set CPU affinity: %m");
531 static void strv_free_free(char ***l) {
543 static void free_join_controllers(void) {
544 if (!arg_join_controllers)
547 strv_free_free(arg_join_controllers);
548 arg_join_controllers = NULL;
551 static int config_parse_join_controllers(
552 const char *filename,
569 free_join_controllers();
571 FOREACH_WORD_QUOTED(w, length, rvalue, state) {
574 s = strndup(w, length);
578 l = strv_split(s, ",");
583 if (strv_length(l) <= 1) {
588 if (!arg_join_controllers) {
589 arg_join_controllers = new(char**, 2);
590 if (!arg_join_controllers) {
595 arg_join_controllers[0] = l;
596 arg_join_controllers[1] = NULL;
603 t = new0(char**, n+2);
611 for (a = arg_join_controllers; *a; a++) {
613 if (strv_overlap(*a, l)) {
616 c = strv_merge(*a, l);
639 t[n++] = strv_uniq(l);
641 strv_free_free(arg_join_controllers);
642 arg_join_controllers = t;
649 static int parse_config_file(void) {
651 const ConfigTableItem items[] = {
652 { "Manager", "LogLevel", config_parse_level2, 0, NULL },
653 { "Manager", "LogTarget", config_parse_target, 0, NULL },
654 { "Manager", "LogColor", config_parse_color, 0, NULL },
655 { "Manager", "LogLocation", config_parse_location, 0, NULL },
656 { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
657 { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
658 { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
659 #ifdef HAVE_SYSV_COMPAT
660 { "Manager", "SysVConsole", config_parse_bool, 0, &arg_sysv_console },
662 { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
663 { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
664 { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers },
665 { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
666 { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
667 { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
668 { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog },
669 { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog },
670 { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
671 { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
672 { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
673 { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
674 { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
675 { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
676 { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
677 { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
678 { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
679 { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
680 { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
681 { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
682 { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
683 { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
684 { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
685 { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
686 { NULL, NULL, NULL, 0, NULL }
693 fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
699 log_warning("Failed to open configuration file '%s': %m", fn);
703 r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
705 log_warning("Failed to parse configuration file: %s", strerror(-r));
712 static int parse_proc_cmdline(void) {
713 char *line, *w, *state;
717 /* Don't read /proc/cmdline if we are in a container, since
718 * that is only relevant for the host system */
719 if (detect_container(NULL) > 0)
722 if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
723 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
727 FOREACH_WORD_QUOTED(w, l, line, state) {
730 if (!(word = strndup(w, l))) {
735 r = parse_proc_cmdline_word(word);
749 static int parse_argv(int argc, char *argv[]) {
752 ARG_LOG_LEVEL = 0x100,
760 ARG_DUMP_CONFIGURATION_ITEMS,
769 ARG_DEFAULT_STD_OUTPUT,
770 ARG_DEFAULT_STD_ERROR
773 static const struct option options[] = {
774 { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
775 { "log-target", required_argument, NULL, ARG_LOG_TARGET },
776 { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
777 { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
778 { "unit", required_argument, NULL, ARG_UNIT },
779 { "system", no_argument, NULL, ARG_SYSTEM },
780 { "user", no_argument, NULL, ARG_USER },
781 { "test", no_argument, NULL, ARG_TEST },
782 { "help", no_argument, NULL, 'h' },
783 { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
784 { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
785 { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
786 { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
787 { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
788 #ifdef HAVE_SYSV_COMPAT
789 { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE },
791 { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
792 { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
793 { "introspect", optional_argument, NULL, ARG_INTROSPECT },
794 { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
795 { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
807 while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
812 if ((r = log_set_max_level_from_string(optarg)) < 0) {
813 log_error("Failed to parse log level %s.", optarg);
821 if ((r = log_set_target_from_string(optarg)) < 0) {
822 log_error("Failed to parse log target %s.", optarg);
831 if ((r = log_show_color_from_string(optarg)) < 0) {
832 log_error("Failed to parse log color setting %s.", optarg);
836 log_show_color(true);
840 case ARG_LOG_LOCATION:
843 if ((r = log_show_location_from_string(optarg)) < 0) {
844 log_error("Failed to parse log location setting %s.", optarg);
848 log_show_location(true);
852 case ARG_DEFAULT_STD_OUTPUT:
854 if ((r = exec_output_from_string(optarg)) < 0) {
855 log_error("Failed to parse default standard output setting %s.", optarg);
858 arg_default_std_output = r;
861 case ARG_DEFAULT_STD_ERROR:
863 if ((r = exec_output_from_string(optarg)) < 0) {
864 log_error("Failed to parse default standard error output setting %s.", optarg);
867 arg_default_std_error = r;
872 if ((r = set_default_unit(optarg)) < 0) {
873 log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
880 arg_running_as = MANAGER_SYSTEM;
884 arg_running_as = MANAGER_USER;
888 arg_action = ACTION_TEST;
891 case ARG_DUMP_CONFIGURATION_ITEMS:
892 arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
896 r = optarg ? parse_boolean(optarg) : 1;
898 log_error("Failed to parse dump core boolean %s.", optarg);
904 case ARG_CRASH_SHELL:
905 r = optarg ? parse_boolean(optarg) : 1;
907 log_error("Failed to parse crash shell boolean %s.", optarg);
913 case ARG_CONFIRM_SPAWN:
914 r = optarg ? parse_boolean(optarg) : 1;
916 log_error("Failed to parse confirm spawn boolean %s.", optarg);
919 arg_confirm_spawn = r;
922 case ARG_SHOW_STATUS:
923 r = optarg ? parse_boolean(optarg) : 1;
925 log_error("Failed to parse show status boolean %s.", optarg);
931 #ifdef HAVE_SYSV_COMPAT
932 case ARG_SYSV_CONSOLE:
933 r = optarg ? parse_boolean(optarg) : 1;
935 log_error("Failed to parse SysV console boolean %s.", optarg);
938 arg_sysv_console = r;
942 case ARG_DESERIALIZE: {
946 if ((r = safe_atoi(optarg, &fd)) < 0 || fd < 0) {
947 log_error("Failed to parse deserialize option %s.", optarg);
951 if (!(f = fdopen(fd, "r"))) {
952 log_error("Failed to open serialization fd: %m");
957 fclose(serialization);
964 case ARG_SWITCHED_ROOT:
965 /* Nothing special yet */
968 case ARG_INTROSPECT: {
969 const char * const * i = NULL;
971 for (i = bus_interface_table; *i; i += 2)
972 if (!optarg || streq(i[0], optarg)) {
973 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
976 fputs("</node>\n", stdout);
983 log_error("Unknown interface %s.", optarg);
985 arg_action = ACTION_DONE;
990 arg_action = ACTION_HELP;
994 log_set_max_level(LOG_DEBUG);
1000 /* Just to eat away the sysvinit kernel
1001 * cmdline args without getopt() error
1002 * messages that we'll parse in
1003 * parse_proc_cmdline_word() or ignore. */
1007 if (getpid() != 1) {
1008 log_error("Unknown option code %c", c);
1015 if (optind < argc && getpid() != 1) {
1016 /* Hmm, when we aren't run as init system
1017 * let's complain about excess arguments */
1019 log_error("Excess arguments.");
1023 if (detect_container(NULL) > 0) {
1026 /* All /proc/cmdline arguments the kernel didn't
1027 * understand it passed to us. We're not really
1028 * interested in that usually since /proc/cmdline is
1029 * more interesting and complete. With one exception:
1030 * if we are run in a container /proc/cmdline is not
1031 * relevant for the container, hence we rely on argv[]
1034 for (a = argv; a < argv + argc; a++)
1035 if ((r = parse_proc_cmdline_word(*a)) < 0)
1042 static int help(void) {
1044 printf("%s [OPTIONS...]\n\n"
1045 "Starts up and maintains the system or user services.\n\n"
1046 " -h --help Show this help\n"
1047 " --test Determine startup sequence, dump it and exit\n"
1048 " --dump-configuration-items Dump understood unit configuration items\n"
1049 " --introspect[=INTERFACE] Extract D-Bus interface data\n"
1050 " --unit=UNIT Set default unit\n"
1051 " --system Run a system instance, even if PID != 1\n"
1052 " --user Run a user instance\n"
1053 " --dump-core[=0|1] Dump core on crash\n"
1054 " --crash-shell[=0|1] Run shell on crash\n"
1055 " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
1056 " --show-status[=0|1] Show status updates on the console during bootup\n"
1057 #ifdef HAVE_SYSV_COMPAT
1058 " --sysv-console[=0|1] Connect output of SysV scripts to console\n"
1060 " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
1061 " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
1062 " --log-color[=0|1] Highlight important log messages\n"
1063 " --log-location[=0|1] Include code location in log messages\n"
1064 " --default-standard-output= Set default standard output for services\n"
1065 " --default-standard-error= Set default standard error output for services\n",
1066 program_invocation_short_name);
1071 static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds) {
1080 /* Make sure nothing is really destructed when we shut down */
1083 if ((r = manager_open_serialization(m, &f)) < 0) {
1084 log_error("Failed to create serialization file: %s", strerror(-r));
1088 if (!(fds = fdset_new())) {
1090 log_error("Failed to allocate fd set: %s", strerror(-r));
1094 if ((r = manager_serialize(m, f, fds)) < 0) {
1095 log_error("Failed to serialize state: %s", strerror(-r));
1099 if (fseeko(f, 0, SEEK_SET) < 0) {
1100 log_error("Failed to rewind serialization fd: %m");
1104 if ((r = fd_cloexec(fileno(f), false)) < 0) {
1105 log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
1109 if ((r = fdset_cloexec(fds, false)) < 0) {
1110 log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
1128 static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
1130 unsigned long long a, b;
1134 e = getenv("RD_TIMESTAMP");
1138 if (sscanf(e, "%llu %llu", &a, &b) != 2)
1141 t->realtime = (usec_t) a;
1142 t->monotonic = (usec_t) b;
1147 static void test_mtab(void) {
1150 /* Check that /etc/mtab is a symlink */
1152 if (readlink_malloc("/etc/mtab", &p) >= 0) {
1155 b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
1162 log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
1163 "This is not supported anymore. "
1164 "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
1167 static void test_usr(void) {
1169 /* Check that /usr is not a separate fs */
1171 if (dir_is_empty("/usr") <= 0)
1174 log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
1175 "Some things will probably break (sometimes even silently) in mysterious ways. "
1176 "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
1179 static void test_cgroups(void) {
1181 if (access("/proc/cgroups", F_OK) >= 0)
1184 log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
1185 "Systems without control groups are not supported. "
1186 "We will now sleep for 10s, and then continue boot-up. "
1187 "Expect breakage and please do not file bugs. "
1188 "Instead fix your kernel and enable CONFIG_CGROUPS. "
1189 "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
1194 int main(int argc, char *argv[]) {
1196 int r, retval = EXIT_FAILURE;
1197 usec_t before_startup, after_startup;
1198 char timespan[FORMAT_TIMESPAN_MAX];
1200 bool reexecute = false;
1201 const char *shutdown_verb = NULL;
1202 dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
1203 static char systemd[] = "systemd";
1204 bool skip_setup = false;
1206 bool loaded_policy = false;
1207 bool arm_reboot_watchdog = false;
1208 char *switch_root_dir = NULL, *switch_root_init = NULL;
1210 #ifdef HAVE_SYSV_COMPAT
1211 if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
1212 /* This is compatibility support for SysV, where
1213 * calling init as a user is identical to telinit. */
1216 execv(SYSTEMCTL_BINARY_PATH, argv);
1217 log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
1222 /* Determine if this is a reexecution or normal bootup. We do
1223 * the full command line parsing much later, so let's just
1224 * have a quick peek here. */
1225 for (j = 1; j < argc; j++)
1226 if (streq(argv[j], "--deserialize")) {
1231 /* If we have switched root, do all the special setup
1233 for (j = 1; j < argc; j++)
1234 if (streq(argv[j], "--switched-root")) {
1239 /* If we get started via the /sbin/init symlink then we are
1240 called 'init'. After a subsequent reexecution we are then
1241 called 'systemd'. That is confusing, hence let's call us
1242 systemd right-away. */
1243 program_invocation_short_name = systemd;
1244 prctl(PR_SET_NAME, systemd);
1249 log_show_color(isatty(STDERR_FILENO) > 0);
1250 log_show_location(false);
1251 log_set_max_level(LOG_INFO);
1253 if (getpid() == 1) {
1255 char *rd_timestamp = NULL;
1257 dual_timestamp_get(&initrd_timestamp);
1258 asprintf(&rd_timestamp, "%llu %llu",
1259 (unsigned long long) initrd_timestamp.realtime,
1260 (unsigned long long) initrd_timestamp.monotonic);
1262 setenv("RD_TIMESTAMP", rd_timestamp, 1);
1267 arg_running_as = MANAGER_SYSTEM;
1268 log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG);
1271 if (selinux_setup(&loaded_policy) < 0)
1273 if (ima_setup() < 0)
1279 if (label_init(NULL) < 0)
1283 if (hwclock_is_localtime() > 0) {
1286 r = hwclock_apply_localtime_delta(&min);
1288 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
1290 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
1294 arg_running_as = MANAGER_USER;
1295 log_set_target(LOG_TARGET_AUTO);
1299 /* Initialize default unit */
1300 if (set_default_unit(SPECIAL_DEFAULT_TARGET) < 0)
1303 /* By default, mount "cpu" and "cpuacct" together */
1304 arg_join_controllers = new(char**, 2);
1305 if (!arg_join_controllers)
1308 arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
1309 arg_join_controllers[1] = NULL;
1311 if (!arg_join_controllers[0])
1314 /* Mount /proc, /sys and friends, so that /proc/cmdline and
1315 * /proc/$PID/fd is available. */
1316 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1317 r = mount_setup(loaded_policy);
1322 /* Reset all signal handlers. */
1323 assert_se(reset_all_signal_handlers() == 0);
1325 /* If we are init, we can block sigkill. Yay. */
1326 ignore_signals(SIGNALS_IGNORE, -1);
1328 if (parse_config_file() < 0)
1331 if (arg_running_as == MANAGER_SYSTEM)
1332 if (parse_proc_cmdline() < 0)
1335 log_parse_environment();
1337 if (parse_argv(argc, argv) < 0)
1340 if (arg_action == ACTION_TEST && geteuid() == 0) {
1341 log_error("Don't run test mode as root.");
1345 if (arg_running_as == MANAGER_SYSTEM &&
1346 arg_action == ACTION_RUN &&
1347 running_in_chroot() > 0) {
1348 log_error("Cannot be run in a chroot() environment.");
1352 if (arg_action == ACTION_HELP) {
1355 } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
1356 unit_dump_config_items(stdout);
1357 retval = EXIT_SUCCESS;
1359 } else if (arg_action == ACTION_DONE) {
1360 retval = EXIT_SUCCESS;
1364 assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
1366 /* Close logging fds, in order not to confuse fdset below */
1369 /* Remember open file descriptors for later deserialization */
1370 if (serialization) {
1371 r = fdset_new_fill(&fds);
1373 log_error("Failed to allocate fd set: %s", strerror(-r));
1377 assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
1379 close_all_fds(NULL, 0);
1381 /* Set up PATH unless it is already set */
1383 #ifdef HAVE_SPLIT_USR
1384 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
1386 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
1388 arg_running_as == MANAGER_SYSTEM);
1390 if (arg_running_as == MANAGER_SYSTEM) {
1391 /* Parse the data passed to us. We leave this
1392 * variables set, but the manager later on will not
1393 * pass them on to our children. */
1395 parse_initrd_timestamp(&initrd_timestamp);
1397 /* Unset some environment variables passed in from the
1398 * kernel that don't really make sense for us. */
1402 /* When we are invoked by a shell, these might be set,
1403 * but make little sense to pass on */
1408 /* When we are invoked by a chroot-like tool such as
1409 * nspawn, these might be set, but make little sense
1412 unsetenv("LOGNAME");
1414 /* All other variables are left as is, so that clients
1415 * can still read them via /proc/1/environ */
1418 /* Move out of the way, so that we won't block unmounts */
1419 assert_se(chdir("/") == 0);
1421 if (arg_running_as == MANAGER_SYSTEM) {
1422 /* Become a session leader if we aren't one yet. */
1425 /* Disable the umask logic */
1429 /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
1430 dbus_connection_set_change_sigpipe(FALSE);
1432 /* Reset the console, but only if this is really init and we
1433 * are freshly booted */
1434 if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) {
1435 console_setup(getpid() == 1 && !skip_setup);
1439 /* Open the logging devices, if possible and necessary */
1442 /* Make sure we leave a core dump without panicing the
1445 install_crash_handler();
1447 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1448 r = mount_cgroup_controllers(arg_join_controllers);
1453 log_full(arg_running_as == MANAGER_SYSTEM ? LOG_INFO : LOG_DEBUG,
1454 PACKAGE_STRING " running in %s mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")", manager_running_as_to_string(arg_running_as));
1456 if (arg_running_as == MANAGER_SYSTEM && !skip_setup) {
1459 if (arg_show_status || plymouth_running())
1472 if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0)
1473 watchdog_set_timeout(&arg_runtime_watchdog);
1475 r = manager_new(arg_running_as, &m);
1477 log_error("Failed to allocate manager object: %s", strerror(-r));
1481 m->confirm_spawn = arg_confirm_spawn;
1482 #ifdef HAVE_SYSV_COMPAT
1483 m->sysv_console = arg_sysv_console;
1485 m->default_std_output = arg_default_std_output;
1486 m->default_std_error = arg_default_std_error;
1487 m->runtime_watchdog = arg_runtime_watchdog;
1488 m->shutdown_watchdog = arg_shutdown_watchdog;
1490 manager_set_default_rlimits(m, arg_default_rlimit);
1492 if (dual_timestamp_is_set(&initrd_timestamp))
1493 m->initrd_timestamp = initrd_timestamp;
1495 if (arg_default_controllers)
1496 manager_set_default_controllers(m, arg_default_controllers);
1498 manager_set_show_status(m, arg_show_status);
1500 before_startup = now(CLOCK_MONOTONIC);
1502 r = manager_startup(m, serialization, fds);
1504 log_error("Failed to fully start up daemon: %s", strerror(-r));
1507 /* This will close all file descriptors that were opened, but
1508 * not claimed by any unit. */
1514 if (serialization) {
1515 fclose(serialization);
1516 serialization = NULL;
1519 Unit *target = NULL;
1520 Job *default_unit_job;
1522 dbus_error_init(&error);
1524 log_debug("Activating default unit: %s", arg_default_unit);
1526 r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
1528 log_error("Failed to load default target: %s", bus_error(&error, r));
1529 dbus_error_free(&error);
1530 } else if (target->load_state == UNIT_ERROR)
1531 log_error("Failed to load default target: %s", strerror(-target->load_error));
1532 else if (target->load_state == UNIT_MASKED)
1533 log_error("Default target masked.");
1535 if (!target || target->load_state != UNIT_LOADED) {
1536 log_info("Trying to load rescue target...");
1538 r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
1540 log_error("Failed to load rescue target: %s", bus_error(&error, r));
1541 dbus_error_free(&error);
1543 } else if (target->load_state == UNIT_ERROR) {
1544 log_error("Failed to load rescue target: %s", strerror(-target->load_error));
1546 } else if (target->load_state == UNIT_MASKED) {
1547 log_error("Rescue target masked.");
1552 assert(target->load_state == UNIT_LOADED);
1554 if (arg_action == ACTION_TEST) {
1555 printf("-> By units:\n");
1556 manager_dump_units(m, stdout, "\t");
1559 r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
1561 log_error("Failed to start default target: %s", bus_error(&error, r));
1562 dbus_error_free(&error);
1565 m->default_unit_job_id = default_unit_job->id;
1567 after_startup = now(CLOCK_MONOTONIC);
1568 log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
1569 "Loaded units and determined initial transaction in %s.",
1570 format_timespan(timespan, sizeof(timespan), after_startup - before_startup));
1572 if (arg_action == ACTION_TEST) {
1573 printf("-> By jobs:\n");
1574 manager_dump_jobs(m, stdout, "\t");
1575 retval = EXIT_SUCCESS;
1581 r = manager_loop(m);
1583 log_error("Failed to run mainloop: %s", strerror(-r));
1587 switch (m->exit_code) {
1590 retval = EXIT_SUCCESS;
1594 case MANAGER_RELOAD:
1595 log_info("Reloading.");
1596 r = manager_reload(m);
1598 log_error("Failed to reload: %s", strerror(-r));
1601 case MANAGER_REEXECUTE:
1603 if (prepare_reexecute(m, &serialization, &fds) < 0)
1607 log_notice("Reexecuting.");
1610 case MANAGER_SWITCH_ROOT:
1611 /* Steal the switch root parameters */
1612 switch_root_dir = m->switch_root;
1613 switch_root_init = m->switch_root_init;
1614 m->switch_root = m->switch_root_init = NULL;
1616 if (!switch_root_init)
1617 if (prepare_reexecute(m, &serialization, &fds) < 0)
1621 log_notice("Switching root.");
1624 case MANAGER_REBOOT:
1625 case MANAGER_POWEROFF:
1627 case MANAGER_KEXEC: {
1628 static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
1629 [MANAGER_REBOOT] = "reboot",
1630 [MANAGER_POWEROFF] = "poweroff",
1631 [MANAGER_HALT] = "halt",
1632 [MANAGER_KEXEC] = "kexec"
1635 assert_se(shutdown_verb = table[m->exit_code]);
1636 arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
1638 log_notice("Shutting down.");
1643 assert_not_reached("Unknown exit code.");
1651 for (j = 0; j < RLIMIT_NLIMITS; j++)
1652 free (arg_default_rlimit[j]);
1654 free(arg_default_unit);
1655 strv_free(arg_default_controllers);
1656 free_join_controllers();
1663 unsigned i, args_size;
1665 /* Close and disarm the watchdog, so that the new
1666 * instance can reinitialize it, but doesn't get
1667 * rebooted while we do that */
1668 watchdog_close(true);
1670 if (switch_root_dir) {
1671 r = switch_root(switch_root_dir);
1673 log_error("Failed to switch root, ignoring: %s", strerror(-r));
1676 args_size = MAX(6, argc+1);
1677 args = newa(const char*, args_size);
1679 if (!switch_root_init) {
1682 /* First try to spawn ourselves with the right
1683 * path, and with full serialization. We do
1684 * this only if the user didn't specify an
1685 * explicit init to spawn. */
1687 assert(serialization);
1690 snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
1694 args[i++] = SYSTEMD_BINARY_PATH;
1695 if (switch_root_dir)
1696 args[i++] = "--switched-root";
1697 args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
1698 args[i++] = "--deserialize";
1702 assert(i <= args_size);
1703 execv(args[0], (char* const*) args);
1706 /* Try the fallback, if there is any, without any
1707 * serialization. We pass the original argv[] and
1708 * envp[]. (Well, modulo the ordering changes due to
1709 * getopt() in argv[], and some cleanups in envp[],
1710 * but let's hope that doesn't matter.) */
1712 if (serialization) {
1713 fclose(serialization);
1714 serialization = NULL;
1722 for (j = 1, i = 1; j < argc; j++)
1723 args[i++] = argv[j];
1725 assert(i <= args_size);
1727 if (switch_root_init) {
1728 args[0] = switch_root_init;
1729 execv(args[0], (char* const*) args);
1730 log_warning("Failed to execute configured init, trying fallback: %m");
1733 args[0] = "/sbin/init";
1734 execv(args[0], (char* const*) args);
1736 log_warning("Failed to execute /sbin/init, trying fallback: %m");
1738 args[0] = "/bin/sh";
1740 execv(args[0], (char* const*) args);
1741 log_error("Failed to execute /bin/sh, giving up: %m");
1745 fclose(serialization);
1750 if (shutdown_verb) {
1751 const char * command_line[] = {
1752 SYSTEMD_SHUTDOWN_BINARY_PATH,
1758 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
1761 /* If we reboot let's set the shutdown
1762 * watchdog and tell the shutdown binary to
1763 * repeatedly ping it */
1764 watchdog_set_timeout(&arg_shutdown_watchdog);
1765 watchdog_close(false);
1767 /* Tell the binary how often to ping */
1768 snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
1771 env_block = strv_append(environ, e);
1773 env_block = strv_copy(environ);
1774 watchdog_close(true);
1777 execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
1779 log_error("Failed to execute shutdown binary, freezing: %m");