]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/main.c
switch-root: move switch_root() call into its own .c file
[thirdparty/systemd.git] / src / core / main.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
11 (at your option) any later version.
12
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
ea430986
LP
22#include <dbus/dbus.h>
23
60918275
LP
24#include <stdio.h>
25#include <errno.h>
26#include <string.h>
16354eff 27#include <unistd.h>
4ade7963
LP
28#include <sys/types.h>
29#include <sys/stat.h>
f170852a 30#include <getopt.h>
97c4f35c 31#include <signal.h>
4fc935ca 32#include <sys/wait.h>
80876c20 33#include <fcntl.h>
f3b6a3ed 34#include <sys/prctl.h>
664f88a7 35#include <sys/mount.h>
60918275
LP
36
37#include "manager.h"
16354eff 38#include "log.h"
302e8c4c 39#include "load-fragment.h"
a16e1123 40#include "fdset.h"
514f4ef5 41#include "special.h"
487393e9 42#include "conf-parser.h"
398ef8ba 43#include "bus-errors.h"
ad780f19 44#include "missing.h"
e51bc1a2 45#include "label.h"
302e27c8 46#include "build.h"
06d4c99a 47#include "strv.h"
f6a6225e 48#include "def.h"
b52aae1d 49#include "virt.h"
e96d6be7 50#include "watchdog.h"
664f88a7 51#include "path-util.h"
41669317 52#include "switch-root.h"
60918275 53
b6e66135
LP
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"
bbc98d32 60#include "hwclock.h"
b6e66135
LP
61#include "selinux-setup.h"
62#include "ima-setup.h"
63
f170852a
LP
64static enum {
65 ACTION_RUN,
e965d56d 66 ACTION_HELP,
e537352b 67 ACTION_TEST,
4288f619
LP
68 ACTION_DUMP_CONFIGURATION_ITEMS,
69 ACTION_DONE
fa0f4d8a 70} arg_action = ACTION_RUN;
f170852a 71
fa0f4d8a
LP
72static char *arg_default_unit = NULL;
73static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
74
75static bool arg_dump_core = true;
76static bool arg_crash_shell = false;
77static int arg_crash_chvt = -1;
78static bool arg_confirm_spawn = false;
9e58ff9c 79static bool arg_show_status = true;
07459bb6 80#ifdef HAVE_SYSV_COMPAT
6e98720f 81static bool arg_sysv_console = true;
07459bb6 82#endif
06d4c99a 83static char **arg_default_controllers = NULL;
0c85a4f3 84static char ***arg_join_controllers = NULL;
706343f4 85static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
0a494f1f 86static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
e96d6be7
LP
87static usec_t arg_runtime_watchdog = 0;
88static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
4fc935ca 89
a16e1123 90static FILE* serialization = NULL;
80876c20 91
6f5e3f35
LP
92static void nop_handler(int sig) {
93}
94
93a46b0b 95_noreturn_ static void crash(int sig) {
97c4f35c 96
fa0f4d8a 97 if (!arg_dump_core)
582a507f 98 log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
97c4f35c 99 else {
6f5e3f35 100 struct sigaction sa;
97c4f35c
LP
101 pid_t pid;
102
6f5e3f35
LP
103 /* We want to wait for the core process, hence let's enable SIGCHLD */
104 zero(sa);
105 sa.sa_handler = nop_handler;
106 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
107 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
108
97c4f35c 109 if ((pid = fork()) < 0)
582a507f 110 log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
97c4f35c
LP
111
112 else if (pid == 0) {
97c4f35c
LP
113 struct rlimit rl;
114
115 /* Enable default signal handler for core dump */
116 zero(sa);
117 sa.sa_handler = SIG_DFL;
118 assert_se(sigaction(sig, &sa, NULL) == 0);
119
120 /* Don't limit the core dump size */
121 zero(rl);
122 rl.rlim_cur = RLIM_INFINITY;
123 rl.rlim_max = RLIM_INFINITY;
124 setrlimit(RLIMIT_CORE, &rl);
125
126 /* Just to be sure... */
127 assert_se(chdir("/") == 0);
128
129 /* Raise the signal again */
130 raise(sig);
131
132 assert_not_reached("We shouldn't be here...");
133 _exit(1);
4fc935ca
LP
134
135 } else {
8e12a6ae
LP
136 siginfo_t status;
137 int r;
4fc935ca
LP
138
139 /* Order things nicely. */
8e12a6ae
LP
140 if ((r = wait_for_terminate(pid, &status)) < 0)
141 log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
142 else if (status.si_code != CLD_DUMPED)
582a507f 143 log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
4fc935ca 144 else
582a507f 145 log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
97c4f35c
LP
146 }
147 }
148
fa0f4d8a
LP
149 if (arg_crash_chvt)
150 chvt(arg_crash_chvt);
601f6a1e 151
fa0f4d8a 152 if (arg_crash_shell) {
6f5e3f35
LP
153 struct sigaction sa;
154 pid_t pid;
8c43883a 155
4fc935ca
LP
156 log_info("Executing crash shell in 10s...");
157 sleep(10);
158
6f5e3f35
LP
159 /* Let the kernel reap children for us */
160 zero(sa);
161 sa.sa_handler = SIG_IGN;
162 sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART;
163 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
8c43883a 164
6f5e3f35
LP
165 if ((pid = fork()) < 0)
166 log_error("Failed to fork off crash shell: %s", strerror(errno));
167 else if (pid == 0) {
843d2643 168 int fd, r;
ea5652c2 169
21de3988 170 if ((fd = acquire_terminal("/dev/console", false, true, true)) < 0)
ea5652c2 171 log_error("Failed to acquire terminal: %s", strerror(-fd));
5b2a0903 172 else if ((r = make_stdio(fd)) < 0)
843d2643 173 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
ea5652c2 174
6f5e3f35
LP
175 execl("/bin/sh", "/bin/sh", NULL);
176
177 log_error("execl() failed: %s", strerror(errno));
178 _exit(1);
179 }
c99b188e 180
f8e08a77 181 log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
4fc935ca
LP
182 }
183
184 log_info("Freezing execution.");
97c4f35c
LP
185 freeze();
186}
187
188static void install_crash_handler(void) {
189 struct sigaction sa;
190
191 zero(sa);
192
193 sa.sa_handler = crash;
194 sa.sa_flags = SA_NODEFER;
195
1b91d3e8 196 sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
97c4f35c 197}
f170852a 198
843d2643
LP
199static int console_setup(bool do_reset) {
200 int tty_fd, r;
80876c20 201
843d2643
LP
202 /* If we are init, we connect stdin/stdout/stderr to /dev/null
203 * and make sure we don't have a controlling tty. */
80876c20 204
843d2643
LP
205 release_terminal();
206
207 if (!do_reset)
208 return 0;
80876c20 209
512947d4
MS
210 tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
211 if (tty_fd < 0) {
843d2643
LP
212 log_error("Failed to open /dev/console: %s", strerror(-tty_fd));
213 return -tty_fd;
214 }
80876c20 215
512947d4
MS
216 /* We don't want to force text mode.
217 * plymouth may be showing pictures already from initrd. */
218 r = reset_terminal_fd(tty_fd, false);
219 if (r < 0)
843d2643
LP
220 log_error("Failed to reset /dev/console: %s", strerror(-r));
221
222 close_nointr_nofail(tty_fd);
80876c20
LP
223 return r;
224}
225
f170852a
LP
226static int set_default_unit(const char *u) {
227 char *c;
228
229 assert(u);
230
231 if (!(c = strdup(u)))
232 return -ENOMEM;
233
fa0f4d8a
LP
234 free(arg_default_unit);
235 arg_default_unit = c;
f170852a
LP
236 return 0;
237}
238
239static int parse_proc_cmdline_word(const char *word) {
240
241 static const char * const rlmap[] = {
ed370f5d 242 "emergency", SPECIAL_EMERGENCY_TARGET,
099663ff 243 "-b", SPECIAL_EMERGENCY_TARGET,
ed370f5d
LP
244 "single", SPECIAL_RESCUE_TARGET,
245 "-s", SPECIAL_RESCUE_TARGET,
246 "s", SPECIAL_RESCUE_TARGET,
247 "S", SPECIAL_RESCUE_TARGET,
248 "1", SPECIAL_RESCUE_TARGET,
249 "2", SPECIAL_RUNLEVEL2_TARGET,
250 "3", SPECIAL_RUNLEVEL3_TARGET,
251 "4", SPECIAL_RUNLEVEL4_TARGET,
252 "5", SPECIAL_RUNLEVEL5_TARGET,
f170852a
LP
253 };
254
5192bd19
LP
255 assert(word);
256
2f198e2f
LP
257 if (startswith(word, "systemd.unit="))
258 return set_default_unit(word + 13);
f170852a
LP
259
260 else if (startswith(word, "systemd.log_target=")) {
261
262 if (log_set_target_from_string(word + 19) < 0)
263 log_warning("Failed to parse log target %s. Ignoring.", word + 19);
264
265 } else if (startswith(word, "systemd.log_level=")) {
266
267 if (log_set_max_level_from_string(word + 18) < 0)
268 log_warning("Failed to parse log level %s. Ignoring.", word + 18);
269
bbe63281
LP
270 } else if (startswith(word, "systemd.log_color=")) {
271
272 if (log_show_color_from_string(word + 18) < 0)
273 log_warning("Failed to parse log color setting %s. Ignoring.", word + 18);
274
275 } else if (startswith(word, "systemd.log_location=")) {
276
277 if (log_show_location_from_string(word + 21) < 0)
278 log_warning("Failed to parse log location setting %s. Ignoring.", word + 21);
279
4fc935ca
LP
280 } else if (startswith(word, "systemd.dump_core=")) {
281 int r;
282
283 if ((r = parse_boolean(word + 18)) < 0)
509b6efb 284 log_warning("Failed to parse dump core switch %s. Ignoring.", word + 18);
4fc935ca 285 else
fa0f4d8a 286 arg_dump_core = r;
4fc935ca
LP
287
288 } else if (startswith(word, "systemd.crash_shell=")) {
289 int r;
290
291 if ((r = parse_boolean(word + 20)) < 0)
509b6efb 292 log_warning("Failed to parse crash shell switch %s. Ignoring.", word + 20);
4fc935ca 293 else
fa0f4d8a 294 arg_crash_shell = r;
5e7ee61c
LP
295
296 } else if (startswith(word, "systemd.confirm_spawn=")) {
297 int r;
298
299 if ((r = parse_boolean(word + 22)) < 0)
509b6efb 300 log_warning("Failed to parse confirm spawn switch %s. Ignoring.", word + 22);
5e7ee61c 301 else
fa0f4d8a 302 arg_confirm_spawn = r;
5e7ee61c 303
601f6a1e
LP
304 } else if (startswith(word, "systemd.crash_chvt=")) {
305 int k;
306
307 if (safe_atoi(word + 19, &k) < 0)
509b6efb 308 log_warning("Failed to parse crash chvt switch %s. Ignoring.", word + 19);
601f6a1e 309 else
fa0f4d8a 310 arg_crash_chvt = k;
601f6a1e 311
9e58ff9c
LP
312 } else if (startswith(word, "systemd.show_status=")) {
313 int r;
314
315 if ((r = parse_boolean(word + 20)) < 0)
509b6efb 316 log_warning("Failed to parse show status switch %s. Ignoring.", word + 20);
6e98720f 317 else
9e58ff9c 318 arg_show_status = r;
0a494f1f
LP
319 } else if (startswith(word, "systemd.default_standard_output=")) {
320 int r;
321
322 if ((r = exec_output_from_string(word + 32)) < 0)
509b6efb 323 log_warning("Failed to parse default standard output switch %s. Ignoring.", word + 32);
0a494f1f
LP
324 else
325 arg_default_std_output = r;
326 } else if (startswith(word, "systemd.default_standard_error=")) {
327 int r;
328
329 if ((r = exec_output_from_string(word + 31)) < 0)
509b6efb 330 log_warning("Failed to parse default standard error switch %s. Ignoring.", word + 31);
0a494f1f
LP
331 else
332 arg_default_std_error = r;
9e7c5357
WD
333 } else if (startswith(word, "systemd.setenv=")) {
334 char *cenv, *eq;
335 int r;
336
337 cenv = strdup(word + 15);
338 if (!cenv)
339 return -ENOMEM;
340
341 eq = strchr(cenv, '=');
342 if (!eq) {
343 r = unsetenv(cenv);
344 if (r < 0)
345 log_warning("unsetenv failed %s. Ignoring.", strerror(errno));
346 } else {
347 *eq = 0;
348 r = setenv(cenv, eq + 1, 1);
349 if (r < 0)
350 log_warning("setenv failed %s. Ignoring.", strerror(errno));
351 }
352 free(cenv);
07459bb6 353#ifdef HAVE_SYSV_COMPAT
6e98720f
LP
354 } else if (startswith(word, "systemd.sysv_console=")) {
355 int r;
356
357 if ((r = parse_boolean(word + 21)) < 0)
509b6efb 358 log_warning("Failed to parse SysV console switch %s. Ignoring.", word + 20);
6e98720f
LP
359 else
360 arg_sysv_console = r;
07459bb6 361#endif
9e58ff9c 362
4fc935ca
LP
363 } else if (startswith(word, "systemd.")) {
364
365 log_warning("Unknown kernel switch %s. Ignoring.", word);
366
bbe63281
LP
367 log_info("Supported kernel switches:\n"
368 "systemd.unit=UNIT Default unit to start\n"
bbe63281 369 "systemd.dump_core=0|1 Dump core on crash\n"
9e58ff9c 370 "systemd.crash_shell=0|1 Run shell on crash\n"
bbe63281 371 "systemd.crash_chvt=N Change to VT #N on crash\n"
9e58ff9c 372 "systemd.confirm_spawn=0|1 Confirm every process spawn\n"
6e98720f 373 "systemd.show_status=0|1 Show status updates on the console during bootup\n"
07459bb6 374#ifdef HAVE_SYSV_COMPAT
6e98720f 375 "systemd.sysv_console=0|1 Connect output of SysV scripts to console\n"
07459bb6 376#endif
4cfa2c99 377 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
6e98720f
LP
378 " Log target\n"
379 "systemd.log_level=LEVEL Log level\n"
380 "systemd.log_color=0|1 Highlight important log messages\n"
0a494f1f 381 "systemd.log_location=0|1 Include code location in log messages\n"
706343f4 382 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
0a494f1f 383 " Set default log output for services\n"
706343f4 384 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
0a494f1f 385 " Set default log error output for services\n");
4fc935ca 386
a9c501a5 387 } else if (streq(word, "quiet")) {
6e98720f 388 arg_show_status = false;
07459bb6 389#ifdef HAVE_SYSV_COMPAT
6e98720f 390 arg_sysv_console = false;
07459bb6 391#endif
9e58ff9c 392 } else {
f170852a
LP
393 unsigned i;
394
395 /* SysV compatibility */
f170852a
LP
396 for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
397 if (streq(word, rlmap[i]))
398 return set_default_unit(rlmap[i+1]);
399 }
400
401 return 0;
402}
403
f975e971 404static int config_parse_level2(
487393e9
LP
405 const char *filename,
406 unsigned line,
407 const char *section,
408 const char *lvalue,
3731f1ea 409 int ltype,
487393e9
LP
410 const char *rvalue,
411 void *data,
412 void *userdata) {
413
414 assert(filename);
415 assert(lvalue);
416 assert(rvalue);
417
418 log_set_max_level_from_string(rvalue);
419 return 0;
420}
421
422static int config_parse_target(
423 const char *filename,
424 unsigned line,
425 const char *section,
426 const char *lvalue,
3731f1ea 427 int ltype,
487393e9
LP
428 const char *rvalue,
429 void *data,
430 void *userdata) {
431
432 assert(filename);
433 assert(lvalue);
434 assert(rvalue);
435
436 log_set_target_from_string(rvalue);
437 return 0;
438}
439
440static int config_parse_color(
441 const char *filename,
442 unsigned line,
443 const char *section,
444 const char *lvalue,
3731f1ea 445 int ltype,
487393e9
LP
446 const char *rvalue,
447 void *data,
448 void *userdata) {
449
450 assert(filename);
451 assert(lvalue);
452 assert(rvalue);
453
454 log_show_color_from_string(rvalue);
455 return 0;
456}
457
458static int config_parse_location(
459 const char *filename,
460 unsigned line,
461 const char *section,
462 const char *lvalue,
3731f1ea 463 int ltype,
487393e9
LP
464 const char *rvalue,
465 void *data,
466 void *userdata) {
467
468 assert(filename);
469 assert(lvalue);
470 assert(rvalue);
471
472 log_show_location_from_string(rvalue);
473 return 0;
474}
475
f975e971 476static int config_parse_cpu_affinity2(
487393e9
LP
477 const char *filename,
478 unsigned line,
479 const char *section,
480 const char *lvalue,
3731f1ea 481 int ltype,
487393e9
LP
482 const char *rvalue,
483 void *data,
484 void *userdata) {
485
486 char *w;
487 size_t l;
488 char *state;
489 cpu_set_t *c = NULL;
490 unsigned ncpus = 0;
491
492 assert(filename);
493 assert(lvalue);
494 assert(rvalue);
495
f60f22df 496 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
487393e9
LP
497 char *t;
498 int r;
499 unsigned cpu;
500
501 if (!(t = strndup(w, l)))
502 return -ENOMEM;
503
504 r = safe_atou(t, &cpu);
505 free(t);
506
507 if (!c)
508 if (!(c = cpu_set_malloc(&ncpus)))
509 return -ENOMEM;
510
511 if (r < 0 || cpu >= ncpus) {
512 log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
513 CPU_FREE(c);
514 return -EBADMSG;
515 }
516
517 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
518 }
519
520 if (c) {
521 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
522 log_warning("Failed to set CPU affinity: %m");
523
524 CPU_FREE(c);
525 }
526
527 return 0;
528}
529
0c85a4f3
LP
530static void strv_free_free(char ***l) {
531 char ***i;
532
533 if (!l)
534 return;
535
536 for (i = l; *i; i++)
537 strv_free(*i);
538
539 free(l);
540}
541
542static void free_join_controllers(void) {
543 if (!arg_join_controllers)
544 return;
545
546 strv_free_free(arg_join_controllers);
547 arg_join_controllers = NULL;
548}
549
550static int config_parse_join_controllers(
551 const char *filename,
552 unsigned line,
553 const char *section,
554 const char *lvalue,
555 int ltype,
556 const char *rvalue,
557 void *data,
558 void *userdata) {
559
560 unsigned n = 0;
561 char *state, *w;
562 size_t length;
563
564 assert(filename);
565 assert(lvalue);
566 assert(rvalue);
567
568 free_join_controllers();
569
570 FOREACH_WORD_QUOTED(w, length, rvalue, state) {
571 char *s, **l;
572
573 s = strndup(w, length);
574 if (!s)
575 return -ENOMEM;
576
577 l = strv_split(s, ",");
578 free(s);
579
580 strv_uniq(l);
581
582 if (strv_length(l) <= 1) {
583 strv_free(l);
584 continue;
585 }
586
587 if (!arg_join_controllers) {
588 arg_join_controllers = new(char**, 2);
589 if (!arg_join_controllers) {
590 strv_free(l);
591 return -ENOMEM;
592 }
593
594 arg_join_controllers[0] = l;
595 arg_join_controllers[1] = NULL;
596
597 n = 1;
598 } else {
599 char ***a;
600 char ***t;
601
602 t = new0(char**, n+2);
603 if (!t) {
604 strv_free(l);
605 return -ENOMEM;
606 }
607
608 n = 0;
609
610 for (a = arg_join_controllers; *a; a++) {
611
612 if (strv_overlap(*a, l)) {
613 char **c;
614
615 c = strv_merge(*a, l);
616 if (!c) {
617 strv_free(l);
618 strv_free_free(t);
619 return -ENOMEM;
620 }
621
622 strv_free(l);
623 l = c;
624 } else {
625 char **c;
626
627 c = strv_copy(*a);
628 if (!c) {
629 strv_free(l);
630 strv_free_free(t);
631 return -ENOMEM;
632 }
633
634 t[n++] = c;
635 }
636 }
637
638 t[n++] = strv_uniq(l);
639
640 strv_free_free(arg_join_controllers);
641 arg_join_controllers = t;
642 }
643 }
644
645 return 0;
646}
647
487393e9
LP
648static int parse_config_file(void) {
649
f975e971
LP
650 const ConfigTableItem items[] = {
651 { "Manager", "LogLevel", config_parse_level2, 0, NULL },
652 { "Manager", "LogTarget", config_parse_target, 0, NULL },
653 { "Manager", "LogColor", config_parse_color, 0, NULL },
654 { "Manager", "LogLocation", config_parse_location, 0, NULL },
655 { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
656 { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
657 { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
07459bb6 658#ifdef HAVE_SYSV_COMPAT
f975e971 659 { "Manager", "SysVConsole", config_parse_bool, 0, &arg_sysv_console },
07459bb6 660#endif
f975e971
LP
661 { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
662 { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
f975e971
LP
663 { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers },
664 { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
665 { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
0c85a4f3 666 { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
e96d6be7
LP
667 { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog },
668 { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog },
f975e971 669 { NULL, NULL, NULL, 0, NULL }
487393e9
LP
670 };
671
672 FILE *f;
673 const char *fn;
674 int r;
675
af2d49f7 676 fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
f975e971
LP
677 f = fopen(fn, "re");
678 if (!f) {
487393e9
LP
679 if (errno == ENOENT)
680 return 0;
681
682 log_warning("Failed to open configuration file '%s': %m", fn);
683 return 0;
684 }
685
f975e971
LP
686 r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
687 if (r < 0)
487393e9
LP
688 log_warning("Failed to parse configuration file: %s", strerror(-r));
689
690 fclose(f);
691
692 return 0;
693}
694
f170852a 695static int parse_proc_cmdline(void) {
52661efd 696 char *line, *w, *state;
f170852a 697 int r;
f170852a 698 size_t l;
f170852a 699
b770165a
LP
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)
703 return 0;
704
f170852a 705 if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
e364ad06 706 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
f170852a
LP
707 return 0;
708 }
709
710 FOREACH_WORD_QUOTED(w, l, line, state) {
711 char *word;
712
713 if (!(word = strndup(w, l))) {
714 r = -ENOMEM;
715 goto finish;
716 }
717
718 r = parse_proc_cmdline_word(word);
719 free(word);
720
721 if (r < 0)
722 goto finish;
723 }
724
725 r = 0;
726
727finish:
728 free(line);
729 return r;
730}
731
732static int parse_argv(int argc, char *argv[]) {
733
734 enum {
735 ARG_LOG_LEVEL = 0x100,
736 ARG_LOG_TARGET,
bbe63281
LP
737 ARG_LOG_COLOR,
738 ARG_LOG_LOCATION,
2f198e2f 739 ARG_UNIT,
edb9aaa8 740 ARG_SYSTEM,
af2d49f7 741 ARG_USER,
e537352b 742 ARG_TEST,
80876c20 743 ARG_DUMP_CONFIGURATION_ITEMS,
9e58ff9c
LP
744 ARG_DUMP_CORE,
745 ARG_CRASH_SHELL,
a16e1123 746 ARG_CONFIRM_SPAWN,
9e58ff9c 747 ARG_SHOW_STATUS,
6e98720f 748 ARG_SYSV_CONSOLE,
4288f619 749 ARG_DESERIALIZE,
d03bc1b8 750 ARG_SWITCHEDROOT,
0a494f1f
LP
751 ARG_INTROSPECT,
752 ARG_DEFAULT_STD_OUTPUT,
753 ARG_DEFAULT_STD_ERROR
f170852a
LP
754 };
755
756 static const struct option options[] = {
a16e1123
LP
757 { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
758 { "log-target", required_argument, NULL, ARG_LOG_TARGET },
bbe63281
LP
759 { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
760 { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
2f198e2f 761 { "unit", required_argument, NULL, ARG_UNIT },
edb9aaa8 762 { "system", no_argument, NULL, ARG_SYSTEM },
af2d49f7 763 { "user", no_argument, NULL, ARG_USER },
a16e1123
LP
764 { "test", no_argument, NULL, ARG_TEST },
765 { "help", no_argument, NULL, 'h' },
766 { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
a5d87bf0
LP
767 { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
768 { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
769 { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
6e98720f 770 { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
07459bb6 771#ifdef HAVE_SYSV_COMPAT
6e98720f 772 { "sysv-console", optional_argument, NULL, ARG_SYSV_CONSOLE },
07459bb6 773#endif
a16e1123 774 { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
d03bc1b8 775 { "switchedroot", no_argument, NULL, ARG_SWITCHEDROOT },
4288f619 776 { "introspect", optional_argument, NULL, ARG_INTROSPECT },
0a494f1f
LP
777 { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
778 { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
a16e1123 779 { NULL, 0, NULL, 0 }
f170852a
LP
780 };
781
782 int c, r;
783
784 assert(argc >= 1);
785 assert(argv);
786
b770165a
LP
787 if (getpid() == 1)
788 opterr = 0;
789
099663ff 790 while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
f170852a
LP
791
792 switch (c) {
793
794 case ARG_LOG_LEVEL:
795 if ((r = log_set_max_level_from_string(optarg)) < 0) {
796 log_error("Failed to parse log level %s.", optarg);
797 return r;
798 }
799
800 break;
801
802 case ARG_LOG_TARGET:
803
804 if ((r = log_set_target_from_string(optarg)) < 0) {
805 log_error("Failed to parse log target %s.", optarg);
806 return r;
807 }
808
809 break;
810
bbe63281
LP
811 case ARG_LOG_COLOR:
812
d0b170c8
LP
813 if (optarg) {
814 if ((r = log_show_color_from_string(optarg)) < 0) {
815 log_error("Failed to parse log color setting %s.", optarg);
816 return r;
817 }
818 } else
819 log_show_color(true);
bbe63281
LP
820
821 break;
822
823 case ARG_LOG_LOCATION:
824
d0b170c8
LP
825 if (optarg) {
826 if ((r = log_show_location_from_string(optarg)) < 0) {
827 log_error("Failed to parse log location setting %s.", optarg);
828 return r;
829 }
830 } else
831 log_show_location(true);
bbe63281
LP
832
833 break;
834
0a494f1f
LP
835 case ARG_DEFAULT_STD_OUTPUT:
836
837 if ((r = exec_output_from_string(optarg)) < 0) {
838 log_error("Failed to parse default standard output setting %s.", optarg);
839 return r;
840 } else
841 arg_default_std_output = r;
842 break;
843
844 case ARG_DEFAULT_STD_ERROR:
845
846 if ((r = exec_output_from_string(optarg)) < 0) {
847 log_error("Failed to parse default standard error output setting %s.", optarg);
848 return r;
849 } else
850 arg_default_std_error = r;
851 break;
852
2f198e2f 853 case ARG_UNIT:
f170852a
LP
854
855 if ((r = set_default_unit(optarg)) < 0) {
856 log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
857 return r;
858 }
859
860 break;
861
edb9aaa8
LP
862 case ARG_SYSTEM:
863 arg_running_as = MANAGER_SYSTEM;
864 break;
a5dab5ce 865
af2d49f7
LP
866 case ARG_USER:
867 arg_running_as = MANAGER_USER;
a5dab5ce 868 break;
a5dab5ce 869
e965d56d 870 case ARG_TEST:
fa0f4d8a 871 arg_action = ACTION_TEST;
e965d56d
LP
872 break;
873
e537352b 874 case ARG_DUMP_CONFIGURATION_ITEMS:
fa0f4d8a 875 arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
e537352b
LP
876 break;
877
9e58ff9c 878 case ARG_DUMP_CORE:
a5d87bf0
LP
879 r = optarg ? parse_boolean(optarg) : 1;
880 if (r < 0) {
881 log_error("Failed to parse dump core boolean %s.", optarg);
882 return r;
883 }
884 arg_dump_core = r;
9e58ff9c
LP
885 break;
886
887 case ARG_CRASH_SHELL:
a5d87bf0
LP
888 r = optarg ? parse_boolean(optarg) : 1;
889 if (r < 0) {
890 log_error("Failed to parse crash shell boolean %s.", optarg);
891 return r;
892 }
893 arg_crash_shell = r;
9e58ff9c
LP
894 break;
895
80876c20 896 case ARG_CONFIRM_SPAWN:
a5d87bf0
LP
897 r = optarg ? parse_boolean(optarg) : 1;
898 if (r < 0) {
899 log_error("Failed to parse confirm spawn boolean %s.", optarg);
900 return r;
901 }
902 arg_confirm_spawn = r;
80876c20
LP
903 break;
904
9e58ff9c 905 case ARG_SHOW_STATUS:
a5d87bf0
LP
906 r = optarg ? parse_boolean(optarg) : 1;
907 if (r < 0) {
908 log_error("Failed to parse show status boolean %s.", optarg);
909 return r;
910 }
911 arg_show_status = r;
6e98720f 912 break;
a5d87bf0 913
07459bb6 914#ifdef HAVE_SYSV_COMPAT
6e98720f 915 case ARG_SYSV_CONSOLE:
a5d87bf0
LP
916 r = optarg ? parse_boolean(optarg) : 1;
917 if (r < 0) {
918 log_error("Failed to parse SysV console boolean %s.", optarg);
919 return r;
920 }
921 arg_sysv_console = r;
9e58ff9c 922 break;
07459bb6 923#endif
9e58ff9c 924
a16e1123
LP
925 case ARG_DESERIALIZE: {
926 int fd;
927 FILE *f;
928
929 if ((r = safe_atoi(optarg, &fd)) < 0 || fd < 0) {
930 log_error("Failed to parse deserialize option %s.", optarg);
931 return r;
932 }
933
934 if (!(f = fdopen(fd, "r"))) {
935 log_error("Failed to open serialization fd: %m");
936 return r;
937 }
938
939 if (serialization)
940 fclose(serialization);
941
942 serialization = f;
943
944 break;
945 }
946
d03bc1b8
HH
947 case ARG_SWITCHEDROOT:
948 /* Nothing special yet */
949 break;
950
4288f619
LP
951 case ARG_INTROSPECT: {
952 const char * const * i = NULL;
953
954 for (i = bus_interface_table; *i; i += 2)
955 if (!optarg || streq(i[0], optarg)) {
956 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
957 "<node>\n", stdout);
958 fputs(i[1], stdout);
959 fputs("</node>\n", stdout);
960
961 if (optarg)
962 break;
963 }
964
965 if (!i[0] && optarg)
966 log_error("Unknown interface %s.", optarg);
967
fa0f4d8a 968 arg_action = ACTION_DONE;
4288f619
LP
969 break;
970 }
971
f170852a 972 case 'h':
fa0f4d8a 973 arg_action = ACTION_HELP;
f170852a
LP
974 break;
975
1d2e23ab
LP
976 case 'D':
977 log_set_max_level(LOG_DEBUG);
978 break;
979
099663ff
LP
980 case 'b':
981 case 's':
982 case 'z':
983 /* Just to eat away the sysvinit kernel
984 * cmdline args without getopt() error
985 * messages that we'll parse in
986 * parse_proc_cmdline_word() or ignore. */
f170852a 987
099663ff 988 case '?':
f170852a 989 default:
099663ff
LP
990 if (getpid() != 1) {
991 log_error("Unknown option code %c", c);
992 return -EINVAL;
993 }
994
995 break;
f170852a
LP
996 }
997
d821e6d6
LP
998 if (optind < argc && getpid() != 1) {
999 /* Hmm, when we aren't run as init system
1000 * let's complain about excess arguments */
1001
1002 log_error("Excess arguments.");
1003 return -EINVAL;
1004 }
1005
1006 if (detect_container(NULL) > 0) {
1007 char **a;
1008
1009 /* All /proc/cmdline arguments the kernel didn't
1010 * understand it passed to us. We're not really
1011 * interested in that usually since /proc/cmdline is
1012 * more interesting and complete. With one exception:
1013 * if we are run in a container /proc/cmdline is not
1014 * relevant for the container, hence we rely on argv[]
1015 * instead. */
1016
1017 for (a = argv; a < argv + argc; a++)
1018 if ((r = parse_proc_cmdline_word(*a)) < 0)
1019 return r;
51f0e189
LP
1020 }
1021
f170852a
LP
1022 return 0;
1023}
1024
1025static int help(void) {
1026
2e33c433 1027 printf("%s [OPTIONS...]\n\n"
af2d49f7 1028 "Starts up and maintains the system or user services.\n\n"
e537352b 1029 " -h --help Show this help\n"
e537352b 1030 " --test Determine startup sequence, dump it and exit\n"
80876c20 1031 " --dump-configuration-items Dump understood unit configuration items\n"
bbe63281 1032 " --introspect[=INTERFACE] Extract D-Bus interface data\n"
9e58ff9c 1033 " --unit=UNIT Set default unit\n"
edb9aaa8 1034 " --system Run a system instance, even if PID != 1\n"
af2d49f7 1035 " --user Run a user instance\n"
a5d87bf0
LP
1036 " --dump-core[=0|1] Dump core on crash\n"
1037 " --crash-shell[=0|1] Run shell on crash\n"
1038 " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
6e98720f 1039 " --show-status[=0|1] Show status updates on the console during bootup\n"
07459bb6 1040#ifdef HAVE_SYSV_COMPAT
6e98720f 1041 " --sysv-console[=0|1] Connect output of SysV scripts to console\n"
07459bb6 1042#endif
4cfa2c99 1043 " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
9e58ff9c 1044 " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
2218198b 1045 " --log-color[=0|1] Highlight important log messages\n"
0a494f1f
LP
1046 " --log-location[=0|1] Include code location in log messages\n"
1047 " --default-standard-output= Set default standard output for services\n"
1048 " --default-standard-error= Set default standard error output for services\n",
5b6319dc 1049 program_invocation_short_name);
f170852a
LP
1050
1051 return 0;
1052}
1053
a16e1123
LP
1054static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds) {
1055 FILE *f = NULL;
1056 FDSet *fds = NULL;
1057 int r;
1058
1059 assert(m);
1060 assert(_f);
1061 assert(_fds);
1062
a7556052
LP
1063 /* Make sure nothing is really destructed when we shut down */
1064 m->n_reloading ++;
1065
d8d5ab98 1066 if ((r = manager_open_serialization(m, &f)) < 0) {
35b8ca3a 1067 log_error("Failed to create serialization file: %s", strerror(-r));
a16e1123
LP
1068 goto fail;
1069 }
1070
1071 if (!(fds = fdset_new())) {
1072 r = -ENOMEM;
1073 log_error("Failed to allocate fd set: %s", strerror(-r));
1074 goto fail;
1075 }
1076
1077 if ((r = manager_serialize(m, f, fds)) < 0) {
1078 log_error("Failed to serialize state: %s", strerror(-r));
1079 goto fail;
1080 }
1081
1082 if (fseeko(f, 0, SEEK_SET) < 0) {
1083 log_error("Failed to rewind serialization fd: %m");
1084 goto fail;
1085 }
1086
1087 if ((r = fd_cloexec(fileno(f), false)) < 0) {
1088 log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
1089 goto fail;
1090 }
1091
1092 if ((r = fdset_cloexec(fds, false)) < 0) {
1093 log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
1094 goto fail;
1095 }
1096
1097 *_f = f;
1098 *_fds = fds;
1099
1100 return 0;
1101
1102fail:
1103 fdset_free(fds);
1104
1105 if (f)
1106 fclose(f);
1107
1108 return r;
1109}
1110
e9ddabc2
LP
1111static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
1112 const char *e;
1113 unsigned long long a, b;
1114
1115 assert(t);
1116
966a5d37
LP
1117 e = getenv("RD_TIMESTAMP");
1118 if (!e)
e9ddabc2
LP
1119 return NULL;
1120
1121 if (sscanf(e, "%llu %llu", &a, &b) != 2)
1122 return NULL;
1123
1124 t->realtime = (usec_t) a;
1125 t->monotonic = (usec_t) b;
1126
1127 return t;
1128}
1129
6ee5bbf8
LP
1130static void test_mtab(void) {
1131 char *p;
1132
80758717
LP
1133 /* Check that /etc/mtab is a symlink */
1134
6ee5bbf8
LP
1135 if (readlink_malloc("/etc/mtab", &p) >= 0) {
1136 bool b;
1137
ed86ebc4 1138 b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
6ee5bbf8
LP
1139 free(p);
1140
1141 if (b)
1142 return;
1143 }
1144
80758717
LP
1145 log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
1146 "This is not supported anymore. "
1147 "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
1148}
1149
1150static void test_usr(void) {
80758717 1151
ed1c99fc 1152 /* Check that /usr is not a separate fs */
80758717 1153
871c44a7
LP
1154 if (dir_is_empty("/usr") <= 0)
1155 return;
1156
2376ce13 1157 log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
871c44a7
LP
1158 "Some things will probably break (sometimes even silently) in mysterious ways. "
1159 "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
1160}
1161
1162static void test_cgroups(void) {
1163
1164 if (access("/proc/cgroups", F_OK) >= 0)
1165 return;
1166
1167 log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
1168 "Systems without control groups are not supported. "
1169 "We will now sleep for 10s, and then continue boot-up. "
1170 "Expect breakage and please do not file bugs. "
966a5d37
LP
1171 "Instead fix your kernel and enable CONFIG_CGROUPS. "
1172 "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
871c44a7
LP
1173
1174 sleep(10);
6ee5bbf8
LP
1175}
1176
60918275
LP
1177int main(int argc, char *argv[]) {
1178 Manager *m = NULL;
22f4096c 1179 int r, retval = EXIT_FAILURE;
9d76d730
LP
1180 usec_t before_startup, after_startup;
1181 char timespan[FORMAT_TIMESPAN_MAX];
a16e1123
LP
1182 FDSet *fds = NULL;
1183 bool reexecute = false;
b9080b03 1184 const char *shutdown_verb = NULL;
e9ddabc2 1185 dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
5d6b1584 1186 static char systemd[] = "systemd";
0b3325e7
LP
1187 bool is_reexec = false;
1188 int j;
1189 bool loaded_policy = false;
e96d6be7 1190 bool arm_reboot_watchdog = false;
41669317 1191 char *switch_root_dir = NULL, *switch_root_init = NULL;
27b14a22 1192
058dc6f3 1193#ifdef HAVE_SYSV_COMPAT
2cb1a60d 1194 if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
35b8ca3a 1195 /* This is compatibility support for SysV, where
2cb1a60d
LP
1196 * calling init as a user is identical to telinit. */
1197
1198 errno = -ENOENT;
1199 execv(SYSTEMCTL_BINARY_PATH, argv);
1200 log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
1201 return 1;
1202 }
058dc6f3 1203#endif
2cb1a60d 1204
0b3325e7
LP
1205 /* Determine if this is a reexecution or normal bootup. We do
1206 * the full command line parsing much later, so let's just
1207 * have a quick peek here. */
1208
1209 for (j = 1; j < argc; j++)
1210 if (streq(argv[j], "--deserialize")) {
0b3325e7 1211 is_reexec = true;
7aaa27f2 1212 break;
0b3325e7
LP
1213 }
1214
d03bc1b8
HH
1215 /* If we have switched root, do all the special things */
1216 for (j = 1; j < argc; j++)
1217 if (streq(argv[j], "--switchedroot")) {
1218 is_reexec = false;
1219 break;
1220 }
1221
f3b6a3ed
LP
1222 /* If we get started via the /sbin/init symlink then we are
1223 called 'init'. After a subsequent reexecution we are then
1224 called 'systemd'. That is confusing, hence let's call us
1225 systemd right-away. */
f3b6a3ed
LP
1226 program_invocation_short_name = systemd;
1227 prctl(PR_SET_NAME, systemd);
5d6b1584 1228
9a0e6896
LP
1229 saved_argv = argv;
1230 saved_argc = argc;
f3b6a3ed 1231
2cc59dbf 1232 log_show_color(isatty(STDERR_FILENO) > 0);
bbe63281 1233 log_show_location(false);
7c706717 1234 log_set_max_level(LOG_INFO);
bbe63281 1235
843d2643 1236 if (getpid() == 1) {
c3ba6250
HH
1237 if (in_initrd()) {
1238 char *rd_timestamp = NULL;
1239
1240 dual_timestamp_get(&initrd_timestamp);
1241 asprintf(&rd_timestamp, "%llu %llu",
1242 (unsigned long long) initrd_timestamp.realtime,
1243 (unsigned long long) initrd_timestamp.monotonic);
1244 if (rd_timestamp) {
1245 setenv("RD_TIMESTAMP", rd_timestamp, 1);
1246 free(rd_timestamp);
1247 }
1248 }
1249
fa0f4d8a 1250 arg_running_as = MANAGER_SYSTEM;
a0a38448 1251 log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG);
0ff4cdd9 1252
81611586 1253 if (!is_reexec) {
0b3325e7
LP
1254 if (selinux_setup(&loaded_policy) < 0)
1255 goto finish;
81611586
RS
1256 if (ima_setup() < 0)
1257 goto finish;
1258 }
0b3325e7
LP
1259
1260 log_open();
c4dcdb9f 1261
e9a5ef7c 1262 if (label_init(NULL) < 0)
0ff4cdd9 1263 goto finish;
7948c4df 1264
0b3325e7
LP
1265 if (!is_reexec)
1266 if (hwclock_is_localtime() > 0) {
1267 int min;
7948c4df 1268
0b3325e7
LP
1269 r = hwclock_apply_localtime_delta(&min);
1270 if (r < 0)
1271 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
1272 else
1273 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
1274 }
871e5809 1275
bbe63281 1276 } else {
af2d49f7 1277 arg_running_as = MANAGER_USER;
eeecf6e6 1278 log_set_target(LOG_TARGET_AUTO);
871e5809 1279 log_open();
bbe63281 1280 }
a5dab5ce 1281
0c85a4f3 1282 /* Initialize default unit */
f170852a
LP
1283 if (set_default_unit(SPECIAL_DEFAULT_TARGET) < 0)
1284 goto finish;
60918275 1285
0c85a4f3
LP
1286 /* By default, mount "cpu" and "cpuacct" together */
1287 arg_join_controllers = new(char**, 2);
1288 if (!arg_join_controllers)
1289 goto finish;
1290
1291 arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
1292 arg_join_controllers[1] = NULL;
1293
1294 if (!arg_join_controllers[0])
1295 goto finish;
1296
f170852a
LP
1297 /* Mount /proc, /sys and friends, so that /proc/cmdline and
1298 * /proc/$PID/fd is available. */
0c85a4f3
LP
1299 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1300 r = mount_setup(loaded_policy);
1301 if (r < 0)
8efe3c01 1302 goto finish;
0c85a4f3 1303 }
4ade7963
LP
1304
1305 /* Reset all signal handlers. */
1306 assert_se(reset_all_signal_handlers() == 0);
1307
078e4539 1308 /* If we are init, we can block sigkill. Yay. */
9a34ec5f 1309 ignore_signals(SIGNALS_IGNORE, -1);
078e4539 1310
487393e9
LP
1311 if (parse_config_file() < 0)
1312 goto finish;
1313
fa0f4d8a 1314 if (arg_running_as == MANAGER_SYSTEM)
a5dab5ce
LP
1315 if (parse_proc_cmdline() < 0)
1316 goto finish;
f170852a
LP
1317
1318 log_parse_environment();
1319
1320 if (parse_argv(argc, argv) < 0)
1321 goto finish;
1322
b5c6cf87
LP
1323 if (arg_action == ACTION_TEST && geteuid() == 0) {
1324 log_error("Don't run test mode as root.");
1325 goto finish;
1326 }
1327
fe783b03
LP
1328 if (arg_running_as == MANAGER_SYSTEM &&
1329 arg_action == ACTION_RUN &&
1330 running_in_chroot() > 0) {
1331 log_error("Cannot be run in a chroot() environment.");
1332 goto finish;
1333 }
1334
fa0f4d8a 1335 if (arg_action == ACTION_HELP) {
f170852a
LP
1336 retval = help();
1337 goto finish;
fa0f4d8a 1338 } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
e537352b 1339 unit_dump_config_items(stdout);
22f4096c 1340 retval = EXIT_SUCCESS;
e537352b 1341 goto finish;
fa0f4d8a 1342 } else if (arg_action == ACTION_DONE) {
22f4096c 1343 retval = EXIT_SUCCESS;
4288f619 1344 goto finish;
f170852a
LP
1345 }
1346
fa0f4d8a 1347 assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
f170852a 1348
871e5809
LP
1349 /* Close logging fds, in order not to confuse fdset below */
1350 log_close();
1351
a16e1123
LP
1352 /* Remember open file descriptors for later deserialization */
1353 if (serialization) {
966a5d37
LP
1354 r = fdset_new_fill(&fds);
1355 if (r < 0) {
a16e1123
LP
1356 log_error("Failed to allocate fd set: %s", strerror(-r));
1357 goto finish;
1358 }
1359
1360 assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
1361 } else
1362 close_all_fds(NULL, 0);
1363
09082a94 1364 /* Set up PATH unless it is already set */
e537352b 1365 setenv("PATH",
2c6db6fb 1366#ifdef HAVE_SPLIT_USR
e537352b 1367 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
2c6db6fb
LP
1368#else
1369 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
1370#endif
fa0f4d8a 1371 arg_running_as == MANAGER_SYSTEM);
09082a94 1372
39439087 1373 if (arg_running_as == MANAGER_SYSTEM) {
71ecc858
LP
1374 /* Parse the data passed to us. We leave this
1375 * variables set, but the manager later on will not
1376 * pass them on to our children. */
c3ba6250
HH
1377 if(!in_initrd())
1378 parse_initrd_timestamp(&initrd_timestamp);
e9ddabc2
LP
1379
1380 /* Unset some environment variables passed in from the
1381 * kernel that don't really make sense for us. */
39439087
LP
1382 unsetenv("HOME");
1383 unsetenv("TERM");
b770165a 1384
9543ad16
LP
1385 /* When we are invoked by a shell, these might be set,
1386 * but make little sense to pass on */
1387 unsetenv("PWD");
1388 unsetenv("SHLVL");
1389 unsetenv("_");
1390
9f28b98e
LP
1391 /* When we are invoked by a tool chroot-like such as
1392 * nspawn, these might be set, but make little sense
1393 * to pass on */
1394 unsetenv("USER");
1395 unsetenv("LOGNAME");
1396
b770165a
LP
1397 /* All other variables are left as is, so that clients
1398 * can still read them via /proc/1/environ */
39439087 1399 }
1104f3c1 1400
f170852a
LP
1401 /* Move out of the way, so that we won't block unmounts */
1402 assert_se(chdir("/") == 0);
1403
fa0f4d8a 1404 if (arg_running_as == MANAGER_SYSTEM) {
80876c20
LP
1405 /* Become a session leader if we aren't one yet. */
1406 setsid();
4ade7963 1407
80876c20
LP
1408 /* Disable the umask logic */
1409 umask(0);
1410 }
1411
843d2643
LP
1412 /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
1413 dbus_connection_set_change_sigpipe(FALSE);
1414
2146621b
LP
1415 /* Reset the console, but only if this is really init and we
1416 * are freshly booted */
fa0f4d8a 1417 if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) {
0b3325e7 1418 console_setup(getpid() == 1 && !is_reexec);
843d2643
LP
1419 make_null_stdio();
1420 }
4ade7963 1421
18149b9f 1422 /* Open the logging devices, if possible and necessary */
843d2643 1423 log_open();
4ade7963 1424
5373d602
LP
1425 /* Make sure we leave a core dump without panicing the
1426 * kernel. */
4fc935ca
LP
1427 if (getpid() == 1)
1428 install_crash_handler();
97c4f35c 1429
0c85a4f3
LP
1430 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1431 r = mount_cgroup_controllers(arg_join_controllers);
1432 if (r < 0)
1433 goto finish;
1434 }
1435
302e27c8 1436 log_full(arg_running_as == MANAGER_SYSTEM ? LOG_INFO : LOG_DEBUG,
7d568925 1437 PACKAGE_STRING " running in %s mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")", manager_running_as_to_string(arg_running_as));
a5dab5ce 1438
0b3325e7 1439 if (arg_running_as == MANAGER_SYSTEM && !is_reexec) {
72bca11b
LP
1440 locale_setup();
1441
6faa1114 1442 if (arg_show_status || plymouth_running())
888c6216
LP
1443 status_welcome();
1444
888c6216
LP
1445 kmod_setup();
1446 hostname_setup();
d7ccca2e 1447 machine_id_setup();
888c6216 1448 loopback_setup();
490aed58 1449
6ee5bbf8 1450 test_mtab();
80758717 1451 test_usr();
871c44a7 1452 test_cgroups();
af5bc85d 1453 }
302e8c4c 1454
e96d6be7
LP
1455 if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0)
1456 watchdog_set_timeout(&arg_runtime_watchdog);
1457
1458 r = manager_new(arg_running_as, &m);
1459 if (r < 0) {
8e274523 1460 log_error("Failed to allocate manager object: %s", strerror(-r));
60918275
LP
1461 goto finish;
1462 }
1463
9e58ff9c 1464 m->confirm_spawn = arg_confirm_spawn;
07459bb6 1465#ifdef HAVE_SYSV_COMPAT
6e98720f 1466 m->sysv_console = arg_sysv_console;
07459bb6 1467#endif
0a494f1f
LP
1468 m->default_std_output = arg_default_std_output;
1469 m->default_std_error = arg_default_std_error;
e96d6be7
LP
1470 m->runtime_watchdog = arg_runtime_watchdog;
1471 m->shutdown_watchdog = arg_shutdown_watchdog;
9e58ff9c 1472
e9ddabc2
LP
1473 if (dual_timestamp_is_set(&initrd_timestamp))
1474 m->initrd_timestamp = initrd_timestamp;
1475
06d4c99a
LP
1476 if (arg_default_controllers)
1477 manager_set_default_controllers(m, arg_default_controllers);
1478
27d340c7
LP
1479 manager_set_show_status(m, arg_show_status);
1480
9d76d730
LP
1481 before_startup = now(CLOCK_MONOTONIC);
1482
e96d6be7
LP
1483 r = manager_startup(m, serialization, fds);
1484 if (r < 0)
6e2ef85b 1485 log_error("Failed to fully start up daemon: %s", strerror(-r));
a16e1123
LP
1486
1487 if (fds) {
1488 /* This will close all file descriptors that were opened, but
1489 * not claimed by any unit. */
1490
1491 fdset_free(fds);
1492 fds = NULL;
f50e0a01
LP
1493 }
1494
a16e1123
LP
1495 if (serialization) {
1496 fclose(serialization);
1497 serialization = NULL;
1498 } else {
398ef8ba 1499 DBusError error;
1c27d3f3 1500 Unit *target = NULL;
bacbccb7 1501 Job *default_unit_job;
398ef8ba
LP
1502
1503 dbus_error_init(&error);
1504
fa0f4d8a 1505 log_debug("Activating default unit: %s", arg_default_unit);
a16e1123 1506
e96d6be7
LP
1507 r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
1508 if (r < 0) {
398ef8ba
LP
1509 log_error("Failed to load default target: %s", bus_error(&error, r));
1510 dbus_error_free(&error);
ac155bb8
MS
1511 } else if (target->load_state == UNIT_ERROR)
1512 log_error("Failed to load default target: %s", strerror(-target->load_error));
1513 else if (target->load_state == UNIT_MASKED)
6daf4f90 1514 log_error("Default target masked.");
27b14a22 1515
ac155bb8 1516 if (!target || target->load_state != UNIT_LOADED) {
a16e1123 1517 log_info("Trying to load rescue target...");
1c27d3f3 1518
e96d6be7
LP
1519 r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
1520 if (r < 0) {
398ef8ba
LP
1521 log_error("Failed to load rescue target: %s", bus_error(&error, r));
1522 dbus_error_free(&error);
a16e1123 1523 goto finish;
ac155bb8
MS
1524 } else if (target->load_state == UNIT_ERROR) {
1525 log_error("Failed to load rescue target: %s", strerror(-target->load_error));
1c27d3f3 1526 goto finish;
ac155bb8 1527 } else if (target->load_state == UNIT_MASKED) {
6daf4f90 1528 log_error("Rescue target masked.");
00dc5d76 1529 goto finish;
a16e1123
LP
1530 }
1531 }
37d88da7 1532
ac155bb8 1533 assert(target->load_state == UNIT_LOADED);
00dc5d76 1534
fa0f4d8a 1535 if (arg_action == ACTION_TEST) {
40d50879 1536 printf("-> By units:\n");
a16e1123
LP
1537 manager_dump_units(m, stdout, "\t");
1538 }
1539
bacbccb7
MS
1540 r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
1541 if (r < 0) {
398ef8ba
LP
1542 log_error("Failed to start default target: %s", bus_error(&error, r));
1543 dbus_error_free(&error);
37d88da7
LP
1544 goto finish;
1545 }
bacbccb7 1546 m->default_unit_job_id = default_unit_job->id;
60918275 1547
07672f49
LP
1548 after_startup = now(CLOCK_MONOTONIC);
1549 log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
1550 "Loaded units and determined initial transaction in %s.",
1551 format_timespan(timespan, sizeof(timespan), after_startup - before_startup));
1552
fa0f4d8a 1553 if (arg_action == ACTION_TEST) {
40d50879 1554 printf("-> By jobs:\n");
a16e1123 1555 manager_dump_jobs(m, stdout, "\t");
22f4096c 1556 retval = EXIT_SUCCESS;
a16e1123
LP
1557 goto finish;
1558 }
e965d56d 1559 }
d46de8a1 1560
a16e1123 1561 for (;;) {
e96d6be7
LP
1562 r = manager_loop(m);
1563 if (r < 0) {
a16e1123
LP
1564 log_error("Failed to run mainloop: %s", strerror(-r));
1565 goto finish;
1566 }
11dd41ce 1567
a16e1123 1568 switch (m->exit_code) {
e965d56d 1569
a16e1123 1570 case MANAGER_EXIT:
22f4096c 1571 retval = EXIT_SUCCESS;
a16e1123
LP
1572 log_debug("Exit.");
1573 goto finish;
e965d56d 1574
a16e1123 1575 case MANAGER_RELOAD:
e015090f 1576 log_info("Reloading.");
e96d6be7
LP
1577 r = manager_reload(m);
1578 if (r < 0)
a16e1123
LP
1579 log_error("Failed to reload: %s", strerror(-r));
1580 break;
cea8e32e 1581
a16e1123 1582 case MANAGER_REEXECUTE:
664f88a7 1583
a16e1123
LP
1584 if (prepare_reexecute(m, &serialization, &fds) < 0)
1585 goto finish;
60918275 1586
a16e1123 1587 reexecute = true;
e015090f 1588 log_notice("Reexecuting.");
a16e1123
LP
1589 goto finish;
1590
664f88a7
LP
1591 case MANAGER_SWITCH_ROOT:
1592 /* Steal the switch root parameters */
41669317 1593 switch_root_dir = m->switch_root;
664f88a7
LP
1594 switch_root_init = m->switch_root_init;
1595 m->switch_root = m->switch_root_init = NULL;
1596
1597 if (!switch_root_init)
1598 if (prepare_reexecute(m, &serialization, &fds) < 0)
1599 goto finish;
1600
1601 reexecute = true;
1602 log_notice("Switching root.");
1603 goto finish;
1604
b9080b03
FF
1605 case MANAGER_REBOOT:
1606 case MANAGER_POWEROFF:
1607 case MANAGER_HALT:
1608 case MANAGER_KEXEC: {
1609 static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
1610 [MANAGER_REBOOT] = "reboot",
1611 [MANAGER_POWEROFF] = "poweroff",
1612 [MANAGER_HALT] = "halt",
1613 [MANAGER_KEXEC] = "kexec"
1614 };
1615
1616 assert_se(shutdown_verb = table[m->exit_code]);
e96d6be7 1617 arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
b9080b03
FF
1618
1619 log_notice("Shutting down.");
1620 goto finish;
1621 }
1622
a16e1123
LP
1623 default:
1624 assert_not_reached("Unknown exit code.");
1625 }
1626 }
f170852a 1627
60918275
LP
1628finish:
1629 if (m)
1630 manager_free(m);
1631
fa0f4d8a 1632 free(arg_default_unit);
06d4c99a 1633 strv_free(arg_default_controllers);
0c85a4f3 1634 free_join_controllers();
b9cd2ec1 1635
ea430986 1636 dbus_shutdown();
b2bb3dbe
LP
1637 label_finish();
1638
a16e1123 1639 if (reexecute) {
664f88a7 1640 const char **args;
e564a982 1641 unsigned i, args_size;
a16e1123 1642
664f88a7
LP
1643 /* Close and disarm the watchdog, so that the new
1644 * instance can reinitialize it, but doesn't get
1645 * rebooted while we do that */
1646 watchdog_close(true);
a16e1123 1647
41669317
LP
1648 if (switch_root_dir) {
1649 r = switch_root(switch_root_dir);
1650 if (r < 0)
1651 log_error("Failed to switch root, ignoring: %s", strerror(-r));
1652 }
a16e1123 1653
d03bc1b8 1654 args_size = MAX(6, argc+1);
e564a982 1655 args = newa(const char*, args_size);
a16e1123 1656
664f88a7
LP
1657 if (!switch_root_init) {
1658 char sfd[16];
a16e1123 1659
664f88a7
LP
1660 /* First try to spawn ourselves with the right
1661 * path, and with full serialization. We do
1662 * this only if the user didn't specify an
1663 * explicit init to spawn. */
edb9aaa8 1664
664f88a7
LP
1665 assert(serialization);
1666 assert(fds);
edb9aaa8 1667
664f88a7
LP
1668 snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
1669 char_array_0(sfd);
edb9aaa8 1670
664f88a7
LP
1671 i = 0;
1672 args[i++] = SYSTEMD_BINARY_PATH;
41669317 1673 if (switch_root_dir)
d03bc1b8 1674 args[i++] = "--switchedroot";
664f88a7
LP
1675 args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
1676 args[i++] = "--deserialize";
1677 args[i++] = sfd;
1678 args[i++] = NULL;
edb9aaa8 1679
e564a982 1680 assert(i <= args_size);
664f88a7
LP
1681 execv(args[0], (char* const*) args);
1682 }
6e98720f 1683
664f88a7
LP
1684 /* Try the fallback, if there is any, without any
1685 * serialization. We pass the original argv[] and
1686 * envp[]. (Well, modulo the ordering changes due to
1687 * getopt() in argv[], and some cleanups in envp[],
1688 * but let's hope that doesn't matter.) */
a16e1123 1689
b8f83232 1690 if (serialization) {
664f88a7 1691 fclose(serialization);
b8f83232
LP
1692 serialization = NULL;
1693 }
a16e1123 1694
b8f83232 1695 if (fds) {
664f88a7 1696 fdset_free(fds);
b8f83232
LP
1697 fds = NULL;
1698 }
a16e1123 1699
b8f83232 1700 for (j = 1, i = 1; j < argc; j++)
664f88a7 1701 args[i++] = argv[j];
a16e1123 1702 args[i++] = NULL;
e564a982 1703 assert(i <= args_size);
b8f83232
LP
1704
1705 if (switch_root_init) {
1706 args[0] = switch_root_init;
1707 execv(args[0], (char* const*) args);
1708 log_warning("Failed to execute configured init, trying fallback: %m");
1709 }
1710
1711 args[0] = "/sbin/init";
a16e1123
LP
1712 execv(args[0], (char* const*) args);
1713
b8f83232
LP
1714 log_warning("Failed to execute /sbin/init, trying fallback: %m");
1715
1716 args[0] = "/bin/sh";
1717 args[1] = NULL;
1718 execv(args[0], (char* const*) args);
1719 log_error("Failed to execute /bin/sh, giving up: %m");
a16e1123
LP
1720 }
1721
1722 if (serialization)
1723 fclose(serialization);
1724
1725 if (fds)
1726 fdset_free(fds);
1727
b9080b03
FF
1728 if (shutdown_verb) {
1729 const char * command_line[] = {
1730 SYSTEMD_SHUTDOWN_BINARY_PATH,
1731 shutdown_verb,
1732 NULL
1733 };
d18f337c 1734 char **env_block;
b9080b03 1735
e96d6be7 1736 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
d18f337c
LP
1737 char e[32];
1738
e96d6be7
LP
1739 /* If we reboot let's set the shutdown
1740 * watchdog and tell the shutdown binary to
1741 * repeatedly ping it */
1742 watchdog_set_timeout(&arg_shutdown_watchdog);
1743 watchdog_close(false);
1744
1745 /* Tell the binary how often to ping */
1746 snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
1747 char_array_0(e);
d18f337c
LP
1748
1749 env_block = strv_append(environ, e);
1750 } else {
1751 env_block = strv_copy(environ);
e96d6be7 1752 watchdog_close(true);
d18f337c 1753 }
e96d6be7 1754
d18f337c
LP
1755 execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
1756 free(env_block);
b9080b03
FF
1757 log_error("Failed to execute shutdown binary, freezing: %m");
1758 }
1759
c3b3c274
LP
1760 if (getpid() == 1)
1761 freeze();
1762
60918275
LP
1763 return retval;
1764}