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