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 "dbus-common.h"
51 #include "path-util.h"
52 #include "switch-root.h"
53 #include "capability.h"
57 #include "sd-daemon.h"
58 #include "sd-messages.h"
60 #include "mount-setup.h"
61 #include "loopback-setup.h"
63 #include "kmod-setup.h"
65 #include "hostname-setup.h"
66 #include "machine-id-setup.h"
67 #include "locale-setup.h"
68 #include "selinux-setup.h"
69 #include "ima-setup.h"
71 #include "smack-setup.h"
78 ACTION_DUMP_CONFIGURATION_ITEMS,
80 } arg_action = ACTION_RUN;
82 static char *arg_default_unit = NULL;
83 static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
85 static bool arg_dump_core = true;
86 static bool arg_crash_shell = false;
87 static int arg_crash_chvt = -1;
88 static bool arg_confirm_spawn = false;
89 static bool arg_show_status = true;
90 static bool arg_switched_root = false;
91 static char **arg_default_controllers = NULL;
92 static char ***arg_join_controllers = NULL;
93 static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
94 static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
95 static usec_t arg_runtime_watchdog = 0;
96 static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
97 static char **arg_default_environment = NULL;
98 static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
99 static uint64_t arg_capability_bounding_set_drop = 0;
100 static nsec_t arg_timer_slack_nsec = (nsec_t) -1;
102 static FILE* serialization = NULL;
104 static void nop_handler(int sig) {
107 _noreturn_ static void crash(int sig) {
110 /* Pass this on immediately, if this is not PID 1 */
112 else if (!arg_dump_core)
113 log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
115 struct sigaction sa = {
116 .sa_handler = nop_handler,
117 .sa_flags = SA_NOCLDSTOP|SA_RESTART,
121 /* We want to wait for the core process, hence let's enable SIGCHLD */
122 sigaction(SIGCHLD, &sa, NULL);
126 log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
129 struct rlimit rl = {};
131 /* Enable default signal handler for core dump */
133 sa.sa_handler = SIG_DFL;
134 sigaction(sig, &sa, NULL);
136 /* Don't limit the core dump size */
137 rl.rlim_cur = RLIM_INFINITY;
138 rl.rlim_max = RLIM_INFINITY;
139 setrlimit(RLIMIT_CORE, &rl);
141 /* Just to be sure... */
144 /* Raise the signal again */
147 assert_not_reached("We shouldn't be here...");
154 /* Order things nicely. */
155 r = wait_for_terminate(pid, &status);
157 log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
158 else if (status.si_code != CLD_DUMPED)
159 log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
161 log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
166 chvt(arg_crash_chvt);
168 if (arg_crash_shell) {
169 struct sigaction sa = {
170 .sa_handler = SIG_IGN,
171 .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
175 log_info("Executing crash shell in 10s...");
178 /* Let the kernel reap children for us */
179 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
183 log_error("Failed to fork off crash shell: %m");
185 make_console_stdio();
186 execl("/bin/sh", "/bin/sh", NULL);
188 log_error("execl() failed: %m");
192 log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
195 log_info("Freezing execution.");
199 static void install_crash_handler(void) {
200 struct sigaction sa = {
202 .sa_flags = SA_NODEFER,
205 sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
208 static int console_setup(bool do_reset) {
211 /* If we are init, we connect stdin/stdout/stderr to /dev/null
212 * and make sure we don't have a controlling tty. */
219 tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
221 log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
225 /* We don't want to force text mode.
226 * plymouth may be showing pictures already from initrd. */
227 r = reset_terminal_fd(tty_fd, false);
229 log_error("Failed to reset /dev/console: %s", strerror(-r));
231 close_nointr_nofail(tty_fd);
235 static int set_default_unit(const char *u) {
244 free(arg_default_unit);
245 arg_default_unit = c;
250 static int parse_proc_cmdline_word(const char *word) {
252 static const char * const rlmap[] = {
253 "emergency", SPECIAL_EMERGENCY_TARGET,
254 "-b", SPECIAL_EMERGENCY_TARGET,
255 "single", SPECIAL_RESCUE_TARGET,
256 "-s", SPECIAL_RESCUE_TARGET,
257 "s", SPECIAL_RESCUE_TARGET,
258 "S", SPECIAL_RESCUE_TARGET,
259 "1", SPECIAL_RESCUE_TARGET,
260 "2", SPECIAL_RUNLEVEL2_TARGET,
261 "3", SPECIAL_RUNLEVEL3_TARGET,
262 "4", SPECIAL_RUNLEVEL4_TARGET,
263 "5", SPECIAL_RUNLEVEL5_TARGET,
268 if (startswith(word, "systemd.unit=")) {
271 return set_default_unit(word + 13);
273 } else if (startswith(word, "rd.systemd.unit=")) {
276 return set_default_unit(word + 16);
278 } else if (startswith(word, "systemd.log_target=")) {
280 if (log_set_target_from_string(word + 19) < 0)
281 log_warning("Failed to parse log target %s. Ignoring.", word + 19);
283 } else if (startswith(word, "systemd.log_level=")) {
285 if (log_set_max_level_from_string(word + 18) < 0)
286 log_warning("Failed to parse log level %s. Ignoring.", word + 18);
288 } else if (startswith(word, "systemd.log_color=")) {
290 if (log_show_color_from_string(word + 18) < 0)
291 log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
293 } else if (startswith(word, "systemd.log_location=")) {
295 if (log_show_location_from_string(word + 21) < 0)
296 log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
298 } else if (startswith(word, "systemd.dump_core=")) {
301 if ((r = parse_boolean(word + 18)) < 0)
302 log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
306 } else if (startswith(word, "systemd.crash_shell=")) {
309 if ((r = parse_boolean(word + 20)) < 0)
310 log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
314 } else if (startswith(word, "systemd.confirm_spawn=")) {
317 if ((r = parse_boolean(word + 22)) < 0)
318 log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
320 arg_confirm_spawn = r;
322 } else if (startswith(word, "systemd.crash_chvt=")) {
325 if (safe_atoi(word + 19, &k) < 0)
326 log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
330 } else if (startswith(word, "systemd.show_status=")) {
333 if ((r = parse_boolean(word + 20)) < 0)
334 log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
337 } else if (startswith(word, "systemd.default_standard_output=")) {
340 if ((r = exec_output_from_string(word + 32)) < 0)
341 log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
343 arg_default_std_output = r;
344 } else if (startswith(word, "systemd.default_standard_error=")) {
347 if ((r = exec_output_from_string(word + 31)) < 0)
348 log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
350 arg_default_std_error = r;
351 } else if (startswith(word, "systemd.setenv=")) {
352 _cleanup_free_ char *cenv = NULL;
356 cenv = strdup(word + 15);
360 eq = strchr(cenv, '=');
362 if (!env_name_is_valid(cenv))
363 log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
367 log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv);
370 if (!env_assignment_is_valid(cenv))
371 log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv);
374 r = setenv(cenv, eq + 1, 1);
376 log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1);
380 } else if (startswith(word, "systemd.") ||
381 (in_initrd() && startswith(word, "rd.systemd."))) {
385 /* Ignore systemd.journald.xyz and friends */
387 if (startswith(c, "rd."))
389 if (startswith(c, "systemd."))
391 if (c[strcspn(c, ".=")] != '.') {
393 log_warning("Unknown kernel switch %s. Ignoring.", word);
395 log_info("Supported kernel switches:\n"
396 "systemd.unit=UNIT Default unit to start\n"
397 "rd.systemd.unit=UNIT Default unit to start when run in initrd\n"
398 "systemd.dump_core=0|1 Dump core on crash\n"
399 "systemd.crash_shell=0|1 Run shell on crash\n"
400 "systemd.crash_chvt=N Change to VT #N on crash\n"
401 "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
402 "systemd.show_status=0|1 Show status updates on the console during bootup\n"
403 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
405 "systemd.log_level=LEVEL Log level\n"
406 "systemd.log_color=0|1 Highlight important log messages\n"
407 "systemd.log_location=0|1 Include code location in log messages\n"
408 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
409 " Set default log output for services\n"
410 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
411 " Set default log error output for services\n"
412 "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n");
415 } else if (streq(word, "quiet"))
416 arg_show_status = false;
417 else if (streq(word, "debug"))
418 log_set_max_level(LOG_DEBUG);
419 else if (!in_initrd()) {
422 /* SysV compatibility */
423 for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
424 if (streq(word, rlmap[i]))
425 return set_default_unit(rlmap[i+1]);
431 #define DEFINE_SETTER(name, func, descr) \
432 static int name(const char *unit, \
433 const char *filename, \
435 const char *section, \
436 const char *lvalue, \
438 const char *rvalue, \
450 log_syntax(unit, LOG_ERR, filename, line, -r, \
451 "Invalid " descr "'%s': %s", \
452 rvalue, strerror(-r)); \
457 DEFINE_SETTER(config_parse_level2, log_set_max_level_from_string, "log level")
458 DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
459 DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
460 DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
463 static int config_parse_cpu_affinity2(const char *unit,
464 const char *filename,
483 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
488 if (!(t = strndup(w, l)))
491 r = safe_atou(t, &cpu);
495 if (!(c = cpu_set_malloc(&ncpus)))
498 if (r < 0 || cpu >= ncpus) {
499 log_syntax(unit, LOG_ERR, filename, line, -r,
500 "Failed to parse CPU affinity '%s'", rvalue);
505 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
509 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
510 log_warning_unit(unit, "Failed to set CPU affinity: %m");
518 static void strv_free_free(char ***l) {
530 static void free_join_controllers(void) {
531 strv_free_free(arg_join_controllers);
532 arg_join_controllers = NULL;
535 static int config_parse_join_controllers(const char *unit,
536 const char *filename,
553 free_join_controllers();
555 FOREACH_WORD_QUOTED(w, length, rvalue, state) {
558 s = strndup(w, length);
562 l = strv_split(s, ",");
567 if (strv_length(l) <= 1) {
572 if (!arg_join_controllers) {
573 arg_join_controllers = new(char**, 2);
574 if (!arg_join_controllers) {
579 arg_join_controllers[0] = l;
580 arg_join_controllers[1] = NULL;
587 t = new0(char**, n+2);
595 for (a = arg_join_controllers; *a; a++) {
597 if (strv_overlap(*a, l)) {
600 c = strv_merge(*a, l);
623 t[n++] = strv_uniq(l);
625 strv_free_free(arg_join_controllers);
626 arg_join_controllers = t;
633 static int parse_config_file(void) {
635 const ConfigTableItem items[] = {
636 { "Manager", "LogLevel", config_parse_level2, 0, NULL },
637 { "Manager", "LogTarget", config_parse_target, 0, NULL },
638 { "Manager", "LogColor", config_parse_color, 0, NULL },
639 { "Manager", "LogLocation", config_parse_location, 0, NULL },
640 { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
641 { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
642 { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
643 { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
644 { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
645 { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers },
646 { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
647 { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
648 { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
649 { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
650 { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
651 { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
652 { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
653 { "Manager", "DefaultEnvironment", config_parse_environ, 0, &arg_default_environment },
654 { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
655 { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
656 { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
657 { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
658 { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
659 { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
660 { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
661 { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
662 { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
663 { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
664 { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
665 { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
666 { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
667 { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
668 { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
669 { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
670 { NULL, NULL, NULL, 0, NULL }
673 _cleanup_fclose_ FILE *f;
677 fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf";
683 log_warning("Failed to open configuration file '%s': %m", fn);
687 r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, false, NULL);
689 log_warning("Failed to parse configuration file: %s", strerror(-r));
694 static int parse_proc_cmdline(void) {
695 _cleanup_free_ char *line = NULL;
700 /* Don't read /proc/cmdline if we are in a container, since
701 * that is only relevant for the host system */
702 if (detect_container(NULL) > 0)
705 r = read_one_line_file("/proc/cmdline", &line);
707 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
711 FOREACH_WORD_QUOTED(w, l, line, state) {
712 _cleanup_free_ char *word;
714 word = strndup(w, l);
718 r = parse_proc_cmdline_word(word);
720 log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
728 static int parse_argv(int argc, char *argv[]) {
731 ARG_LOG_LEVEL = 0x100,
740 ARG_DUMP_CONFIGURATION_ITEMS,
748 ARG_DEFAULT_STD_OUTPUT,
749 ARG_DEFAULT_STD_ERROR
752 static const struct option options[] = {
753 { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
754 { "log-target", required_argument, NULL, ARG_LOG_TARGET },
755 { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
756 { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
757 { "unit", required_argument, NULL, ARG_UNIT },
758 { "system", no_argument, NULL, ARG_SYSTEM },
759 { "user", no_argument, NULL, ARG_USER },
760 { "test", no_argument, NULL, ARG_TEST },
761 { "help", no_argument, NULL, 'h' },
762 { "version", no_argument, NULL, ARG_VERSION },
763 { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
764 { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
765 { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
766 { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
767 { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
768 { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
769 { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
770 { "introspect", optional_argument, NULL, ARG_INTROSPECT },
771 { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
772 { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
784 while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
789 if ((r = log_set_max_level_from_string(optarg)) < 0) {
790 log_error("Failed to parse log level %s.", optarg);
798 if ((r = log_set_target_from_string(optarg)) < 0) {
799 log_error("Failed to parse log target %s.", optarg);
808 if ((r = log_show_color_from_string(optarg)) < 0) {
809 log_error("Failed to parse log color setting %s.", optarg);
813 log_show_color(true);
817 case ARG_LOG_LOCATION:
820 if ((r = log_show_location_from_string(optarg)) < 0) {
821 log_error("Failed to parse log location setting %s.", optarg);
825 log_show_location(true);
829 case ARG_DEFAULT_STD_OUTPUT:
831 if ((r = exec_output_from_string(optarg)) < 0) {
832 log_error("Failed to parse default standard output setting %s.", optarg);
835 arg_default_std_output = r;
838 case ARG_DEFAULT_STD_ERROR:
840 if ((r = exec_output_from_string(optarg)) < 0) {
841 log_error("Failed to parse default standard error output setting %s.", optarg);
844 arg_default_std_error = r;
849 if ((r = set_default_unit(optarg)) < 0) {
850 log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
857 arg_running_as = SYSTEMD_SYSTEM;
861 arg_running_as = SYSTEMD_USER;
865 arg_action = ACTION_TEST;
869 arg_action = ACTION_VERSION;
872 case ARG_DUMP_CONFIGURATION_ITEMS:
873 arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
877 r = optarg ? parse_boolean(optarg) : 1;
879 log_error("Failed to parse dump core boolean %s.", optarg);
885 case ARG_CRASH_SHELL:
886 r = optarg ? parse_boolean(optarg) : 1;
888 log_error("Failed to parse crash shell boolean %s.", optarg);
894 case ARG_CONFIRM_SPAWN:
895 r = optarg ? parse_boolean(optarg) : 1;
897 log_error("Failed to parse confirm spawn boolean %s.", optarg);
900 arg_confirm_spawn = r;
903 case ARG_SHOW_STATUS:
904 r = optarg ? parse_boolean(optarg) : 1;
906 log_error("Failed to parse show status boolean %s.", optarg);
912 case ARG_DESERIALIZE: {
916 r = safe_atoi(optarg, &fd);
917 if (r < 0 || fd < 0) {
918 log_error("Failed to parse deserialize option %s.", optarg);
919 return r < 0 ? r : -EINVAL;
922 fd_cloexec(fd, true);
926 log_error("Failed to open serialization fd: %m");
931 fclose(serialization);
938 case ARG_SWITCHED_ROOT:
939 arg_switched_root = true;
942 case ARG_INTROSPECT: {
943 const char * const * i = NULL;
945 for (i = bus_interface_table; *i; i += 2)
946 if (!optarg || streq(i[0], optarg)) {
947 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
950 fputs("</node>\n", stdout);
957 log_error("Unknown interface %s.", optarg);
959 arg_action = ACTION_DONE;
964 arg_action = ACTION_HELP;
968 log_set_max_level(LOG_DEBUG);
974 /* Just to eat away the sysvinit kernel
975 * cmdline args without getopt() error
976 * messages that we'll parse in
977 * parse_proc_cmdline_word() or ignore. */
982 log_error("Unknown option code %c", c);
989 if (optind < argc && getpid() != 1) {
990 /* Hmm, when we aren't run as init system
991 * let's complain about excess arguments */
993 log_error("Excess arguments.");
997 if (detect_container(NULL) > 0) {
1000 /* All /proc/cmdline arguments the kernel didn't
1001 * understand it passed to us. We're not really
1002 * interested in that usually since /proc/cmdline is
1003 * more interesting and complete. With one exception:
1004 * if we are run in a container /proc/cmdline is not
1005 * relevant for the container, hence we rely on argv[]
1008 for (a = argv; a < argv + argc; a++)
1009 if ((r = parse_proc_cmdline_word(*a)) < 0) {
1010 log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
1018 static int help(void) {
1020 printf("%s [OPTIONS...]\n\n"
1021 "Starts up and maintains the system or user services.\n\n"
1022 " -h --help Show this help\n"
1023 " --test Determine startup sequence, dump it and exit\n"
1024 " --dump-configuration-items Dump understood unit configuration items\n"
1025 " --introspect[=INTERFACE] Extract D-Bus interface data\n"
1026 " --unit=UNIT Set default unit\n"
1027 " --system Run a system instance, even if PID != 1\n"
1028 " --user Run a user instance\n"
1029 " --dump-core[=0|1] Dump core on crash\n"
1030 " --crash-shell[=0|1] Run shell on crash\n"
1031 " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
1032 " --show-status[=0|1] Show status updates on the console during bootup\n"
1033 " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
1034 " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
1035 " --log-color[=0|1] Highlight important log messages\n"
1036 " --log-location[=0|1] Include code location in log messages\n"
1037 " --default-standard-output= Set default standard output for services\n"
1038 " --default-standard-error= Set default standard error output for services\n",
1039 program_invocation_short_name);
1044 static int version(void) {
1045 puts(PACKAGE_STRING);
1046 puts(SYSTEMD_FEATURES);
1051 static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching_root) {
1060 /* Make sure nothing is really destructed when we shut down */
1063 r = manager_open_serialization(m, &f);
1065 log_error("Failed to create serialization file: %s", strerror(-r));
1072 log_error("Failed to allocate fd set: %s", strerror(-r));
1076 r = manager_serialize(m, f, fds, switching_root);
1078 log_error("Failed to serialize state: %s", strerror(-r));
1082 if (fseeko(f, 0, SEEK_SET) < 0) {
1083 log_error("Failed to rewind serialization fd: %m");
1087 r = fd_cloexec(fileno(f), false);
1089 log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
1093 r = fdset_cloexec(fds, false);
1095 log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
1113 static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
1117 assert(saved_rlimit);
1119 /* Save the original RLIMIT_NOFILE so that we can reset it
1120 * later when transitioning from the initrd to the main
1121 * systemd or suchlike. */
1122 if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
1123 log_error("Reading RLIMIT_NOFILE failed: %m");
1127 /* Make sure forked processes get the default kernel setting */
1128 if (!arg_default_rlimit[RLIMIT_NOFILE]) {
1131 rl = newdup(struct rlimit, saved_rlimit, 1);
1135 arg_default_rlimit[RLIMIT_NOFILE] = rl;
1138 /* Bump up the resource limit for ourselves substantially */
1139 nl.rlim_cur = nl.rlim_max = 64*1024;
1140 r = setrlimit_closest(RLIMIT_NOFILE, &nl);
1142 log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
1149 static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
1151 unsigned long long a, b;
1155 e = getenv("RD_TIMESTAMP");
1159 if (sscanf(e, "%llu %llu", &a, &b) != 2)
1162 t->realtime = (usec_t) a;
1163 t->monotonic = (usec_t) b;
1168 static void test_mtab(void) {
1171 /* Check that /etc/mtab is a symlink */
1173 if (readlink_malloc("/etc/mtab", &p) >= 0) {
1176 b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
1183 log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
1184 "This is not supported anymore. "
1185 "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
1188 static void test_usr(void) {
1190 /* Check that /usr is not a separate fs */
1192 if (dir_is_empty("/usr") <= 0)
1195 log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
1196 "Some things will probably break (sometimes even silently) in mysterious ways. "
1197 "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
1200 static void test_cgroups(void) {
1202 if (access("/proc/cgroups", F_OK) >= 0)
1205 log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
1206 "Systems without control groups are not supported. "
1207 "We will now sleep for 10s, and then continue boot-up. "
1208 "Expect breakage and please do not file bugs. "
1209 "Instead fix your kernel and enable CONFIG_CGROUPS. "
1210 "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
1215 static int initialize_join_controllers(void) {
1216 /* By default, mount "cpu" + "cpuacct" together, and "net_cls"
1217 * + "net_prio". We'd like to add "cpuset" to the mix, but
1218 * "cpuset" does't really work for groups with no initialized
1221 arg_join_controllers = new(char**, 3);
1222 if (!arg_join_controllers)
1225 arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
1226 arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
1227 arg_join_controllers[2] = NULL;
1229 if (!arg_join_controllers[0] || !arg_join_controllers[1]) {
1230 free_join_controllers();
1237 int main(int argc, char *argv[]) {
1239 int r, retval = EXIT_FAILURE;
1240 usec_t before_startup, after_startup;
1241 char timespan[FORMAT_TIMESPAN_MAX];
1243 bool reexecute = false;
1244 const char *shutdown_verb = NULL;
1245 dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
1246 dual_timestamp userspace_timestamp = { 0ULL, 0ULL };
1247 dual_timestamp kernel_timestamp = { 0ULL, 0ULL };
1248 static char systemd[] = "systemd";
1249 bool skip_setup = false;
1251 bool loaded_policy = false;
1252 bool arm_reboot_watchdog = false;
1253 bool queue_default_job = false;
1254 char *switch_root_dir = NULL, *switch_root_init = NULL;
1255 static struct rlimit saved_rlimit_nofile = { 0, 0 };
1257 #ifdef HAVE_SYSV_COMPAT
1258 if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
1259 /* This is compatibility support for SysV, where
1260 * calling init as a user is identical to telinit. */
1263 execv(SYSTEMCTL_BINARY_PATH, argv);
1264 log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
1269 dual_timestamp_from_monotonic(&kernel_timestamp, 0);
1270 dual_timestamp_get(&userspace_timestamp);
1272 /* Determine if this is a reexecution or normal bootup. We do
1273 * the full command line parsing much later, so let's just
1274 * have a quick peek here. */
1275 if (strv_find(argv+1, "--deserialize"))
1278 /* If we have switched root, do all the special setup
1280 if (strv_find(argv+1, "--switched-root"))
1283 /* If we get started via the /sbin/init symlink then we are
1284 called 'init'. After a subsequent reexecution we are then
1285 called 'systemd'. That is confusing, hence let's call us
1286 systemd right-away. */
1287 program_invocation_short_name = systemd;
1288 prctl(PR_SET_NAME, systemd);
1293 log_show_color(isatty(STDERR_FILENO) > 0);
1295 if (getpid() == 1 && detect_container(NULL) <= 0) {
1297 /* Running outside of a container as PID 1 */
1298 arg_running_as = SYSTEMD_SYSTEM;
1300 log_set_target(LOG_TARGET_KMSG);
1304 char *rd_timestamp = NULL;
1306 initrd_timestamp = userspace_timestamp;
1307 asprintf(&rd_timestamp, "%llu %llu",
1308 (unsigned long long) initrd_timestamp.realtime,
1309 (unsigned long long) initrd_timestamp.monotonic);
1311 setenv("RD_TIMESTAMP", rd_timestamp, 1);
1317 mount_setup_early();
1318 if (selinux_setup(&loaded_policy) < 0)
1320 if (ima_setup() < 0)
1322 if (smack_setup() < 0)
1326 if (label_init(NULL) < 0)
1330 if (hwclock_is_localtime() > 0) {
1333 /* The first-time call to settimeofday() does a time warp in the kernel */
1334 r = hwclock_set_timezone(&min);
1336 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
1338 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
1339 } else if (!in_initrd()) {
1341 * Do dummy first-time call to seal the kernel's time warp magic
1343 * Do not call this this from inside the initrd. The initrd might not
1344 * carry /etc/adjtime with LOCAL, but the real system could be set up
1345 * that way. In such case, we need to delay the time-warp or the sealing
1346 * until we reach the real system.
1348 hwclock_reset_timezone();
1350 /* Tell the kernel our time zone */
1351 r = hwclock_set_timezone(NULL);
1353 log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
1357 /* Set the default for later on, but don't actually
1358 * open the logs like this for now. Note that if we
1359 * are transitioning from the initrd there might still
1360 * be journal fd open, and we shouldn't attempt
1361 * opening that before we parsed /proc/cmdline which
1362 * might redirect output elsewhere. */
1363 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1365 } else if (getpid() == 1) {
1366 /* Running inside a container, as PID 1 */
1367 arg_running_as = SYSTEMD_SYSTEM;
1368 log_set_target(LOG_TARGET_CONSOLE);
1371 /* For the later on, see above... */
1372 log_set_target(LOG_TARGET_JOURNAL);
1374 /* clear the kernel timestamp,
1375 * because we are in a container */
1376 kernel_timestamp.monotonic = 0ULL;
1377 kernel_timestamp.realtime = 0ULL;
1380 /* Running as user instance */
1381 arg_running_as = SYSTEMD_USER;
1382 log_set_target(LOG_TARGET_AUTO);
1385 /* clear the kernel timestamp,
1386 * because we are not PID 1 */
1387 kernel_timestamp.monotonic = 0ULL;
1388 kernel_timestamp.realtime = 0ULL;
1391 /* Initialize default unit */
1392 r = set_default_unit(SPECIAL_DEFAULT_TARGET);
1394 log_error("Failed to set default unit %s: %s", SPECIAL_DEFAULT_TARGET, strerror(-r));
1398 r = initialize_join_controllers();
1402 /* Mount /proc, /sys and friends, so that /proc/cmdline and
1403 * /proc/$PID/fd is available. */
1404 if (getpid() == 1) {
1405 r = mount_setup(loaded_policy);
1410 /* Reset all signal handlers. */
1411 assert_se(reset_all_signal_handlers() == 0);
1413 ignore_signals(SIGNALS_IGNORE, -1);
1415 if (parse_config_file() < 0)
1418 if (arg_running_as == SYSTEMD_SYSTEM)
1419 if (parse_proc_cmdline() < 0)
1422 log_parse_environment();
1424 if (parse_argv(argc, argv) < 0)
1427 if (arg_action == ACTION_TEST &&
1429 log_error("Don't run test mode as root.");
1433 if (arg_running_as == SYSTEMD_USER &&
1434 arg_action == ACTION_RUN &&
1436 log_error("Trying to run as user instance, but the system has not been booted with systemd.");
1440 if (arg_running_as == SYSTEMD_SYSTEM &&
1441 arg_action == ACTION_RUN &&
1442 running_in_chroot() > 0) {
1443 log_error("Cannot be run in a chroot() environment.");
1447 if (arg_action == ACTION_HELP) {
1450 } else if (arg_action == ACTION_VERSION) {
1453 } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
1454 unit_dump_config_items(stdout);
1455 retval = EXIT_SUCCESS;
1457 } else if (arg_action == ACTION_DONE) {
1458 retval = EXIT_SUCCESS;
1462 assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
1464 /* Close logging fds, in order not to confuse fdset below */
1467 /* Remember open file descriptors for later deserialization */
1468 r = fdset_new_fill(&fds);
1470 log_error("Failed to allocate fd set: %s", strerror(-r));
1473 fdset_cloexec(fds, true);
1476 assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
1478 /* Set up PATH unless it is already set */
1480 #ifdef HAVE_SPLIT_USR
1481 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
1483 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
1485 arg_running_as == SYSTEMD_SYSTEM);
1487 if (arg_running_as == SYSTEMD_SYSTEM) {
1488 /* Parse the data passed to us. We leave this
1489 * variables set, but the manager later on will not
1490 * pass them on to our children. */
1492 parse_initrd_timestamp(&initrd_timestamp);
1494 /* Unset some environment variables passed in from the
1495 * kernel that don't really make sense for us. */
1499 /* When we are invoked by a shell, these might be set,
1500 * but make little sense to pass on */
1505 /* When we are invoked by a chroot-like tool such as
1506 * nspawn, these might be set, but make little sense
1509 unsetenv("LOGNAME");
1511 /* We suppress the socket activation env vars, as
1512 * we'll try to match *any* open fd to units if
1514 unsetenv("LISTEN_FDS");
1515 unsetenv("LISTEN_PID");
1517 /* All other variables are left as is, so that clients
1518 * can still read them via /proc/1/environ */
1521 /* Move out of the way, so that we won't block unmounts */
1522 assert_se(chdir("/") == 0);
1524 if (arg_running_as == SYSTEMD_SYSTEM) {
1525 /* Become a session leader if we aren't one yet. */
1528 /* Disable the umask logic */
1532 /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
1533 dbus_connection_set_change_sigpipe(FALSE);
1535 /* Reset the console, but only if this is really init and we
1536 * are freshly booted */
1537 if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
1538 console_setup(getpid() == 1 && !skip_setup);
1540 /* Open the logging devices, if possible and necessary */
1543 /* Make sure we leave a core dump without panicing the
1545 if (getpid() == 1) {
1546 install_crash_handler();
1548 r = mount_cgroup_controllers(arg_join_controllers);
1553 if (arg_running_as == SYSTEMD_SYSTEM) {
1554 const char *virtualization = NULL;
1556 log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
1558 detect_virtualization(&virtualization);
1560 log_info("Detected virtualization '%s'.", virtualization);
1563 log_info("Running in initial RAM disk.");
1566 log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
1568 if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
1571 if (arg_show_status || plymouth_running())
1586 if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
1587 watchdog_set_timeout(&arg_runtime_watchdog);
1589 if (arg_timer_slack_nsec != (nsec_t) -1)
1590 if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
1591 log_error("Failed to adjust timer slack: %m");
1593 if (arg_capability_bounding_set_drop) {
1594 r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
1596 log_error("Failed to drop capability bounding set: %s", strerror(-r));
1599 r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
1601 log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
1606 if (arg_running_as == SYSTEMD_USER) {
1607 /* Become reaper of our children */
1608 if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
1609 log_warning("Failed to make us a subreaper: %m");
1610 if (errno == EINVAL)
1611 log_info("Perhaps the kernel version is too old (< 3.4?)");
1615 if (arg_running_as == SYSTEMD_SYSTEM)
1616 bump_rlimit_nofile(&saved_rlimit_nofile);
1618 r = manager_new(arg_running_as, &m);
1620 log_error("Failed to allocate manager object: %s", strerror(-r));
1624 m->confirm_spawn = arg_confirm_spawn;
1625 m->default_std_output = arg_default_std_output;
1626 m->default_std_error = arg_default_std_error;
1627 m->runtime_watchdog = arg_runtime_watchdog;
1628 m->shutdown_watchdog = arg_shutdown_watchdog;
1629 m->userspace_timestamp = userspace_timestamp;
1630 m->kernel_timestamp = kernel_timestamp;
1631 m->initrd_timestamp = initrd_timestamp;
1633 manager_set_default_rlimits(m, arg_default_rlimit);
1635 if (arg_default_controllers)
1636 manager_set_default_controllers(m, arg_default_controllers);
1638 if (arg_default_environment)
1639 manager_set_default_environment(m, arg_default_environment);
1641 manager_set_show_status(m, arg_show_status);
1643 /* Remember whether we should queue the default job */
1644 queue_default_job = !serialization || arg_switched_root;
1646 before_startup = now(CLOCK_MONOTONIC);
1648 r = manager_startup(m, serialization, fds);
1650 log_error("Failed to fully start up daemon: %s", strerror(-r));
1652 /* This will close all file descriptors that were opened, but
1653 * not claimed by any unit. */
1656 if (serialization) {
1657 fclose(serialization);
1658 serialization = NULL;
1661 if (queue_default_job) {
1663 Unit *target = NULL;
1664 Job *default_unit_job;
1666 dbus_error_init(&error);
1668 log_debug("Activating default unit: %s", arg_default_unit);
1670 r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
1672 log_error("Failed to load default target: %s", bus_error(&error, r));
1673 dbus_error_free(&error);
1674 } else if (target->load_state == UNIT_ERROR)
1675 log_error("Failed to load default target: %s", strerror(-target->load_error));
1676 else if (target->load_state == UNIT_MASKED)
1677 log_error("Default target masked.");
1679 if (!target || target->load_state != UNIT_LOADED) {
1680 log_info("Trying to load rescue target...");
1682 r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
1684 log_error("Failed to load rescue target: %s", bus_error(&error, r));
1685 dbus_error_free(&error);
1687 } else if (target->load_state == UNIT_ERROR) {
1688 log_error("Failed to load rescue target: %s", strerror(-target->load_error));
1690 } else if (target->load_state == UNIT_MASKED) {
1691 log_error("Rescue target masked.");
1696 assert(target->load_state == UNIT_LOADED);
1698 if (arg_action == ACTION_TEST) {
1699 printf("-> By units:\n");
1700 manager_dump_units(m, stdout, "\t");
1703 r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, false, &error, &default_unit_job);
1705 log_debug("Default target could not be isolated, starting instead: %s", bus_error(&error, r));
1706 dbus_error_free(&error);
1708 r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
1710 log_error("Failed to start default target: %s", bus_error(&error, r));
1711 dbus_error_free(&error);
1715 log_error("Failed to isolate default target: %s", bus_error(&error, r));
1716 dbus_error_free(&error);
1720 m->default_unit_job_id = default_unit_job->id;
1722 after_startup = now(CLOCK_MONOTONIC);
1723 log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
1724 "Loaded units and determined initial transaction in %s.",
1725 format_timespan(timespan, sizeof(timespan), after_startup - before_startup, 0));
1727 if (arg_action == ACTION_TEST) {
1728 printf("-> By jobs:\n");
1729 manager_dump_jobs(m, stdout, "\t");
1730 retval = EXIT_SUCCESS;
1736 r = manager_loop(m);
1738 log_error("Failed to run mainloop: %s", strerror(-r));
1742 switch (m->exit_code) {
1745 retval = EXIT_SUCCESS;
1749 case MANAGER_RELOAD:
1750 log_info("Reloading.");
1751 r = manager_reload(m);
1753 log_error("Failed to reload: %s", strerror(-r));
1756 case MANAGER_REEXECUTE:
1758 if (prepare_reexecute(m, &serialization, &fds, false) < 0)
1762 log_notice("Reexecuting.");
1765 case MANAGER_SWITCH_ROOT:
1766 /* Steal the switch root parameters */
1767 switch_root_dir = m->switch_root;
1768 switch_root_init = m->switch_root_init;
1769 m->switch_root = m->switch_root_init = NULL;
1771 if (!switch_root_init)
1772 if (prepare_reexecute(m, &serialization, &fds, true) < 0)
1776 log_notice("Switching root.");
1779 case MANAGER_REBOOT:
1780 case MANAGER_POWEROFF:
1782 case MANAGER_KEXEC: {
1783 static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
1784 [MANAGER_REBOOT] = "reboot",
1785 [MANAGER_POWEROFF] = "poweroff",
1786 [MANAGER_HALT] = "halt",
1787 [MANAGER_KEXEC] = "kexec"
1790 assert_se(shutdown_verb = table[m->exit_code]);
1791 arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
1793 log_notice("Shutting down.");
1798 assert_not_reached("Unknown exit code.");
1806 for (j = 0; j < RLIMIT_NLIMITS; j++)
1807 free(arg_default_rlimit[j]);
1809 free(arg_default_unit);
1810 strv_free(arg_default_controllers);
1811 free_join_controllers();
1818 unsigned i, args_size;
1820 /* Close and disarm the watchdog, so that the new
1821 * instance can reinitialize it, but doesn't get
1822 * rebooted while we do that */
1823 watchdog_close(true);
1825 /* Reset the RLIMIT_NOFILE to the kernel default, so
1826 * that the new systemd can pass the kernel default to
1827 * its child processes */
1828 if (saved_rlimit_nofile.rlim_cur > 0)
1829 setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
1831 if (switch_root_dir) {
1832 /* Kill all remaining processes from the
1833 * initrd, but don't wait for them, so that we
1834 * can handle the SIGCHLD for them after
1836 broadcast_signal(SIGTERM, false);
1838 /* And switch root */
1839 r = switch_root(switch_root_dir);
1841 log_error("Failed to switch root, ignoring: %s", strerror(-r));
1844 args_size = MAX(6, argc+1);
1845 args = newa(const char*, args_size);
1847 if (!switch_root_init) {
1850 /* First try to spawn ourselves with the right
1851 * path, and with full serialization. We do
1852 * this only if the user didn't specify an
1853 * explicit init to spawn. */
1855 assert(serialization);
1858 snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
1862 args[i++] = SYSTEMD_BINARY_PATH;
1863 if (switch_root_dir)
1864 args[i++] = "--switched-root";
1865 args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user";
1866 args[i++] = "--deserialize";
1870 assert(i <= args_size);
1871 execv(args[0], (char* const*) args);
1874 /* Try the fallback, if there is any, without any
1875 * serialization. We pass the original argv[] and
1876 * envp[]. (Well, modulo the ordering changes due to
1877 * getopt() in argv[], and some cleanups in envp[],
1878 * but let's hope that doesn't matter.) */
1880 if (serialization) {
1881 fclose(serialization);
1882 serialization = NULL;
1890 /* Reopen the console */
1891 make_console_stdio();
1893 for (j = 1, i = 1; j < argc; j++)
1894 args[i++] = argv[j];
1896 assert(i <= args_size);
1898 if (switch_root_init) {
1899 args[0] = switch_root_init;
1900 execv(args[0], (char* const*) args);
1901 log_warning("Failed to execute configured init, trying fallback: %m");
1904 args[0] = "/sbin/init";
1905 execv(args[0], (char* const*) args);
1907 if (errno == ENOENT) {
1908 log_warning("No /sbin/init, trying fallback");
1910 args[0] = "/bin/sh";
1912 execv(args[0], (char* const*) args);
1913 log_error("Failed to execute /bin/sh, giving up: %m");
1915 log_warning("Failed to execute /sbin/init, giving up: %m");
1919 fclose(serialization);
1924 if (shutdown_verb) {
1925 const char * command_line[] = {
1926 SYSTEMD_SHUTDOWN_BINARY_PATH,
1932 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
1935 /* If we reboot let's set the shutdown
1936 * watchdog and tell the shutdown binary to
1937 * repeatedly ping it */
1938 watchdog_set_timeout(&arg_shutdown_watchdog);
1939 watchdog_close(false);
1941 /* Tell the binary how often to ping */
1942 snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
1945 env_block = strv_append(environ, e);
1947 env_block = strv_copy(environ);
1948 watchdog_close(true);
1951 execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
1953 log_error("Failed to execute shutdown binary, freezing: %m");