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>
38 #include "load-fragment.h"
41 #include "conf-parser.h"
42 #include "bus-errors.h"
51 #include "mount-setup.h"
52 #include "loopback-setup.h"
53 #include "kmod-setup.h"
54 #include "hostname-setup.h"
55 #include "machine-id-setup.h"
56 #include "locale-setup.h"
58 #include "selinux-setup.h"
59 #include "ima-setup.h"
65 ACTION_DUMP_CONFIGURATION_ITEMS
,
67 } arg_action
= ACTION_RUN
;
69 static char *arg_default_unit
= NULL
;
70 static ManagerRunningAs arg_running_as
= _MANAGER_RUNNING_AS_INVALID
;
72 static bool arg_dump_core
= true;
73 static bool arg_crash_shell
= false;
74 static int arg_crash_chvt
= -1;
75 static bool arg_confirm_spawn
= false;
76 static bool arg_show_status
= true;
77 #ifdef HAVE_SYSV_COMPAT
78 static bool arg_sysv_console
= true;
80 static char **arg_default_controllers
= NULL
;
81 static char ***arg_join_controllers
= NULL
;
82 static ExecOutput arg_default_std_output
= EXEC_OUTPUT_JOURNAL
;
83 static ExecOutput arg_default_std_error
= EXEC_OUTPUT_INHERIT
;
84 static usec_t arg_runtime_watchdog
= 0;
85 static usec_t arg_shutdown_watchdog
= 10 * USEC_PER_MINUTE
;
87 static FILE* serialization
= NULL
;
89 static void nop_handler(int sig
) {
92 _noreturn_
static void crash(int sig
) {
95 log_error("Caught <%s>, not dumping core.", signal_to_string(sig
));
100 /* We want to wait for the core process, hence let's enable SIGCHLD */
102 sa
.sa_handler
= nop_handler
;
103 sa
.sa_flags
= SA_NOCLDSTOP
|SA_RESTART
;
104 assert_se(sigaction(SIGCHLD
, &sa
, NULL
) == 0);
106 if ((pid
= fork()) < 0)
107 log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig
), strerror(errno
));
112 /* Enable default signal handler for core dump */
114 sa
.sa_handler
= SIG_DFL
;
115 assert_se(sigaction(sig
, &sa
, NULL
) == 0);
117 /* Don't limit the core dump size */
119 rl
.rlim_cur
= RLIM_INFINITY
;
120 rl
.rlim_max
= RLIM_INFINITY
;
121 setrlimit(RLIMIT_CORE
, &rl
);
123 /* Just to be sure... */
124 assert_se(chdir("/") == 0);
126 /* Raise the signal again */
129 assert_not_reached("We shouldn't be here...");
136 /* Order things nicely. */
137 if ((r
= wait_for_terminate(pid
, &status
)) < 0)
138 log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig
), strerror(-r
));
139 else if (status
.si_code
!= CLD_DUMPED
)
140 log_error("Caught <%s>, core dump failed.", signal_to_string(sig
));
142 log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig
), (unsigned long) pid
);
147 chvt(arg_crash_chvt
);
149 if (arg_crash_shell
) {
153 log_info("Executing crash shell in 10s...");
156 /* Let the kernel reap children for us */
158 sa
.sa_handler
= SIG_IGN
;
159 sa
.sa_flags
= SA_NOCLDSTOP
|SA_NOCLDWAIT
|SA_RESTART
;
160 assert_se(sigaction(SIGCHLD
, &sa
, NULL
) == 0);
162 if ((pid
= fork()) < 0)
163 log_error("Failed to fork off crash shell: %s", strerror(errno
));
167 if ((fd
= acquire_terminal("/dev/console", false, true, true)) < 0)
168 log_error("Failed to acquire terminal: %s", strerror(-fd
));
169 else if ((r
= make_stdio(fd
)) < 0)
170 log_error("Failed to duplicate terminal fd: %s", strerror(-r
));
172 execl("/bin/sh", "/bin/sh", NULL
);
174 log_error("execl() failed: %s", strerror(errno
));
178 log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid
);
181 log_info("Freezing execution.");
185 static void install_crash_handler(void) {
190 sa
.sa_handler
= crash
;
191 sa
.sa_flags
= SA_NODEFER
;
193 sigaction_many(&sa
, SIGNALS_CRASH_HANDLER
, -1);
196 static int console_setup(bool do_reset
) {
199 /* If we are init, we connect stdin/stdout/stderr to /dev/null
200 * and make sure we don't have a controlling tty. */
207 tty_fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
209 log_error("Failed to open /dev/console: %s", strerror(-tty_fd
));
213 /* We don't want to force text mode.
214 * plymouth may be showing pictures already from initrd. */
215 r
= reset_terminal_fd(tty_fd
, false);
217 log_error("Failed to reset /dev/console: %s", strerror(-r
));
219 close_nointr_nofail(tty_fd
);
223 static int set_default_unit(const char *u
) {
228 if (!(c
= strdup(u
)))
231 free(arg_default_unit
);
232 arg_default_unit
= c
;
236 static int parse_proc_cmdline_word(const char *word
) {
238 static const char * const rlmap
[] = {
239 "emergency", SPECIAL_EMERGENCY_TARGET
,
240 "-b", SPECIAL_EMERGENCY_TARGET
,
241 "single", SPECIAL_RESCUE_TARGET
,
242 "-s", SPECIAL_RESCUE_TARGET
,
243 "s", SPECIAL_RESCUE_TARGET
,
244 "S", SPECIAL_RESCUE_TARGET
,
245 "1", SPECIAL_RESCUE_TARGET
,
246 "2", SPECIAL_RUNLEVEL2_TARGET
,
247 "3", SPECIAL_RUNLEVEL3_TARGET
,
248 "4", SPECIAL_RUNLEVEL4_TARGET
,
249 "5", SPECIAL_RUNLEVEL5_TARGET
,
254 if (startswith(word
, "systemd.unit="))
255 return set_default_unit(word
+ 13);
257 else if (startswith(word
, "systemd.log_target=")) {
259 if (log_set_target_from_string(word
+ 19) < 0)
260 log_warning("Failed to parse log target %s. Ignoring.", word
+ 19);
262 } else if (startswith(word
, "systemd.log_level=")) {
264 if (log_set_max_level_from_string(word
+ 18) < 0)
265 log_warning("Failed to parse log level %s. Ignoring.", word
+ 18);
267 } else if (startswith(word
, "systemd.log_color=")) {
269 if (log_show_color_from_string(word
+ 18) < 0)
270 log_warning("Failed to parse log color setting %s. Ignoring.", word
+ 18);
272 } else if (startswith(word
, "systemd.log_location=")) {
274 if (log_show_location_from_string(word
+ 21) < 0)
275 log_warning("Failed to parse log location setting %s. Ignoring.", word
+ 21);
277 } else if (startswith(word
, "systemd.dump_core=")) {
280 if ((r
= parse_boolean(word
+ 18)) < 0)
281 log_warning("Failed to parse dump core switch %s. Ignoring.", word
+ 18);
285 } else if (startswith(word
, "systemd.crash_shell=")) {
288 if ((r
= parse_boolean(word
+ 20)) < 0)
289 log_warning("Failed to parse crash shell switch %s. Ignoring.", word
+ 20);
293 } else if (startswith(word
, "systemd.confirm_spawn=")) {
296 if ((r
= parse_boolean(word
+ 22)) < 0)
297 log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word
+ 22);
299 arg_confirm_spawn
= r
;
301 } else if (startswith(word
, "systemd.crash_chvt=")) {
304 if (safe_atoi(word
+ 19, &k
) < 0)
305 log_warning("Failed to parse crash chvt switch %s. Ignoring.", word
+ 19);
309 } else if (startswith(word
, "systemd.show_status=")) {
312 if ((r
= parse_boolean(word
+ 20)) < 0)
313 log_warning("Failed to parse show status switch %s. Ignoring.", word
+ 20);
316 } else if (startswith(word
, "systemd.default_standard_output=")) {
319 if ((r
= exec_output_from_string(word
+ 32)) < 0)
320 log_warning("Failed to parse default standard output switch %s. Ignoring.", word
+ 32);
322 arg_default_std_output
= r
;
323 } else if (startswith(word
, "systemd.default_standard_error=")) {
326 if ((r
= exec_output_from_string(word
+ 31)) < 0)
327 log_warning("Failed to parse default standard error switch %s. Ignoring.", word
+ 31);
329 arg_default_std_error
= r
;
330 } else if (startswith(word
, "systemd.setenv=")) {
334 cenv
= strdup(word
+ 15);
338 eq
= strchr(cenv
, '=');
342 log_warning("unsetenv failed %s. Ignoring.", strerror(errno
));
345 r
= setenv(cenv
, eq
+ 1, 1);
347 log_warning("setenv failed %s. Ignoring.", strerror(errno
));
350 #ifdef HAVE_SYSV_COMPAT
351 } else if (startswith(word
, "systemd.sysv_console=")) {
354 if ((r
= parse_boolean(word
+ 21)) < 0)
355 log_warning("Failed to parse SysV console switch %s. Ignoring.", word
+ 20);
357 arg_sysv_console
= r
;
360 } else if (startswith(word
, "systemd.")) {
362 log_warning("Unknown kernel switch %s. Ignoring.", word
);
364 log_info("Supported kernel switches:\n"
365 "systemd.unit=UNIT Default unit to start\n"
366 "systemd.dump_core=0|1 Dump core on crash\n"
367 "systemd.crash_shell=0|1 Run shell on crash\n"
368 "systemd.crash_chvt=N Change to VT #N on crash\n"
369 "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
370 "systemd.show_status=0|1 Show status updates on the console during bootup\n"
371 #ifdef HAVE_SYSV_COMPAT
372 "systemd.sysv_console=0|1 Connect output of SysV scripts to console\n"
374 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
376 "systemd.log_level=LEVEL Log level\n"
377 "systemd.log_color=0|1 Highlight important log messages\n"
378 "systemd.log_location=0|1 Include code location in log messages\n"
379 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
380 " Set default log output for services\n"
381 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
382 " Set default log error output for services\n");
384 } else if (streq(word
, "quiet")) {
385 arg_show_status
= false;
386 #ifdef HAVE_SYSV_COMPAT
387 arg_sysv_console
= false;
392 /* SysV compatibility */
393 for (i
= 0; i
< ELEMENTSOF(rlmap
); i
+= 2)
394 if (streq(word
, rlmap
[i
]))
395 return set_default_unit(rlmap
[i
+1]);
401 static int config_parse_level2(
402 const char *filename
,
415 log_set_max_level_from_string(rvalue
);
419 static int config_parse_target(
420 const char *filename
,
433 log_set_target_from_string(rvalue
);
437 static int config_parse_color(
438 const char *filename
,
451 log_show_color_from_string(rvalue
);
455 static int config_parse_location(
456 const char *filename
,
469 log_show_location_from_string(rvalue
);
473 static int config_parse_cpu_affinity2(
474 const char *filename
,
493 FOREACH_WORD_QUOTED(w
, l
, rvalue
, state
) {
498 if (!(t
= strndup(w
, l
)))
501 r
= safe_atou(t
, &cpu
);
505 if (!(c
= cpu_set_malloc(&ncpus
)))
508 if (r
< 0 || cpu
>= ncpus
) {
509 log_error("[%s:%u] Failed to parse CPU affinity: %s", filename
, line
, rvalue
);
514 CPU_SET_S(cpu
, CPU_ALLOC_SIZE(ncpus
), c
);
518 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus
), c
) < 0)
519 log_warning("Failed to set CPU affinity: %m");
527 static void strv_free_free(char ***l
) {
539 static void free_join_controllers(void) {
540 if (!arg_join_controllers
)
543 strv_free_free(arg_join_controllers
);
544 arg_join_controllers
= NULL
;
547 static int config_parse_join_controllers(
548 const char *filename
,
565 free_join_controllers();
567 FOREACH_WORD_QUOTED(w
, length
, rvalue
, state
) {
570 s
= strndup(w
, length
);
574 l
= strv_split(s
, ",");
579 if (strv_length(l
) <= 1) {
584 if (!arg_join_controllers
) {
585 arg_join_controllers
= new(char**, 2);
586 if (!arg_join_controllers
) {
591 arg_join_controllers
[0] = l
;
592 arg_join_controllers
[1] = NULL
;
599 t
= new0(char**, n
+2);
607 for (a
= arg_join_controllers
; *a
; a
++) {
609 if (strv_overlap(*a
, l
)) {
612 c
= strv_merge(*a
, l
);
635 t
[n
++] = strv_uniq(l
);
637 strv_free_free(arg_join_controllers
);
638 arg_join_controllers
= t
;
645 static int parse_config_file(void) {
647 const ConfigTableItem items
[] = {
648 { "Manager", "LogLevel", config_parse_level2
, 0, NULL
},
649 { "Manager", "LogTarget", config_parse_target
, 0, NULL
},
650 { "Manager", "LogColor", config_parse_color
, 0, NULL
},
651 { "Manager", "LogLocation", config_parse_location
, 0, NULL
},
652 { "Manager", "DumpCore", config_parse_bool
, 0, &arg_dump_core
},
653 { "Manager", "CrashShell", config_parse_bool
, 0, &arg_crash_shell
},
654 { "Manager", "ShowStatus", config_parse_bool
, 0, &arg_show_status
},
655 #ifdef HAVE_SYSV_COMPAT
656 { "Manager", "SysVConsole", config_parse_bool
, 0, &arg_sysv_console
},
658 { "Manager", "CrashChVT", config_parse_int
, 0, &arg_crash_chvt
},
659 { "Manager", "CPUAffinity", config_parse_cpu_affinity2
, 0, NULL
},
660 { "Manager", "DefaultControllers", config_parse_strv
, 0, &arg_default_controllers
},
661 { "Manager", "DefaultStandardOutput", config_parse_output
, 0, &arg_default_std_output
},
662 { "Manager", "DefaultStandardError", config_parse_output
, 0, &arg_default_std_error
},
663 { "Manager", "JoinControllers", config_parse_join_controllers
, 0, &arg_join_controllers
},
664 { "Manager", "RuntimeWatchdogSec", config_parse_usec
, 0, &arg_runtime_watchdog
},
665 { "Manager", "ShutdownWatchdogSec", config_parse_usec
, 0, &arg_shutdown_watchdog
},
666 { NULL
, NULL
, NULL
, 0, NULL
}
673 fn
= arg_running_as
== MANAGER_SYSTEM
? SYSTEM_CONFIG_FILE
: USER_CONFIG_FILE
;
679 log_warning("Failed to open configuration file '%s': %m", fn
);
683 r
= config_parse(fn
, f
, "Manager\0", config_item_table_lookup
, (void*) items
, false, NULL
);
685 log_warning("Failed to parse configuration file: %s", strerror(-r
));
692 static int parse_proc_cmdline(void) {
693 char *line
, *w
, *state
;
697 /* Don't read /proc/cmdline if we are in a container, since
698 * that is only relevant for the host system */
699 if (detect_container(NULL
) > 0)
702 if ((r
= read_one_line_file("/proc/cmdline", &line
)) < 0) {
703 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r
));
707 FOREACH_WORD_QUOTED(w
, l
, line
, state
) {
710 if (!(word
= strndup(w
, l
))) {
715 r
= parse_proc_cmdline_word(word
);
729 static int parse_argv(int argc
, char *argv
[]) {
732 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 { "dump-configuration-items", no_argument
, NULL
, ARG_DUMP_CONFIGURATION_ITEMS
},
763 { "dump-core", optional_argument
, NULL
, ARG_DUMP_CORE
},
764 { "crash-shell", optional_argument
, NULL
, ARG_CRASH_SHELL
},
765 { "confirm-spawn", optional_argument
, NULL
, ARG_CONFIRM_SPAWN
},
766 { "show-status", optional_argument
, NULL
, ARG_SHOW_STATUS
},
767 #ifdef HAVE_SYSV_COMPAT
768 { "sysv-console", optional_argument
, NULL
, ARG_SYSV_CONSOLE
},
770 { "deserialize", required_argument
, NULL
, ARG_DESERIALIZE
},
771 { "introspect", optional_argument
, NULL
, ARG_INTROSPECT
},
772 { "default-standard-output", required_argument
, NULL
, ARG_DEFAULT_STD_OUTPUT
, },
773 { "default-standard-error", required_argument
, NULL
, ARG_DEFAULT_STD_ERROR
, },
785 while ((c
= getopt_long(argc
, argv
, "hDbsz:", options
, NULL
)) >= 0)
790 if ((r
= log_set_max_level_from_string(optarg
)) < 0) {
791 log_error("Failed to parse log level %s.", optarg
);
799 if ((r
= log_set_target_from_string(optarg
)) < 0) {
800 log_error("Failed to parse log target %s.", optarg
);
809 if ((r
= log_show_color_from_string(optarg
)) < 0) {
810 log_error("Failed to parse log color setting %s.", optarg
);
814 log_show_color(true);
818 case ARG_LOG_LOCATION
:
821 if ((r
= log_show_location_from_string(optarg
)) < 0) {
822 log_error("Failed to parse log location setting %s.", optarg
);
826 log_show_location(true);
830 case ARG_DEFAULT_STD_OUTPUT
:
832 if ((r
= exec_output_from_string(optarg
)) < 0) {
833 log_error("Failed to parse default standard output setting %s.", optarg
);
836 arg_default_std_output
= r
;
839 case ARG_DEFAULT_STD_ERROR
:
841 if ((r
= exec_output_from_string(optarg
)) < 0) {
842 log_error("Failed to parse default standard error output setting %s.", optarg
);
845 arg_default_std_error
= r
;
850 if ((r
= set_default_unit(optarg
)) < 0) {
851 log_error("Failed to set default unit %s: %s", optarg
, strerror(-r
));
858 arg_running_as
= MANAGER_SYSTEM
;
862 arg_running_as
= MANAGER_USER
;
866 arg_action
= ACTION_TEST
;
869 case ARG_DUMP_CONFIGURATION_ITEMS
:
870 arg_action
= ACTION_DUMP_CONFIGURATION_ITEMS
;
874 r
= optarg
? parse_boolean(optarg
) : 1;
876 log_error("Failed to parse dump core boolean %s.", optarg
);
882 case ARG_CRASH_SHELL
:
883 r
= optarg
? parse_boolean(optarg
) : 1;
885 log_error("Failed to parse crash shell boolean %s.", optarg
);
891 case ARG_CONFIRM_SPAWN
:
892 r
= optarg
? parse_boolean(optarg
) : 1;
894 log_error("Failed to parse confirm spawn boolean %s.", optarg
);
897 arg_confirm_spawn
= r
;
900 case ARG_SHOW_STATUS
:
901 r
= optarg
? parse_boolean(optarg
) : 1;
903 log_error("Failed to parse show status boolean %s.", optarg
);
909 #ifdef HAVE_SYSV_COMPAT
910 case ARG_SYSV_CONSOLE
:
911 r
= optarg
? parse_boolean(optarg
) : 1;
913 log_error("Failed to parse SysV console boolean %s.", optarg
);
916 arg_sysv_console
= r
;
920 case ARG_DESERIALIZE
: {
924 if ((r
= safe_atoi(optarg
, &fd
)) < 0 || fd
< 0) {
925 log_error("Failed to parse deserialize option %s.", optarg
);
929 if (!(f
= fdopen(fd
, "r"))) {
930 log_error("Failed to open serialization fd: %m");
935 fclose(serialization
);
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)
1016 static int help(void) {
1018 printf("%s [OPTIONS...]\n\n"
1019 "Starts up and maintains the system or user services.\n\n"
1020 " -h --help Show this help\n"
1021 " --test Determine startup sequence, dump it and exit\n"
1022 " --dump-configuration-items Dump understood unit configuration items\n"
1023 " --introspect[=INTERFACE] Extract D-Bus interface data\n"
1024 " --unit=UNIT Set default unit\n"
1025 " --system Run a system instance, even if PID != 1\n"
1026 " --user Run a user instance\n"
1027 " --dump-core[=0|1] Dump core on crash\n"
1028 " --crash-shell[=0|1] Run shell on crash\n"
1029 " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
1030 " --show-status[=0|1] Show status updates on the console during bootup\n"
1031 #ifdef HAVE_SYSV_COMPAT
1032 " --sysv-console[=0|1] Connect output of SysV scripts to console\n"
1034 " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
1035 " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
1036 " --log-color[=0|1] Highlight important log messages\n"
1037 " --log-location[=0|1] Include code location in log messages\n"
1038 " --default-standard-output= Set default standard output for services\n"
1039 " --default-standard-error= Set default standard error output for services\n",
1040 program_invocation_short_name
);
1045 static int prepare_reexecute(Manager
*m
, FILE **_f
, FDSet
**_fds
) {
1054 /* Make sure nothing is really destructed when we shut down */
1057 if ((r
= manager_open_serialization(m
, &f
)) < 0) {
1058 log_error("Failed to create serialization file: %s", strerror(-r
));
1062 if (!(fds
= fdset_new())) {
1064 log_error("Failed to allocate fd set: %s", strerror(-r
));
1068 if ((r
= manager_serialize(m
, f
, fds
)) < 0) {
1069 log_error("Failed to serialize state: %s", strerror(-r
));
1073 if (fseeko(f
, 0, SEEK_SET
) < 0) {
1074 log_error("Failed to rewind serialization fd: %m");
1078 if ((r
= fd_cloexec(fileno(f
), false)) < 0) {
1079 log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r
));
1083 if ((r
= fdset_cloexec(fds
, false)) < 0) {
1084 log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r
));
1102 static struct dual_timestamp
* parse_initrd_timestamp(struct dual_timestamp
*t
) {
1104 unsigned long long a
, b
;
1108 e
= getenv("RD_TIMESTAMP");
1112 if (sscanf(e
, "%llu %llu", &a
, &b
) != 2)
1115 t
->realtime
= (usec_t
) a
;
1116 t
->monotonic
= (usec_t
) b
;
1121 static void test_mtab(void) {
1124 /* Check that /etc/mtab is a symlink */
1126 if (readlink_malloc("/etc/mtab", &p
) >= 0) {
1129 b
= streq(p
, "/proc/self/mounts") || streq(p
, "/proc/mounts");
1136 log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
1137 "This is not supported anymore. "
1138 "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
1141 static void test_usr(void) {
1143 /* Check that /usr is not a separate fs */
1145 if (dir_is_empty("/usr") <= 0)
1148 log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
1149 "Some things will probably break (sometimes even silently) in mysterious ways. "
1150 "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
1153 static void test_cgroups(void) {
1155 if (access("/proc/cgroups", F_OK
) >= 0)
1158 log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
1159 "Systems without control groups are not supported. "
1160 "We will now sleep for 10s, and then continue boot-up. "
1161 "Expect breakage and please do not file bugs. "
1162 "Instead fix your kernel and enable CONFIG_CGROUPS. "
1163 "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
1168 int main(int argc
, char *argv
[]) {
1170 int r
, retval
= EXIT_FAILURE
;
1171 usec_t before_startup
, after_startup
;
1172 char timespan
[FORMAT_TIMESPAN_MAX
];
1174 bool reexecute
= false;
1175 const char *shutdown_verb
= NULL
;
1176 dual_timestamp initrd_timestamp
= { 0ULL, 0ULL };
1177 static char systemd
[] = "systemd";
1178 bool is_reexec
= false;
1180 bool loaded_policy
= false;
1181 bool arm_reboot_watchdog
= false;
1183 #ifdef HAVE_SYSV_COMPAT
1184 if (getpid() != 1 && strstr(program_invocation_short_name
, "init")) {
1185 /* This is compatibility support for SysV, where
1186 * calling init as a user is identical to telinit. */
1189 execv(SYSTEMCTL_BINARY_PATH
, argv
);
1190 log_error("Failed to exec " SYSTEMCTL_BINARY_PATH
": %m");
1195 /* Determine if this is a reexecution or normal bootup. We do
1196 * the full command line parsing much later, so let's just
1197 * have a quick peek here. */
1199 for (j
= 1; j
< argc
; j
++)
1200 if (streq(argv
[j
], "--deserialize")) {
1205 /* If we get started via the /sbin/init symlink then we are
1206 called 'init'. After a subsequent reexecution we are then
1207 called 'systemd'. That is confusing, hence let's call us
1208 systemd right-away. */
1209 program_invocation_short_name
= systemd
;
1210 prctl(PR_SET_NAME
, systemd
);
1215 log_show_color(isatty(STDERR_FILENO
) > 0);
1216 log_show_location(false);
1217 log_set_max_level(LOG_INFO
);
1219 if (getpid() == 1) {
1220 arg_running_as
= MANAGER_SYSTEM
;
1221 log_set_target(detect_container(NULL
) > 0 ? LOG_TARGET_JOURNAL
: LOG_TARGET_JOURNAL_OR_KMSG
);
1224 if (selinux_setup(&loaded_policy
) < 0)
1226 if (ima_setup() < 0)
1232 if (label_init(NULL
) < 0)
1236 if (hwclock_is_localtime() > 0) {
1239 r
= hwclock_apply_localtime_delta(&min
);
1241 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r
));
1243 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min
);
1247 arg_running_as
= MANAGER_USER
;
1248 log_set_target(LOG_TARGET_AUTO
);
1252 /* Initialize default unit */
1253 if (set_default_unit(SPECIAL_DEFAULT_TARGET
) < 0)
1256 /* By default, mount "cpu" and "cpuacct" together */
1257 arg_join_controllers
= new(char**, 2);
1258 if (!arg_join_controllers
)
1261 arg_join_controllers
[0] = strv_new("cpu", "cpuacct", NULL
);
1262 arg_join_controllers
[1] = NULL
;
1264 if (!arg_join_controllers
[0])
1267 /* Mount /proc, /sys and friends, so that /proc/cmdline and
1268 * /proc/$PID/fd is available. */
1269 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1270 r
= mount_setup(loaded_policy
);
1275 /* Reset all signal handlers. */
1276 assert_se(reset_all_signal_handlers() == 0);
1278 /* If we are init, we can block sigkill. Yay. */
1279 ignore_signals(SIGNALS_IGNORE
, -1);
1281 if (parse_config_file() < 0)
1284 if (arg_running_as
== MANAGER_SYSTEM
)
1285 if (parse_proc_cmdline() < 0)
1288 log_parse_environment();
1290 if (parse_argv(argc
, argv
) < 0)
1293 if (arg_action
== ACTION_TEST
&& geteuid() == 0) {
1294 log_error("Don't run test mode as root.");
1298 if (arg_running_as
== MANAGER_SYSTEM
&&
1299 arg_action
== ACTION_RUN
&&
1300 running_in_chroot() > 0) {
1301 log_error("Cannot be run in a chroot() environment.");
1305 if (arg_action
== ACTION_HELP
) {
1308 } else if (arg_action
== ACTION_DUMP_CONFIGURATION_ITEMS
) {
1309 unit_dump_config_items(stdout
);
1310 retval
= EXIT_SUCCESS
;
1312 } else if (arg_action
== ACTION_DONE
) {
1313 retval
= EXIT_SUCCESS
;
1317 assert_se(arg_action
== ACTION_RUN
|| arg_action
== ACTION_TEST
);
1319 /* Close logging fds, in order not to confuse fdset below */
1322 /* Remember open file descriptors for later deserialization */
1323 if (serialization
) {
1324 r
= fdset_new_fill(&fds
);
1326 log_error("Failed to allocate fd set: %s", strerror(-r
));
1330 assert_se(fdset_remove(fds
, fileno(serialization
)) >= 0);
1332 close_all_fds(NULL
, 0);
1334 /* Set up PATH unless it is already set */
1336 #ifdef HAVE_SPLIT_USR
1337 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
1339 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
1341 arg_running_as
== MANAGER_SYSTEM
);
1343 if (arg_running_as
== MANAGER_SYSTEM
) {
1344 /* Parse the data passed to us. We leave this
1345 * variables set, but the manager later on will not
1346 * pass them on to our children. */
1347 parse_initrd_timestamp(&initrd_timestamp
);
1349 /* Unset some environment variables passed in from the
1350 * kernel that don't really make sense for us. */
1354 /* When we are invoked by a shell, these might be set,
1355 * but make little sense to pass on */
1360 /* When we are invoked by a tool chroot-like such as
1361 * nspawn, these might be set, but make little sense
1364 unsetenv("LOGNAME");
1366 /* All other variables are left as is, so that clients
1367 * can still read them via /proc/1/environ */
1370 /* Move out of the way, so that we won't block unmounts */
1371 assert_se(chdir("/") == 0);
1373 if (arg_running_as
== MANAGER_SYSTEM
) {
1374 /* Become a session leader if we aren't one yet. */
1377 /* Disable the umask logic */
1381 /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
1382 dbus_connection_set_change_sigpipe(FALSE
);
1384 /* Reset the console, but only if this is really init and we
1385 * are freshly booted */
1386 if (arg_running_as
== MANAGER_SYSTEM
&& arg_action
== ACTION_RUN
) {
1387 console_setup(getpid() == 1 && !is_reexec
);
1391 /* Open the logging devices, if possible and necessary */
1394 /* Make sure we leave a core dump without panicing the
1397 install_crash_handler();
1399 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1400 r
= mount_cgroup_controllers(arg_join_controllers
);
1405 log_full(arg_running_as
== MANAGER_SYSTEM
? LOG_INFO
: LOG_DEBUG
,
1406 PACKAGE_STRING
" running in %s mode. (" SYSTEMD_FEATURES
"; " DISTRIBUTION
")", manager_running_as_to_string(arg_running_as
));
1408 if (arg_running_as
== MANAGER_SYSTEM
&& !is_reexec
) {
1411 if (arg_show_status
|| plymouth_running())
1424 if (arg_running_as
== MANAGER_SYSTEM
&& arg_runtime_watchdog
> 0)
1425 watchdog_set_timeout(&arg_runtime_watchdog
);
1427 r
= manager_new(arg_running_as
, &m
);
1429 log_error("Failed to allocate manager object: %s", strerror(-r
));
1433 m
->confirm_spawn
= arg_confirm_spawn
;
1434 #ifdef HAVE_SYSV_COMPAT
1435 m
->sysv_console
= arg_sysv_console
;
1437 m
->default_std_output
= arg_default_std_output
;
1438 m
->default_std_error
= arg_default_std_error
;
1439 m
->runtime_watchdog
= arg_runtime_watchdog
;
1440 m
->shutdown_watchdog
= arg_shutdown_watchdog
;
1442 if (dual_timestamp_is_set(&initrd_timestamp
))
1443 m
->initrd_timestamp
= initrd_timestamp
;
1445 if (arg_default_controllers
)
1446 manager_set_default_controllers(m
, arg_default_controllers
);
1448 manager_set_show_status(m
, arg_show_status
);
1450 before_startup
= now(CLOCK_MONOTONIC
);
1452 r
= manager_startup(m
, serialization
, fds
);
1454 log_error("Failed to fully start up daemon: %s", strerror(-r
));
1457 /* This will close all file descriptors that were opened, but
1458 * not claimed by any unit. */
1464 if (serialization
) {
1465 fclose(serialization
);
1466 serialization
= NULL
;
1469 Unit
*target
= NULL
;
1470 Job
*default_unit_job
;
1472 dbus_error_init(&error
);
1474 log_debug("Activating default unit: %s", arg_default_unit
);
1476 r
= manager_load_unit(m
, arg_default_unit
, NULL
, &error
, &target
);
1478 log_error("Failed to load default target: %s", bus_error(&error
, r
));
1479 dbus_error_free(&error
);
1480 } else if (target
->load_state
== UNIT_ERROR
)
1481 log_error("Failed to load default target: %s", strerror(-target
->load_error
));
1482 else if (target
->load_state
== UNIT_MASKED
)
1483 log_error("Default target masked.");
1485 if (!target
|| target
->load_state
!= UNIT_LOADED
) {
1486 log_info("Trying to load rescue target...");
1488 r
= manager_load_unit(m
, SPECIAL_RESCUE_TARGET
, NULL
, &error
, &target
);
1490 log_error("Failed to load rescue target: %s", bus_error(&error
, r
));
1491 dbus_error_free(&error
);
1493 } else if (target
->load_state
== UNIT_ERROR
) {
1494 log_error("Failed to load rescue target: %s", strerror(-target
->load_error
));
1496 } else if (target
->load_state
== UNIT_MASKED
) {
1497 log_error("Rescue target masked.");
1502 assert(target
->load_state
== UNIT_LOADED
);
1504 if (arg_action
== ACTION_TEST
) {
1505 printf("-> By units:\n");
1506 manager_dump_units(m
, stdout
, "\t");
1509 r
= manager_add_job(m
, JOB_START
, target
, JOB_REPLACE
, false, &error
, &default_unit_job
);
1511 log_error("Failed to start default target: %s", bus_error(&error
, r
));
1512 dbus_error_free(&error
);
1515 m
->default_unit_job_id
= default_unit_job
->id
;
1517 after_startup
= now(CLOCK_MONOTONIC
);
1518 log_full(arg_action
== ACTION_TEST
? LOG_INFO
: LOG_DEBUG
,
1519 "Loaded units and determined initial transaction in %s.",
1520 format_timespan(timespan
, sizeof(timespan
), after_startup
- before_startup
));
1522 if (arg_action
== ACTION_TEST
) {
1523 printf("-> By jobs:\n");
1524 manager_dump_jobs(m
, stdout
, "\t");
1525 retval
= EXIT_SUCCESS
;
1531 r
= manager_loop(m
);
1533 log_error("Failed to run mainloop: %s", strerror(-r
));
1537 switch (m
->exit_code
) {
1540 retval
= EXIT_SUCCESS
;
1544 case MANAGER_RELOAD
:
1545 log_info("Reloading.");
1546 r
= manager_reload(m
);
1548 log_error("Failed to reload: %s", strerror(-r
));
1551 case MANAGER_REEXECUTE
:
1552 if (prepare_reexecute(m
, &serialization
, &fds
) < 0)
1556 log_notice("Reexecuting.");
1559 case MANAGER_REBOOT
:
1560 case MANAGER_POWEROFF
:
1562 case MANAGER_KEXEC
: {
1563 static const char * const table
[_MANAGER_EXIT_CODE_MAX
] = {
1564 [MANAGER_REBOOT
] = "reboot",
1565 [MANAGER_POWEROFF
] = "poweroff",
1566 [MANAGER_HALT
] = "halt",
1567 [MANAGER_KEXEC
] = "kexec"
1570 assert_se(shutdown_verb
= table
[m
->exit_code
]);
1571 arm_reboot_watchdog
= m
->exit_code
== MANAGER_REBOOT
;
1573 log_notice("Shutting down.");
1578 assert_not_reached("Unknown exit code.");
1586 free(arg_default_unit
);
1587 strv_free(arg_default_controllers
);
1588 free_join_controllers();
1595 const char *args
[15];
1599 assert(serialization
);
1602 args
[i
++] = SYSTEMD_BINARY_PATH
;
1604 args
[i
++] = "--log-level";
1605 args
[i
++] = log_level_to_string(log_get_max_level());
1607 args
[i
++] = "--log-target";
1608 args
[i
++] = log_target_to_string(log_get_target());
1610 if (arg_running_as
== MANAGER_SYSTEM
)
1611 args
[i
++] = "--system";
1613 args
[i
++] = "--user";
1616 args
[i
++] = "--dump-core";
1618 if (arg_crash_shell
)
1619 args
[i
++] = "--crash-shell";
1621 if (arg_confirm_spawn
)
1622 args
[i
++] = "--confirm-spawn";
1624 if (arg_show_status
)
1625 args
[i
++] = "--show-status=1";
1627 args
[i
++] = "--show-status=0";
1629 #ifdef HAVE_SYSV_COMPAT
1630 if (arg_sysv_console
)
1631 args
[i
++] = "--sysv-console=1";
1633 args
[i
++] = "--sysv-console=0";
1636 snprintf(sfd
, sizeof(sfd
), "%i", fileno(serialization
));
1639 args
[i
++] = "--deserialize";
1644 assert(i
<= ELEMENTSOF(args
));
1646 /* Close and disarm the watchdog, so that the new
1647 * instance can reinitialize it, but doesn't get
1648 * rebooted while we do that */
1649 watchdog_close(true);
1651 execv(args
[0], (char* const*) args
);
1653 log_error("Failed to reexecute: %m");
1657 fclose(serialization
);
1662 if (shutdown_verb
) {
1663 const char * command_line
[] = {
1664 SYSTEMD_SHUTDOWN_BINARY_PATH
,
1670 if (arm_reboot_watchdog
&& arg_shutdown_watchdog
> 0) {
1673 /* If we reboot let's set the shutdown
1674 * watchdog and tell the shutdown binary to
1675 * repeatedly ping it */
1676 watchdog_set_timeout(&arg_shutdown_watchdog
);
1677 watchdog_close(false);
1679 /* Tell the binary how often to ping */
1680 snprintf(e
, sizeof(e
), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog
);
1683 env_block
= strv_append(environ
, e
);
1685 env_block
= strv_copy(environ
);
1686 watchdog_close(true);
1689 execve(SYSTEMD_SHUTDOWN_BINARY_PATH
, (char **) command_line
, env_block
);
1691 log_error("Failed to execute shutdown binary, freezing: %m");