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