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