]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/main.c
honor SELinux labels, when creating and writing config files
[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"
bd3fa1d2 54#include "killall.h"
0c4025d1
LP
55#include "env-util.h"
56#include "hwclock.h"
57#include "sd-daemon.h"
60918275 58
b6e66135
LP
59#include "mount-setup.h"
60#include "loopback-setup.h"
e3043162 61#ifdef HAVE_KMOD
b6e66135 62#include "kmod-setup.h"
e3043162 63#endif
b6e66135
LP
64#include "hostname-setup.h"
65#include "machine-id-setup.h"
66#include "locale-setup.h"
67#include "selinux-setup.h"
68#include "ima-setup.h"
a5c32cff 69#include "fileio.h"
b6e66135 70
f170852a
LP
71static enum {
72 ACTION_RUN,
e965d56d 73 ACTION_HELP,
9ba0bc4e 74 ACTION_VERSION,
e537352b 75 ACTION_TEST,
4288f619
LP
76 ACTION_DUMP_CONFIGURATION_ITEMS,
77 ACTION_DONE
fa0f4d8a 78} arg_action = ACTION_RUN;
f170852a 79
fa0f4d8a 80static char *arg_default_unit = NULL;
67445f4e 81static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
fa0f4d8a
LP
82
83static bool arg_dump_core = true;
84static bool arg_crash_shell = false;
85static int arg_crash_chvt = -1;
86static bool arg_confirm_spawn = false;
9e58ff9c 87static bool arg_show_status = true;
bf4df7c3 88static bool arg_switched_root = false;
06d4c99a 89static char **arg_default_controllers = NULL;
0c85a4f3 90static char ***arg_join_controllers = NULL;
706343f4 91static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
0a494f1f 92static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
e96d6be7
LP
93static usec_t arg_runtime_watchdog = 0;
94static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
c93ff2e9 95static struct rlimit *arg_default_rlimit[RLIMIT_NLIMITS] = {};
ec8927ca 96static uint64_t arg_capability_bounding_set_drop = 0;
aa0f64ac 97static nsec_t arg_timer_slack_nsec = (nsec_t) -1;
4fc935ca 98
a16e1123 99static FILE* serialization = NULL;
80876c20 100
6f5e3f35
LP
101static void nop_handler(int sig) {
102}
103
93a46b0b 104_noreturn_ static void crash(int sig) {
97c4f35c 105
fa0f4d8a 106 if (!arg_dump_core)
582a507f 107 log_error("Caught <%s>, not dumping core.", signal_to_string(sig));
97c4f35c 108 else {
6f5e3f35 109 struct sigaction sa;
97c4f35c
LP
110 pid_t pid;
111
6f5e3f35
LP
112 /* We want to wait for the core process, hence let's enable SIGCHLD */
113 zero(sa);
114 sa.sa_handler = nop_handler;
115 sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
116 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
117
97c4f35c 118 if ((pid = fork()) < 0)
582a507f 119 log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
97c4f35c
LP
120
121 else if (pid == 0) {
97c4f35c
LP
122 struct rlimit rl;
123
124 /* Enable default signal handler for core dump */
125 zero(sa);
126 sa.sa_handler = SIG_DFL;
127 assert_se(sigaction(sig, &sa, NULL) == 0);
128
129 /* Don't limit the core dump size */
130 zero(rl);
131 rl.rlim_cur = RLIM_INFINITY;
132 rl.rlim_max = RLIM_INFINITY;
133 setrlimit(RLIMIT_CORE, &rl);
134
135 /* Just to be sure... */
136 assert_se(chdir("/") == 0);
137
138 /* Raise the signal again */
139 raise(sig);
140
141 assert_not_reached("We shouldn't be here...");
142 _exit(1);
4fc935ca
LP
143
144 } else {
8e12a6ae
LP
145 siginfo_t status;
146 int r;
4fc935ca
LP
147
148 /* Order things nicely. */
8e12a6ae
LP
149 if ((r = wait_for_terminate(pid, &status)) < 0)
150 log_error("Caught <%s>, waitpid() failed: %s", signal_to_string(sig), strerror(-r));
151 else if (status.si_code != CLD_DUMPED)
582a507f 152 log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
4fc935ca 153 else
582a507f 154 log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
97c4f35c
LP
155 }
156 }
157
fa0f4d8a
LP
158 if (arg_crash_chvt)
159 chvt(arg_crash_chvt);
601f6a1e 160
fa0f4d8a 161 if (arg_crash_shell) {
6f5e3f35
LP
162 struct sigaction sa;
163 pid_t pid;
8c43883a 164
4fc935ca
LP
165 log_info("Executing crash shell in 10s...");
166 sleep(10);
167
6f5e3f35
LP
168 /* Let the kernel reap children for us */
169 zero(sa);
170 sa.sa_handler = SIG_IGN;
171 sa.sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART;
172 assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
8c43883a 173
cd3bd60a
LP
174 pid = fork();
175 if (pid < 0)
14212119 176 log_error("Failed to fork off crash shell: %m");
6f5e3f35 177 else if (pid == 0) {
cd3bd60a 178 make_console_stdio();
6f5e3f35
LP
179 execl("/bin/sh", "/bin/sh", NULL);
180
14212119 181 log_error("execl() failed: %m");
6f5e3f35
LP
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 346 } else if (startswith(word, "systemd.setenv=")) {
0c4025d1
LP
347 _cleanup_free_ char *cenv = NULL;
348 char *eq;
9e7c5357
WD
349 int r;
350
351 cenv = strdup(word + 15);
352 if (!cenv)
353 return -ENOMEM;
354
355 eq = strchr(cenv, '=');
356 if (!eq) {
0c4025d1
LP
357 if (!env_name_is_valid(cenv))
358 log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
359 else {
360 r = unsetenv(cenv);
361 if (r < 0)
362 log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv);
363 }
9e7c5357 364 } else {
0c4025d1
LP
365 if (!env_assignment_is_valid(cenv))
366 log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv);
367 else {
368 *eq = 0;
369 r = setenv(cenv, eq + 1, 1);
370 if (r < 0)
371 log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1);
372 }
9e7c5357 373 }
9e58ff9c 374
66a78c2b
LP
375 } else if (startswith(word, "systemd.") ||
376 (in_initrd() && startswith(word, "rd.systemd."))) {
4fc935ca
LP
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"
4cfa2c99 388 "systemd.log_target=console|kmsg|journal|journal-or-kmsg|syslog|syslog-or-kmsg|null\n"
6e98720f
LP
389 " Log target\n"
390 "systemd.log_level=LEVEL Log level\n"
391 "systemd.log_color=0|1 Highlight important log messages\n"
0a494f1f 392 "systemd.log_location=0|1 Include code location in log messages\n"
706343f4 393 "systemd.default_standard_output=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
0a494f1f 394 " Set default log output for services\n"
706343f4 395 "systemd.default_standard_error=null|tty|syslog|syslog+console|kmsg|kmsg+console|journal|journal+console\n"
c66e7bc7
LP
396 " Set default log error output for services\n"
397 "systemd.setenv=ASSIGNMENT Set an environment variable for all spawned processes\n");
4fc935ca 398
d081dffb 399 } else if (streq(word, "quiet"))
6e98720f 400 arg_show_status = false;
d081dffb 401 else if (!in_initrd()) {
f170852a
LP
402 unsigned i;
403
404 /* SysV compatibility */
f170852a
LP
405 for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
406 if (streq(word, rlmap[i]))
407 return set_default_unit(rlmap[i+1]);
408 }
409
410 return 0;
411}
412
f975e971 413static int config_parse_level2(
487393e9
LP
414 const char *filename,
415 unsigned line,
416 const char *section,
417 const char *lvalue,
3731f1ea 418 int ltype,
487393e9
LP
419 const char *rvalue,
420 void *data,
421 void *userdata) {
422
423 assert(filename);
424 assert(lvalue);
425 assert(rvalue);
426
427 log_set_max_level_from_string(rvalue);
428 return 0;
429}
430
431static int config_parse_target(
432 const char *filename,
433 unsigned line,
434 const char *section,
435 const char *lvalue,
3731f1ea 436 int ltype,
487393e9
LP
437 const char *rvalue,
438 void *data,
439 void *userdata) {
440
441 assert(filename);
442 assert(lvalue);
443 assert(rvalue);
444
445 log_set_target_from_string(rvalue);
446 return 0;
447}
448
449static int config_parse_color(
450 const char *filename,
451 unsigned line,
452 const char *section,
453 const char *lvalue,
3731f1ea 454 int ltype,
487393e9
LP
455 const char *rvalue,
456 void *data,
457 void *userdata) {
458
459 assert(filename);
460 assert(lvalue);
461 assert(rvalue);
462
463 log_show_color_from_string(rvalue);
464 return 0;
465}
466
467static int config_parse_location(
468 const char *filename,
469 unsigned line,
470 const char *section,
471 const char *lvalue,
3731f1ea 472 int ltype,
487393e9
LP
473 const char *rvalue,
474 void *data,
475 void *userdata) {
476
477 assert(filename);
478 assert(lvalue);
479 assert(rvalue);
480
481 log_show_location_from_string(rvalue);
482 return 0;
483}
484
f975e971 485static int config_parse_cpu_affinity2(
487393e9
LP
486 const char *filename,
487 unsigned line,
488 const char *section,
489 const char *lvalue,
3731f1ea 490 int ltype,
487393e9
LP
491 const char *rvalue,
492 void *data,
493 void *userdata) {
494
495 char *w;
496 size_t l;
497 char *state;
498 cpu_set_t *c = NULL;
499 unsigned ncpus = 0;
500
501 assert(filename);
502 assert(lvalue);
503 assert(rvalue);
504
f60f22df 505 FOREACH_WORD_QUOTED(w, l, rvalue, state) {
487393e9
LP
506 char *t;
507 int r;
508 unsigned cpu;
509
510 if (!(t = strndup(w, l)))
14212119 511 return log_oom();
487393e9
LP
512
513 r = safe_atou(t, &cpu);
514 free(t);
515
516 if (!c)
517 if (!(c = cpu_set_malloc(&ncpus)))
14212119 518 return log_oom();
487393e9
LP
519
520 if (r < 0 || cpu >= ncpus) {
521 log_error("[%s:%u] Failed to parse CPU affinity: %s", filename, line, rvalue);
522 CPU_FREE(c);
523 return -EBADMSG;
524 }
525
526 CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
527 }
528
529 if (c) {
530 if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
531 log_warning("Failed to set CPU affinity: %m");
532
533 CPU_FREE(c);
534 }
535
536 return 0;
537}
538
0c85a4f3
LP
539static void strv_free_free(char ***l) {
540 char ***i;
541
542 if (!l)
543 return;
544
545 for (i = l; *i; i++)
546 strv_free(*i);
547
548 free(l);
549}
550
551static void free_join_controllers(void) {
552 if (!arg_join_controllers)
553 return;
554
555 strv_free_free(arg_join_controllers);
556 arg_join_controllers = NULL;
557}
558
559static int config_parse_join_controllers(
560 const char *filename,
561 unsigned line,
562 const char *section,
563 const char *lvalue,
564 int ltype,
565 const char *rvalue,
566 void *data,
567 void *userdata) {
568
569 unsigned n = 0;
570 char *state, *w;
571 size_t length;
572
573 assert(filename);
574 assert(lvalue);
575 assert(rvalue);
576
577 free_join_controllers();
578
579 FOREACH_WORD_QUOTED(w, length, rvalue, state) {
580 char *s, **l;
581
582 s = strndup(w, length);
583 if (!s)
14212119 584 return log_oom();
0c85a4f3
LP
585
586 l = strv_split(s, ",");
587 free(s);
588
589 strv_uniq(l);
590
591 if (strv_length(l) <= 1) {
592 strv_free(l);
593 continue;
594 }
595
596 if (!arg_join_controllers) {
597 arg_join_controllers = new(char**, 2);
598 if (!arg_join_controllers) {
599 strv_free(l);
14212119 600 return log_oom();
0c85a4f3
LP
601 }
602
603 arg_join_controllers[0] = l;
604 arg_join_controllers[1] = NULL;
605
606 n = 1;
607 } else {
608 char ***a;
609 char ***t;
610
611 t = new0(char**, n+2);
612 if (!t) {
613 strv_free(l);
14212119 614 return log_oom();
0c85a4f3
LP
615 }
616
617 n = 0;
618
619 for (a = arg_join_controllers; *a; a++) {
620
621 if (strv_overlap(*a, l)) {
622 char **c;
623
624 c = strv_merge(*a, l);
625 if (!c) {
626 strv_free(l);
627 strv_free_free(t);
14212119 628 return log_oom();
0c85a4f3
LP
629 }
630
631 strv_free(l);
632 l = c;
633 } else {
634 char **c;
635
636 c = strv_copy(*a);
637 if (!c) {
638 strv_free(l);
639 strv_free_free(t);
14212119 640 return log_oom();
0c85a4f3
LP
641 }
642
643 t[n++] = c;
644 }
645 }
646
647 t[n++] = strv_uniq(l);
648
649 strv_free_free(arg_join_controllers);
650 arg_join_controllers = t;
651 }
652 }
653
654 return 0;
655}
656
487393e9
LP
657static int parse_config_file(void) {
658
f975e971
LP
659 const ConfigTableItem items[] = {
660 { "Manager", "LogLevel", config_parse_level2, 0, NULL },
661 { "Manager", "LogTarget", config_parse_target, 0, NULL },
662 { "Manager", "LogColor", config_parse_color, 0, NULL },
663 { "Manager", "LogLocation", config_parse_location, 0, NULL },
664 { "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
665 { "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
666 { "Manager", "ShowStatus", config_parse_bool, 0, &arg_show_status },
f975e971
LP
667 { "Manager", "CrashChVT", config_parse_int, 0, &arg_crash_chvt },
668 { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
f975e971
LP
669 { "Manager", "DefaultControllers", config_parse_strv, 0, &arg_default_controllers },
670 { "Manager", "DefaultStandardOutput", config_parse_output, 0, &arg_default_std_output },
671 { "Manager", "DefaultStandardError", config_parse_output, 0, &arg_default_std_error },
0c85a4f3 672 { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
e96d6be7
LP
673 { "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog },
674 { "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog },
ec8927ca 675 { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop },
aa0f64ac 676 { "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
c93ff2e9
FC
677 { "Manager", "DefaultLimitCPU", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CPU]},
678 { "Manager", "DefaultLimitFSIZE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_FSIZE]},
679 { "Manager", "DefaultLimitDATA", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_DATA]},
680 { "Manager", "DefaultLimitSTACK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_STACK]},
681 { "Manager", "DefaultLimitCORE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_CORE]},
682 { "Manager", "DefaultLimitRSS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RSS]},
683 { "Manager", "DefaultLimitNOFILE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NOFILE]},
684 { "Manager", "DefaultLimitAS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_AS]},
685 { "Manager", "DefaultLimitNPROC", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NPROC]},
686 { "Manager", "DefaultLimitMEMLOCK", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MEMLOCK]},
687 { "Manager", "DefaultLimitLOCKS", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_LOCKS]},
688 { "Manager", "DefaultLimitSIGPENDING",config_parse_limit, 0, &arg_default_rlimit[RLIMIT_SIGPENDING]},
689 { "Manager", "DefaultLimitMSGQUEUE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE]},
690 { "Manager", "DefaultLimitNICE", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_NICE]},
691 { "Manager", "DefaultLimitRTPRIO", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTPRIO]},
692 { "Manager", "DefaultLimitRTTIME", config_parse_limit, 0, &arg_default_rlimit[RLIMIT_RTTIME]},
f975e971 693 { NULL, NULL, NULL, 0, NULL }
487393e9
LP
694 };
695
696 FILE *f;
697 const char *fn;
698 int r;
699
67445f4e 700 fn = arg_running_as == SYSTEMD_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
f975e971
LP
701 f = fopen(fn, "re");
702 if (!f) {
487393e9
LP
703 if (errno == ENOENT)
704 return 0;
705
706 log_warning("Failed to open configuration file '%s': %m", fn);
707 return 0;
708 }
709
f975e971
LP
710 r = config_parse(fn, f, "Manager\0", config_item_table_lookup, (void*) items, false, NULL);
711 if (r < 0)
487393e9
LP
712 log_warning("Failed to parse configuration file: %s", strerror(-r));
713
714 fclose(f);
715
716 return 0;
717}
718
f170852a 719static int parse_proc_cmdline(void) {
52661efd 720 char *line, *w, *state;
f170852a 721 int r;
f170852a 722 size_t l;
f170852a 723
b770165a
LP
724 /* Don't read /proc/cmdline if we are in a container, since
725 * that is only relevant for the host system */
726 if (detect_container(NULL) > 0)
727 return 0;
728
f170852a 729 if ((r = read_one_line_file("/proc/cmdline", &line)) < 0) {
e364ad06 730 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
f170852a
LP
731 return 0;
732 }
733
734 FOREACH_WORD_QUOTED(w, l, line, state) {
735 char *word;
736
737 if (!(word = strndup(w, l))) {
738 r = -ENOMEM;
739 goto finish;
740 }
741
742 r = parse_proc_cmdline_word(word);
14212119
SL
743 if (r < 0) {
744 log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
032f8164 745 free(word);
f170852a 746 goto finish;
14212119 747 }
032f8164
LN
748
749 free(word);
f170852a
LP
750 }
751
752 r = 0;
753
754finish:
755 free(line);
756 return r;
757}
758
759static int parse_argv(int argc, char *argv[]) {
760
761 enum {
762 ARG_LOG_LEVEL = 0x100,
763 ARG_LOG_TARGET,
bbe63281
LP
764 ARG_LOG_COLOR,
765 ARG_LOG_LOCATION,
2f198e2f 766 ARG_UNIT,
edb9aaa8 767 ARG_SYSTEM,
af2d49f7 768 ARG_USER,
e537352b 769 ARG_TEST,
9ba0bc4e 770 ARG_VERSION,
80876c20 771 ARG_DUMP_CONFIGURATION_ITEMS,
9e58ff9c
LP
772 ARG_DUMP_CORE,
773 ARG_CRASH_SHELL,
a16e1123 774 ARG_CONFIRM_SPAWN,
9e58ff9c 775 ARG_SHOW_STATUS,
4288f619 776 ARG_DESERIALIZE,
2660882b 777 ARG_SWITCHED_ROOT,
0a494f1f
LP
778 ARG_INTROSPECT,
779 ARG_DEFAULT_STD_OUTPUT,
780 ARG_DEFAULT_STD_ERROR
f170852a
LP
781 };
782
783 static const struct option options[] = {
a16e1123
LP
784 { "log-level", required_argument, NULL, ARG_LOG_LEVEL },
785 { "log-target", required_argument, NULL, ARG_LOG_TARGET },
bbe63281
LP
786 { "log-color", optional_argument, NULL, ARG_LOG_COLOR },
787 { "log-location", optional_argument, NULL, ARG_LOG_LOCATION },
2f198e2f 788 { "unit", required_argument, NULL, ARG_UNIT },
edb9aaa8 789 { "system", no_argument, NULL, ARG_SYSTEM },
af2d49f7 790 { "user", no_argument, NULL, ARG_USER },
a16e1123
LP
791 { "test", no_argument, NULL, ARG_TEST },
792 { "help", no_argument, NULL, 'h' },
9ba0bc4e 793 { "version", no_argument, NULL, ARG_VERSION },
a16e1123 794 { "dump-configuration-items", no_argument, NULL, ARG_DUMP_CONFIGURATION_ITEMS },
a5d87bf0
LP
795 { "dump-core", optional_argument, NULL, ARG_DUMP_CORE },
796 { "crash-shell", optional_argument, NULL, ARG_CRASH_SHELL },
797 { "confirm-spawn", optional_argument, NULL, ARG_CONFIRM_SPAWN },
6e98720f 798 { "show-status", optional_argument, NULL, ARG_SHOW_STATUS },
a16e1123 799 { "deserialize", required_argument, NULL, ARG_DESERIALIZE },
2660882b 800 { "switched-root", no_argument, NULL, ARG_SWITCHED_ROOT },
4288f619 801 { "introspect", optional_argument, NULL, ARG_INTROSPECT },
0a494f1f
LP
802 { "default-standard-output", required_argument, NULL, ARG_DEFAULT_STD_OUTPUT, },
803 { "default-standard-error", required_argument, NULL, ARG_DEFAULT_STD_ERROR, },
a16e1123 804 { NULL, 0, NULL, 0 }
f170852a
LP
805 };
806
807 int c, r;
808
809 assert(argc >= 1);
810 assert(argv);
811
b770165a
LP
812 if (getpid() == 1)
813 opterr = 0;
814
099663ff 815 while ((c = getopt_long(argc, argv, "hDbsz:", options, NULL)) >= 0)
f170852a
LP
816
817 switch (c) {
818
819 case ARG_LOG_LEVEL:
820 if ((r = log_set_max_level_from_string(optarg)) < 0) {
821 log_error("Failed to parse log level %s.", optarg);
822 return r;
823 }
824
825 break;
826
827 case ARG_LOG_TARGET:
828
829 if ((r = log_set_target_from_string(optarg)) < 0) {
830 log_error("Failed to parse log target %s.", optarg);
831 return r;
832 }
833
834 break;
835
bbe63281
LP
836 case ARG_LOG_COLOR:
837
d0b170c8
LP
838 if (optarg) {
839 if ((r = log_show_color_from_string(optarg)) < 0) {
840 log_error("Failed to parse log color setting %s.", optarg);
841 return r;
842 }
843 } else
844 log_show_color(true);
bbe63281
LP
845
846 break;
847
848 case ARG_LOG_LOCATION:
849
d0b170c8
LP
850 if (optarg) {
851 if ((r = log_show_location_from_string(optarg)) < 0) {
852 log_error("Failed to parse log location setting %s.", optarg);
853 return r;
854 }
855 } else
856 log_show_location(true);
bbe63281
LP
857
858 break;
859
0a494f1f
LP
860 case ARG_DEFAULT_STD_OUTPUT:
861
862 if ((r = exec_output_from_string(optarg)) < 0) {
863 log_error("Failed to parse default standard output setting %s.", optarg);
864 return r;
865 } else
866 arg_default_std_output = r;
867 break;
868
869 case ARG_DEFAULT_STD_ERROR:
870
871 if ((r = exec_output_from_string(optarg)) < 0) {
872 log_error("Failed to parse default standard error output setting %s.", optarg);
873 return r;
874 } else
875 arg_default_std_error = r;
876 break;
877
2f198e2f 878 case ARG_UNIT:
f170852a
LP
879
880 if ((r = set_default_unit(optarg)) < 0) {
881 log_error("Failed to set default unit %s: %s", optarg, strerror(-r));
882 return r;
883 }
884
885 break;
886
edb9aaa8 887 case ARG_SYSTEM:
67445f4e 888 arg_running_as = SYSTEMD_SYSTEM;
edb9aaa8 889 break;
a5dab5ce 890
af2d49f7 891 case ARG_USER:
67445f4e 892 arg_running_as = SYSTEMD_USER;
a5dab5ce 893 break;
a5dab5ce 894
e965d56d 895 case ARG_TEST:
fa0f4d8a 896 arg_action = ACTION_TEST;
e965d56d
LP
897 break;
898
9ba0bc4e
ZJS
899 case ARG_VERSION:
900 arg_action = ACTION_VERSION;
901 break;
902
e537352b 903 case ARG_DUMP_CONFIGURATION_ITEMS:
fa0f4d8a 904 arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
e537352b
LP
905 break;
906
9e58ff9c 907 case ARG_DUMP_CORE:
a5d87bf0
LP
908 r = optarg ? parse_boolean(optarg) : 1;
909 if (r < 0) {
910 log_error("Failed to parse dump core boolean %s.", optarg);
911 return r;
912 }
913 arg_dump_core = r;
9e58ff9c
LP
914 break;
915
916 case ARG_CRASH_SHELL:
a5d87bf0
LP
917 r = optarg ? parse_boolean(optarg) : 1;
918 if (r < 0) {
919 log_error("Failed to parse crash shell boolean %s.", optarg);
920 return r;
921 }
922 arg_crash_shell = r;
9e58ff9c
LP
923 break;
924
80876c20 925 case ARG_CONFIRM_SPAWN:
a5d87bf0
LP
926 r = optarg ? parse_boolean(optarg) : 1;
927 if (r < 0) {
928 log_error("Failed to parse confirm spawn boolean %s.", optarg);
929 return r;
930 }
931 arg_confirm_spawn = r;
80876c20
LP
932 break;
933
9e58ff9c 934 case ARG_SHOW_STATUS:
a5d87bf0
LP
935 r = optarg ? parse_boolean(optarg) : 1;
936 if (r < 0) {
937 log_error("Failed to parse show status boolean %s.", optarg);
938 return r;
939 }
940 arg_show_status = r;
6e98720f 941 break;
a5d87bf0 942
a16e1123
LP
943 case ARG_DESERIALIZE: {
944 int fd;
945 FILE *f;
946
01e10de3
LP
947 r = safe_atoi(optarg, &fd);
948 if (r < 0 || fd < 0) {
a16e1123 949 log_error("Failed to parse deserialize option %s.", optarg);
01e10de3 950 return r < 0 ? r : -EINVAL;
a16e1123
LP
951 }
952
01e10de3
LP
953 fd_cloexec(fd, true);
954
955 f = fdopen(fd, "r");
956 if (!f) {
a16e1123 957 log_error("Failed to open serialization fd: %m");
01e10de3 958 return -errno;
a16e1123
LP
959 }
960
961 if (serialization)
962 fclose(serialization);
963
964 serialization = f;
965
966 break;
967 }
968
2660882b 969 case ARG_SWITCHED_ROOT:
bf4df7c3 970 arg_switched_root = true;
d03bc1b8
HH
971 break;
972
4288f619
LP
973 case ARG_INTROSPECT: {
974 const char * const * i = NULL;
975
976 for (i = bus_interface_table; *i; i += 2)
977 if (!optarg || streq(i[0], optarg)) {
978 fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
979 "<node>\n", stdout);
980 fputs(i[1], stdout);
981 fputs("</node>\n", stdout);
982
983 if (optarg)
984 break;
985 }
986
987 if (!i[0] && optarg)
988 log_error("Unknown interface %s.", optarg);
989
fa0f4d8a 990 arg_action = ACTION_DONE;
4288f619
LP
991 break;
992 }
993
f170852a 994 case 'h':
fa0f4d8a 995 arg_action = ACTION_HELP;
f170852a
LP
996 break;
997
1d2e23ab
LP
998 case 'D':
999 log_set_max_level(LOG_DEBUG);
1000 break;
1001
099663ff
LP
1002 case 'b':
1003 case 's':
1004 case 'z':
1005 /* Just to eat away the sysvinit kernel
1006 * cmdline args without getopt() error
1007 * messages that we'll parse in
1008 * parse_proc_cmdline_word() or ignore. */
f170852a 1009
099663ff 1010 case '?':
f170852a 1011 default:
099663ff
LP
1012 if (getpid() != 1) {
1013 log_error("Unknown option code %c", c);
1014 return -EINVAL;
1015 }
1016
1017 break;
f170852a
LP
1018 }
1019
d821e6d6
LP
1020 if (optind < argc && getpid() != 1) {
1021 /* Hmm, when we aren't run as init system
1022 * let's complain about excess arguments */
1023
1024 log_error("Excess arguments.");
1025 return -EINVAL;
1026 }
1027
1028 if (detect_container(NULL) > 0) {
1029 char **a;
1030
1031 /* All /proc/cmdline arguments the kernel didn't
1032 * understand it passed to us. We're not really
1033 * interested in that usually since /proc/cmdline is
1034 * more interesting and complete. With one exception:
1035 * if we are run in a container /proc/cmdline is not
1036 * relevant for the container, hence we rely on argv[]
1037 * instead. */
1038
1039 for (a = argv; a < argv + argc; a++)
14212119
SL
1040 if ((r = parse_proc_cmdline_word(*a)) < 0) {
1041 log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
d821e6d6 1042 return r;
14212119 1043 }
51f0e189
LP
1044 }
1045
f170852a
LP
1046 return 0;
1047}
1048
1049static int help(void) {
1050
2e33c433 1051 printf("%s [OPTIONS...]\n\n"
af2d49f7 1052 "Starts up and maintains the system or user services.\n\n"
e537352b 1053 " -h --help Show this help\n"
e537352b 1054 " --test Determine startup sequence, dump it and exit\n"
80876c20 1055 " --dump-configuration-items Dump understood unit configuration items\n"
bbe63281 1056 " --introspect[=INTERFACE] Extract D-Bus interface data\n"
9e58ff9c 1057 " --unit=UNIT Set default unit\n"
edb9aaa8 1058 " --system Run a system instance, even if PID != 1\n"
af2d49f7 1059 " --user Run a user instance\n"
a5d87bf0
LP
1060 " --dump-core[=0|1] Dump core on crash\n"
1061 " --crash-shell[=0|1] Run shell on crash\n"
1062 " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
6e98720f 1063 " --show-status[=0|1] Show status updates on the console during bootup\n"
4cfa2c99 1064 " --log-target=TARGET Set log target (console, journal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n"
9e58ff9c 1065 " --log-level=LEVEL Set log level (debug, info, notice, warning, err, crit, alert, emerg)\n"
2218198b 1066 " --log-color[=0|1] Highlight important log messages\n"
0a494f1f
LP
1067 " --log-location[=0|1] Include code location in log messages\n"
1068 " --default-standard-output= Set default standard output for services\n"
1069 " --default-standard-error= Set default standard error output for services\n",
5b6319dc 1070 program_invocation_short_name);
f170852a
LP
1071
1072 return 0;
1073}
1074
9ba0bc4e
ZJS
1075static int version(void) {
1076 puts(PACKAGE_STRING);
9ba0bc4e
ZJS
1077 puts(SYSTEMD_FEATURES);
1078
1079 return 0;
1080}
1081
6b78f9b4 1082static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool serialize_jobs) {
a16e1123
LP
1083 FILE *f = NULL;
1084 FDSet *fds = NULL;
1085 int r;
1086
1087 assert(m);
1088 assert(_f);
1089 assert(_fds);
1090
a7556052
LP
1091 /* Make sure nothing is really destructed when we shut down */
1092 m->n_reloading ++;
1093
6b78f9b4
LP
1094 r = manager_open_serialization(m, &f);
1095 if (r < 0) {
35b8ca3a 1096 log_error("Failed to create serialization file: %s", strerror(-r));
a16e1123
LP
1097 goto fail;
1098 }
1099
6b78f9b4
LP
1100 fds = fdset_new();
1101 if (!fds) {
a16e1123
LP
1102 r = -ENOMEM;
1103 log_error("Failed to allocate fd set: %s", strerror(-r));
1104 goto fail;
1105 }
1106
6b78f9b4
LP
1107 r = manager_serialize(m, f, fds, serialize_jobs);
1108 if (r < 0) {
a16e1123
LP
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
6b78f9b4
LP
1118 r = fd_cloexec(fileno(f), false);
1119 if (r < 0) {
a16e1123
LP
1120 log_error("Failed to disable O_CLOEXEC for serialization: %s", strerror(-r));
1121 goto fail;
1122 }
1123
6b78f9b4
LP
1124 r = fdset_cloexec(fds, false);
1125 if (r < 0) {
a16e1123
LP
1126 log_error("Failed to disable O_CLOEXEC for serialization fds: %s", strerror(-r));
1127 goto fail;
1128 }
1129
1130 *_f = f;
1131 *_fds = fds;
1132
1133 return 0;
1134
1135fail:
1136 fdset_free(fds);
1137
1138 if (f)
1139 fclose(f);
1140
1141 return r;
1142}
1143
4096d6f5
LP
1144static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
1145 struct rlimit nl;
1146 int r;
1147
1148 assert(saved_rlimit);
1149
1150 /* Save the original RLIMIT_NOFILE so that we can reset it
1151 * later when transitioning from the initrd to the main
1152 * systemd or suchlike. */
1153 if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
1154 log_error("Reading RLIMIT_NOFILE failed: %m");
1155 return -errno;
1156 }
1157
1158 /* Make sure forked processes get the default kernel setting */
1159 if (!arg_default_rlimit[RLIMIT_NOFILE]) {
1160 struct rlimit *rl;
1161
1162 rl = newdup(struct rlimit, saved_rlimit, 1);
1163 if (!rl)
1164 return log_oom();
1165
1166 arg_default_rlimit[RLIMIT_NOFILE] = rl;
1167 }
1168
1169 /* Bump up the resource limit for ourselves substantially */
1170 nl.rlim_cur = nl.rlim_max = 64*1024;
1171 r = setrlimit_closest(RLIMIT_NOFILE, &nl);
1172 if (r < 0) {
1173 log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
1174 return r;
1175 }
1176
1177 return 0;
1178}
1179
e9ddabc2
LP
1180static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
1181 const char *e;
1182 unsigned long long a, b;
1183
1184 assert(t);
1185
966a5d37
LP
1186 e = getenv("RD_TIMESTAMP");
1187 if (!e)
e9ddabc2
LP
1188 return NULL;
1189
1190 if (sscanf(e, "%llu %llu", &a, &b) != 2)
1191 return NULL;
1192
1193 t->realtime = (usec_t) a;
1194 t->monotonic = (usec_t) b;
1195
1196 return t;
1197}
1198
6ee5bbf8
LP
1199static void test_mtab(void) {
1200 char *p;
1201
80758717
LP
1202 /* Check that /etc/mtab is a symlink */
1203
6ee5bbf8
LP
1204 if (readlink_malloc("/etc/mtab", &p) >= 0) {
1205 bool b;
1206
ed86ebc4 1207 b = streq(p, "/proc/self/mounts") || streq(p, "/proc/mounts");
6ee5bbf8
LP
1208 free(p);
1209
1210 if (b)
1211 return;
1212 }
1213
80758717
LP
1214 log_warning("/etc/mtab is not a symlink or not pointing to /proc/self/mounts. "
1215 "This is not supported anymore. "
1216 "Please make sure to replace this file by a symlink to avoid incorrect or misleading mount(8) output.");
1217}
1218
1219static void test_usr(void) {
80758717 1220
ed1c99fc 1221 /* Check that /usr is not a separate fs */
80758717 1222
871c44a7
LP
1223 if (dir_is_empty("/usr") <= 0)
1224 return;
1225
2376ce13 1226 log_warning("/usr appears to be on its own filesytem and is not already mounted. This is not a supported setup. "
871c44a7
LP
1227 "Some things will probably break (sometimes even silently) in mysterious ways. "
1228 "Consult http://freedesktop.org/wiki/Software/systemd/separate-usr-is-broken for more information.");
1229}
1230
1231static void test_cgroups(void) {
1232
1233 if (access("/proc/cgroups", F_OK) >= 0)
1234 return;
1235
1236 log_warning("CONFIG_CGROUPS was not set when your kernel was compiled. "
1237 "Systems without control groups are not supported. "
1238 "We will now sleep for 10s, and then continue boot-up. "
1239 "Expect breakage and please do not file bugs. "
966a5d37
LP
1240 "Instead fix your kernel and enable CONFIG_CGROUPS. "
1241 "Consult http://0pointer.de/blog/projects/cgroups-vs-cgroups.html for more information.");
871c44a7
LP
1242
1243 sleep(10);
6ee5bbf8
LP
1244}
1245
a07fdfa3
LP
1246static int initialize_join_controllers(void) {
1247 /* By default, mount "cpu" + "cpuacct" together, and "net_cls"
1248 * + "net_prio". We'd like to add "cpuset" to the mix, but
1249 * "cpuset" does't really work for groups with no initialized
1250 * attributes. */
1251
1252 arg_join_controllers = new(char**, 3);
1253 if (!arg_join_controllers)
1254 return -ENOMEM;
1255
1256 arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
1257 if (!arg_join_controllers[0])
1258 return -ENOMEM;
1259
1260 arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
1261 if (!arg_join_controllers[1])
1262 return -ENOMEM;
1263
1264 arg_join_controllers[2] = NULL;
1265 return 0;
1266}
1267
60918275
LP
1268int main(int argc, char *argv[]) {
1269 Manager *m = NULL;
22f4096c 1270 int r, retval = EXIT_FAILURE;
9d76d730
LP
1271 usec_t before_startup, after_startup;
1272 char timespan[FORMAT_TIMESPAN_MAX];
a16e1123
LP
1273 FDSet *fds = NULL;
1274 bool reexecute = false;
b9080b03 1275 const char *shutdown_verb = NULL;
e9ddabc2 1276 dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
5d6b1584 1277 static char systemd[] = "systemd";
2660882b 1278 bool skip_setup = false;
0b3325e7
LP
1279 int j;
1280 bool loaded_policy = false;
e96d6be7 1281 bool arm_reboot_watchdog = false;
bf4df7c3 1282 bool queue_default_job = false;
41669317 1283 char *switch_root_dir = NULL, *switch_root_init = NULL;
4096d6f5 1284 static struct rlimit saved_rlimit_nofile = { 0, 0 };
27b14a22 1285
058dc6f3 1286#ifdef HAVE_SYSV_COMPAT
2cb1a60d 1287 if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
35b8ca3a 1288 /* This is compatibility support for SysV, where
2cb1a60d
LP
1289 * calling init as a user is identical to telinit. */
1290
1291 errno = -ENOENT;
1292 execv(SYSTEMCTL_BINARY_PATH, argv);
1293 log_error("Failed to exec " SYSTEMCTL_BINARY_PATH ": %m");
1294 return 1;
1295 }
058dc6f3 1296#endif
2cb1a60d 1297
0b3325e7
LP
1298 /* Determine if this is a reexecution or normal bootup. We do
1299 * the full command line parsing much later, so let's just
1300 * have a quick peek here. */
0b3325e7
LP
1301 for (j = 1; j < argc; j++)
1302 if (streq(argv[j], "--deserialize")) {
2660882b 1303 skip_setup = true;
7aaa27f2 1304 break;
0b3325e7
LP
1305 }
1306
2660882b
LP
1307 /* If we have switched root, do all the special setup
1308 * things */
d03bc1b8 1309 for (j = 1; j < argc; j++)
2660882b
LP
1310 if (streq(argv[j], "--switched-root")) {
1311 skip_setup = false;
d03bc1b8
HH
1312 break;
1313 }
1314
f3b6a3ed
LP
1315 /* If we get started via the /sbin/init symlink then we are
1316 called 'init'. After a subsequent reexecution we are then
1317 called 'systemd'. That is confusing, hence let's call us
1318 systemd right-away. */
f3b6a3ed
LP
1319 program_invocation_short_name = systemd;
1320 prctl(PR_SET_NAME, systemd);
5d6b1584 1321
9a0e6896
LP
1322 saved_argv = argv;
1323 saved_argc = argc;
f3b6a3ed 1324
2cc59dbf 1325 log_show_color(isatty(STDERR_FILENO) > 0);
bbe63281 1326
a866073d
LP
1327 if (getpid() == 1 && detect_container(NULL) <= 0) {
1328
1329 /* Running outside of a container as PID 1 */
67445f4e 1330 arg_running_as = SYSTEMD_SYSTEM;
a866073d
LP
1331 make_null_stdio();
1332 log_set_target(LOG_TARGET_KMSG);
1333 log_open();
1334
c3ba6250
HH
1335 if (in_initrd()) {
1336 char *rd_timestamp = NULL;
1337
1338 dual_timestamp_get(&initrd_timestamp);
1339 asprintf(&rd_timestamp, "%llu %llu",
1340 (unsigned long long) initrd_timestamp.realtime,
1341 (unsigned long long) initrd_timestamp.monotonic);
1342 if (rd_timestamp) {
1343 setenv("RD_TIMESTAMP", rd_timestamp, 1);
1344 free(rd_timestamp);
1345 }
1346 }
1347
2660882b 1348 if (!skip_setup) {
0b3325e7
LP
1349 if (selinux_setup(&loaded_policy) < 0)
1350 goto finish;
81611586
RS
1351 if (ima_setup() < 0)
1352 goto finish;
1353 }
0b3325e7 1354
e9a5ef7c 1355 if (label_init(NULL) < 0)
0ff4cdd9 1356 goto finish;
7948c4df 1357
72edcff5 1358 if (!skip_setup) {
0b3325e7
LP
1359 if (hwclock_is_localtime() > 0) {
1360 int min;
7948c4df 1361
72edcff5
KS
1362 /* The first-time call to settimeofday() does a time warp in the kernel */
1363 r = hwclock_set_timezone(&min);
0b3325e7
LP
1364 if (r < 0)
1365 log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
1366 else
1367 log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
19e65613
KS
1368 } else if (!in_initrd()) {
1369 /*
1370 * Do dummy first-time call to seal the kernel's time warp magic
1371 *
1372 * Do not call this this from inside the initrd. The initrd might not
1373 * carry /etc/adjtime with LOCAL, but the real system could be set up
1374 * that way. In such case, we need to delay the time-warp or the sealing
1375 * until we reach the real system.
1376 */
72edcff5 1377 hwclock_reset_timezone();
871e5809 1378
72edcff5
KS
1379 /* Tell the kernel our time zone */
1380 r = hwclock_set_timezone(NULL);
1381 if (r < 0)
1382 log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
1383 }
1384 }
a866073d
LP
1385
1386 /* Set the default for later on, but don't actually
1387 * open the logs like this for now. Note that if we
1388 * are transitioning from the initrd there might still
1389 * be journal fd open, and we shouldn't attempt
1390 * opening that before we parsed /proc/cmdline which
1391 * might redirect output elsewhere. */
1392 log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
1393
1394 } else if (getpid() == 1) {
1395
1396 /* Running inside a container, as PID 1 */
67445f4e 1397 arg_running_as = SYSTEMD_SYSTEM;
a866073d
LP
1398 log_set_target(LOG_TARGET_CONSOLE);
1399 log_open();
1400
1401 /* For the later on, see above... */
1402 log_set_target(LOG_TARGET_JOURNAL);
1403
bbe63281 1404 } else {
a866073d
LP
1405
1406 /* Running as user instance */
67445f4e 1407 arg_running_as = SYSTEMD_USER;
eeecf6e6 1408 log_set_target(LOG_TARGET_AUTO);
871e5809 1409 log_open();
bbe63281 1410 }
a5dab5ce 1411
0c85a4f3 1412 /* Initialize default unit */
6afa301b
LP
1413 r = set_default_unit(SPECIAL_DEFAULT_TARGET);
1414 if (r < 0) {
14212119 1415 log_error("Failed to set default unit %s: %s", SPECIAL_DEFAULT_TARGET, strerror(-r));
f170852a 1416 goto finish;
14212119 1417 }
60918275 1418
a07fdfa3
LP
1419 r = initialize_join_controllers();
1420 if (r < 0)
0c85a4f3
LP
1421 goto finish;
1422
f170852a
LP
1423 /* Mount /proc, /sys and friends, so that /proc/cmdline and
1424 * /proc/$PID/fd is available. */
0c85a4f3
LP
1425 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1426 r = mount_setup(loaded_policy);
1427 if (r < 0)
8efe3c01 1428 goto finish;
0c85a4f3 1429 }
4ade7963
LP
1430
1431 /* Reset all signal handlers. */
1432 assert_se(reset_all_signal_handlers() == 0);
1433
078e4539 1434 /* If we are init, we can block sigkill. Yay. */
9a34ec5f 1435 ignore_signals(SIGNALS_IGNORE, -1);
078e4539 1436
487393e9
LP
1437 if (parse_config_file() < 0)
1438 goto finish;
1439
67445f4e 1440 if (arg_running_as == SYSTEMD_SYSTEM)
a5dab5ce
LP
1441 if (parse_proc_cmdline() < 0)
1442 goto finish;
f170852a
LP
1443
1444 log_parse_environment();
1445
1446 if (parse_argv(argc, argv) < 0)
1447 goto finish;
1448
6bae23a0
TB
1449 if (arg_action == ACTION_TEST &&
1450 geteuid() == 0) {
b5c6cf87
LP
1451 log_error("Don't run test mode as root.");
1452 goto finish;
1453 }
1454
6bae23a0
TB
1455 if (arg_running_as == SYSTEMD_USER &&
1456 arg_action == ACTION_RUN &&
1457 sd_booted() <= 0) {
1458 log_error("Trying to run as user instance, but the system has not been booted with systemd.");
1459 goto finish;
1460 }
1461
67445f4e 1462 if (arg_running_as == SYSTEMD_SYSTEM &&
fe783b03
LP
1463 arg_action == ACTION_RUN &&
1464 running_in_chroot() > 0) {
1465 log_error("Cannot be run in a chroot() environment.");
1466 goto finish;
1467 }
1468
fa0f4d8a 1469 if (arg_action == ACTION_HELP) {
f170852a
LP
1470 retval = help();
1471 goto finish;
9ba0bc4e
ZJS
1472 } else if (arg_action == ACTION_VERSION) {
1473 retval = version();
1474 goto finish;
fa0f4d8a 1475 } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
e537352b 1476 unit_dump_config_items(stdout);
22f4096c 1477 retval = EXIT_SUCCESS;
e537352b 1478 goto finish;
fa0f4d8a 1479 } else if (arg_action == ACTION_DONE) {
22f4096c 1480 retval = EXIT_SUCCESS;
4288f619 1481 goto finish;
f170852a
LP
1482 }
1483
fa0f4d8a 1484 assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
f170852a 1485
871e5809
LP
1486 /* Close logging fds, in order not to confuse fdset below */
1487 log_close();
1488
a16e1123 1489 /* Remember open file descriptors for later deserialization */
01e10de3
LP
1490 r = fdset_new_fill(&fds);
1491 if (r < 0) {
1492 log_error("Failed to allocate fd set: %s", strerror(-r));
1493 goto finish;
1494 } else
1495 fdset_cloexec(fds, true);
a16e1123 1496
01e10de3 1497 if (serialization)
a16e1123 1498 assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
a16e1123 1499
09082a94 1500 /* Set up PATH unless it is already set */
e537352b 1501 setenv("PATH",
2c6db6fb 1502#ifdef HAVE_SPLIT_USR
e537352b 1503 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
2c6db6fb
LP
1504#else
1505 "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
1506#endif
67445f4e 1507 arg_running_as == SYSTEMD_SYSTEM);
09082a94 1508
67445f4e 1509 if (arg_running_as == SYSTEMD_SYSTEM) {
71ecc858
LP
1510 /* Parse the data passed to us. We leave this
1511 * variables set, but the manager later on will not
1512 * pass them on to our children. */
2660882b 1513 if (!in_initrd())
c3ba6250 1514 parse_initrd_timestamp(&initrd_timestamp);
e9ddabc2
LP
1515
1516 /* Unset some environment variables passed in from the
1517 * kernel that don't really make sense for us. */
39439087
LP
1518 unsetenv("HOME");
1519 unsetenv("TERM");
b770165a 1520
9543ad16
LP
1521 /* When we are invoked by a shell, these might be set,
1522 * but make little sense to pass on */
1523 unsetenv("PWD");
1524 unsetenv("SHLVL");
1525 unsetenv("_");
1526
2660882b 1527 /* When we are invoked by a chroot-like tool such as
9f28b98e
LP
1528 * nspawn, these might be set, but make little sense
1529 * to pass on */
1530 unsetenv("USER");
1531 unsetenv("LOGNAME");
1532
01e10de3
LP
1533 /* We suppress the socket activation env vars, as
1534 * we'll try to match *any* open fd to units if
1535 * possible. */
1536 unsetenv("LISTEN_FDS");
1537 unsetenv("LISTEN_PID");
1538
b770165a
LP
1539 /* All other variables are left as is, so that clients
1540 * can still read them via /proc/1/environ */
39439087 1541 }
1104f3c1 1542
f170852a
LP
1543 /* Move out of the way, so that we won't block unmounts */
1544 assert_se(chdir("/") == 0);
1545
67445f4e 1546 if (arg_running_as == SYSTEMD_SYSTEM) {
80876c20
LP
1547 /* Become a session leader if we aren't one yet. */
1548 setsid();
4ade7963 1549
80876c20
LP
1550 /* Disable the umask logic */
1551 umask(0);
1552 }
1553
843d2643
LP
1554 /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
1555 dbus_connection_set_change_sigpipe(FALSE);
1556
2146621b
LP
1557 /* Reset the console, but only if this is really init and we
1558 * are freshly booted */
67445f4e 1559 if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
2660882b 1560 console_setup(getpid() == 1 && !skip_setup);
4ade7963 1561
18149b9f 1562 /* Open the logging devices, if possible and necessary */
843d2643 1563 log_open();
4ade7963 1564
5373d602
LP
1565 /* Make sure we leave a core dump without panicing the
1566 * kernel. */
4fc935ca
LP
1567 if (getpid() == 1)
1568 install_crash_handler();
97c4f35c 1569
0c85a4f3
LP
1570 if (geteuid() == 0 && !getenv("SYSTEMD_SKIP_API_MOUNTS")) {
1571 r = mount_cgroup_controllers(arg_join_controllers);
1572 if (r < 0)
1573 goto finish;
1574 }
1575
67445f4e 1576 if (arg_running_as == SYSTEMD_SYSTEM) {
c20f5ac7
LP
1577 const char *virtualization = NULL;
1578
bc270841 1579 log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
c20f5ac7
LP
1580
1581 detect_virtualization(&virtualization);
1582 if (virtualization)
1583 log_info("Detected virtualization '%s'.", virtualization);
1584
26a1efdf
LP
1585 if (in_initrd())
1586 log_info("Running in initial RAM disk.");
1587
c20f5ac7 1588 } else
bc270841 1589 log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
a5dab5ce 1590
67445f4e 1591 if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
72bca11b
LP
1592 locale_setup();
1593
6faa1114 1594 if (arg_show_status || plymouth_running())
888c6216
LP
1595 status_welcome();
1596
e3043162 1597#ifdef HAVE_KMOD
888c6216 1598 kmod_setup();
e3043162 1599#endif
888c6216 1600 hostname_setup();
d7ccca2e 1601 machine_id_setup();
888c6216 1602 loopback_setup();
490aed58 1603
6ee5bbf8 1604 test_mtab();
80758717 1605 test_usr();
871c44a7 1606 test_cgroups();
af5bc85d 1607 }
302e8c4c 1608
67445f4e 1609 if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
e96d6be7
LP
1610 watchdog_set_timeout(&arg_runtime_watchdog);
1611
aa0f64ac
LP
1612 if (arg_timer_slack_nsec != (nsec_t) -1)
1613 if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
1614 log_error("Failed to adjust timer slack: %m");
1615
ec8927ca
LP
1616 if (arg_capability_bounding_set_drop) {
1617 r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
1618 if (r < 0) {
1619 log_error("Failed to drop capability bounding set: %s", strerror(-r));
1620 goto finish;
1621 }
939b8f14
LP
1622 r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
1623 if (r < 0) {
1624 log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
1625 goto finish;
1626 }
ec8927ca
LP
1627 }
1628
67445f4e 1629 if (arg_running_as == SYSTEMD_USER) {
d4447f4d 1630 /* Become reaper of our children */
8b8ffe68
LP
1631 if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
1632 log_warning("Failed to make us a subreaper: %m");
1633 if (errno == EINVAL)
ddfa5101 1634 log_info("Perhaps the kernel version is too old (< 3.4?)");
8b8ffe68 1635 }
d4447f4d
AK
1636 }
1637
67445f4e 1638 if (arg_running_as == SYSTEMD_SYSTEM)
4096d6f5
LP
1639 bump_rlimit_nofile(&saved_rlimit_nofile);
1640
e96d6be7
LP
1641 r = manager_new(arg_running_as, &m);
1642 if (r < 0) {
8e274523 1643 log_error("Failed to allocate manager object: %s", strerror(-r));
60918275
LP
1644 goto finish;
1645 }
1646
9e58ff9c 1647 m->confirm_spawn = arg_confirm_spawn;
0a494f1f
LP
1648 m->default_std_output = arg_default_std_output;
1649 m->default_std_error = arg_default_std_error;
e96d6be7
LP
1650 m->runtime_watchdog = arg_runtime_watchdog;
1651 m->shutdown_watchdog = arg_shutdown_watchdog;
9e58ff9c 1652
c93ff2e9
FC
1653 manager_set_default_rlimits(m, arg_default_rlimit);
1654
e9ddabc2
LP
1655 if (dual_timestamp_is_set(&initrd_timestamp))
1656 m->initrd_timestamp = initrd_timestamp;
1657
06d4c99a
LP
1658 if (arg_default_controllers)
1659 manager_set_default_controllers(m, arg_default_controllers);
1660
27d340c7
LP
1661 manager_set_show_status(m, arg_show_status);
1662
bf4df7c3
LP
1663 /* Remember whether we should queue the default job */
1664 queue_default_job = !serialization || arg_switched_root;
1665
9d76d730
LP
1666 before_startup = now(CLOCK_MONOTONIC);
1667
e96d6be7
LP
1668 r = manager_startup(m, serialization, fds);
1669 if (r < 0)
6e2ef85b 1670 log_error("Failed to fully start up daemon: %s", strerror(-r));
a16e1123 1671
bf4df7c3
LP
1672 /* This will close all file descriptors that were opened, but
1673 * not claimed by any unit. */
01e10de3 1674 fdset_free(fds);
f50e0a01 1675
a16e1123
LP
1676 if (serialization) {
1677 fclose(serialization);
1678 serialization = NULL;
bf4df7c3
LP
1679 }
1680
1681 if (queue_default_job) {
398ef8ba 1682 DBusError error;
1c27d3f3 1683 Unit *target = NULL;
bacbccb7 1684 Job *default_unit_job;
398ef8ba
LP
1685
1686 dbus_error_init(&error);
1687
fa0f4d8a 1688 log_debug("Activating default unit: %s", arg_default_unit);
a16e1123 1689
e96d6be7
LP
1690 r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
1691 if (r < 0) {
398ef8ba
LP
1692 log_error("Failed to load default target: %s", bus_error(&error, r));
1693 dbus_error_free(&error);
ac155bb8
MS
1694 } else if (target->load_state == UNIT_ERROR)
1695 log_error("Failed to load default target: %s", strerror(-target->load_error));
1696 else if (target->load_state == UNIT_MASKED)
6daf4f90 1697 log_error("Default target masked.");
27b14a22 1698
ac155bb8 1699 if (!target || target->load_state != UNIT_LOADED) {
a16e1123 1700 log_info("Trying to load rescue target...");
1c27d3f3 1701
e96d6be7
LP
1702 r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
1703 if (r < 0) {
398ef8ba
LP
1704 log_error("Failed to load rescue target: %s", bus_error(&error, r));
1705 dbus_error_free(&error);
a16e1123 1706 goto finish;
ac155bb8
MS
1707 } else if (target->load_state == UNIT_ERROR) {
1708 log_error("Failed to load rescue target: %s", strerror(-target->load_error));
1c27d3f3 1709 goto finish;
ac155bb8 1710 } else if (target->load_state == UNIT_MASKED) {
6daf4f90 1711 log_error("Rescue target masked.");
00dc5d76 1712 goto finish;
a16e1123
LP
1713 }
1714 }
37d88da7 1715
ac155bb8 1716 assert(target->load_state == UNIT_LOADED);
00dc5d76 1717
fa0f4d8a 1718 if (arg_action == ACTION_TEST) {
40d50879 1719 printf("-> By units:\n");
a16e1123
LP
1720 manager_dump_units(m, stdout, "\t");
1721 }
1722
bacbccb7
MS
1723 r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
1724 if (r < 0) {
398ef8ba
LP
1725 log_error("Failed to start default target: %s", bus_error(&error, r));
1726 dbus_error_free(&error);
37d88da7
LP
1727 goto finish;
1728 }
bacbccb7 1729 m->default_unit_job_id = default_unit_job->id;
60918275 1730
07672f49
LP
1731 after_startup = now(CLOCK_MONOTONIC);
1732 log_full(arg_action == ACTION_TEST ? LOG_INFO : LOG_DEBUG,
1733 "Loaded units and determined initial transaction in %s.",
1734 format_timespan(timespan, sizeof(timespan), after_startup - before_startup));
1735
fa0f4d8a 1736 if (arg_action == ACTION_TEST) {
40d50879 1737 printf("-> By jobs:\n");
a16e1123 1738 manager_dump_jobs(m, stdout, "\t");
22f4096c 1739 retval = EXIT_SUCCESS;
a16e1123
LP
1740 goto finish;
1741 }
e965d56d 1742 }
d46de8a1 1743
a16e1123 1744 for (;;) {
e96d6be7
LP
1745 r = manager_loop(m);
1746 if (r < 0) {
a16e1123
LP
1747 log_error("Failed to run mainloop: %s", strerror(-r));
1748 goto finish;
1749 }
11dd41ce 1750
a16e1123 1751 switch (m->exit_code) {
e965d56d 1752
a16e1123 1753 case MANAGER_EXIT:
22f4096c 1754 retval = EXIT_SUCCESS;
a16e1123
LP
1755 log_debug("Exit.");
1756 goto finish;
e965d56d 1757
a16e1123 1758 case MANAGER_RELOAD:
e015090f 1759 log_info("Reloading.");
e96d6be7
LP
1760 r = manager_reload(m);
1761 if (r < 0)
a16e1123
LP
1762 log_error("Failed to reload: %s", strerror(-r));
1763 break;
cea8e32e 1764
a16e1123 1765 case MANAGER_REEXECUTE:
664f88a7 1766
6b78f9b4 1767 if (prepare_reexecute(m, &serialization, &fds, true) < 0)
a16e1123 1768 goto finish;
60918275 1769
a16e1123 1770 reexecute = true;
e015090f 1771 log_notice("Reexecuting.");
a16e1123
LP
1772 goto finish;
1773
664f88a7
LP
1774 case MANAGER_SWITCH_ROOT:
1775 /* Steal the switch root parameters */
41669317 1776 switch_root_dir = m->switch_root;
664f88a7
LP
1777 switch_root_init = m->switch_root_init;
1778 m->switch_root = m->switch_root_init = NULL;
1779
1780 if (!switch_root_init)
6b78f9b4 1781 if (prepare_reexecute(m, &serialization, &fds, false) < 0)
664f88a7
LP
1782 goto finish;
1783
1784 reexecute = true;
1785 log_notice("Switching root.");
1786 goto finish;
1787
b9080b03
FF
1788 case MANAGER_REBOOT:
1789 case MANAGER_POWEROFF:
1790 case MANAGER_HALT:
1791 case MANAGER_KEXEC: {
1792 static const char * const table[_MANAGER_EXIT_CODE_MAX] = {
1793 [MANAGER_REBOOT] = "reboot",
1794 [MANAGER_POWEROFF] = "poweroff",
1795 [MANAGER_HALT] = "halt",
1796 [MANAGER_KEXEC] = "kexec"
1797 };
1798
1799 assert_se(shutdown_verb = table[m->exit_code]);
e96d6be7 1800 arm_reboot_watchdog = m->exit_code == MANAGER_REBOOT;
b9080b03
FF
1801
1802 log_notice("Shutting down.");
1803 goto finish;
1804 }
1805
a16e1123
LP
1806 default:
1807 assert_not_reached("Unknown exit code.");
1808 }
1809 }
f170852a 1810
60918275
LP
1811finish:
1812 if (m)
1813 manager_free(m);
1814
c93ff2e9 1815 for (j = 0; j < RLIMIT_NLIMITS; j++)
4096d6f5 1816 free(arg_default_rlimit[j]);
c93ff2e9 1817
fa0f4d8a 1818 free(arg_default_unit);
06d4c99a 1819 strv_free(arg_default_controllers);
0c85a4f3 1820 free_join_controllers();
b9cd2ec1 1821
ea430986 1822 dbus_shutdown();
b2bb3dbe
LP
1823 label_finish();
1824
a16e1123 1825 if (reexecute) {
664f88a7 1826 const char **args;
e564a982 1827 unsigned i, args_size;
a16e1123 1828
664f88a7
LP
1829 /* Close and disarm the watchdog, so that the new
1830 * instance can reinitialize it, but doesn't get
1831 * rebooted while we do that */
1832 watchdog_close(true);
a16e1123 1833
4096d6f5
LP
1834 /* Reset the RLIMIT_NOFILE to the kernel default, so
1835 * that the new systemd can pass the kernel default to
1836 * its child processes */
1837 if (saved_rlimit_nofile.rlim_cur > 0)
1838 setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
1839
41669317 1840 if (switch_root_dir) {
cee530bb
LP
1841 /* Kill all remaining processes from the
1842 * initrd, but don't wait for them, so that we
1843 * can handle the SIGCHLD for them after
1844 * deserializing. */
1845 broadcast_signal(SIGTERM, false);
bd3fa1d2
LP
1846
1847 /* And switch root */
41669317
LP
1848 r = switch_root(switch_root_dir);
1849 if (r < 0)
1850 log_error("Failed to switch root, ignoring: %s", strerror(-r));
1851 }
a16e1123 1852
d03bc1b8 1853 args_size = MAX(6, argc+1);
e564a982 1854 args = newa(const char*, args_size);
a16e1123 1855
664f88a7
LP
1856 if (!switch_root_init) {
1857 char sfd[16];
a16e1123 1858
664f88a7
LP
1859 /* First try to spawn ourselves with the right
1860 * path, and with full serialization. We do
1861 * this only if the user didn't specify an
1862 * explicit init to spawn. */
edb9aaa8 1863
664f88a7
LP
1864 assert(serialization);
1865 assert(fds);
edb9aaa8 1866
664f88a7
LP
1867 snprintf(sfd, sizeof(sfd), "%i", fileno(serialization));
1868 char_array_0(sfd);
edb9aaa8 1869
664f88a7
LP
1870 i = 0;
1871 args[i++] = SYSTEMD_BINARY_PATH;
41669317 1872 if (switch_root_dir)
2660882b 1873 args[i++] = "--switched-root";
67445f4e 1874 args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user";
664f88a7
LP
1875 args[i++] = "--deserialize";
1876 args[i++] = sfd;
1877 args[i++] = NULL;
edb9aaa8 1878
e564a982 1879 assert(i <= args_size);
664f88a7
LP
1880 execv(args[0], (char* const*) args);
1881 }
6e98720f 1882
664f88a7
LP
1883 /* Try the fallback, if there is any, without any
1884 * serialization. We pass the original argv[] and
1885 * envp[]. (Well, modulo the ordering changes due to
1886 * getopt() in argv[], and some cleanups in envp[],
1887 * but let's hope that doesn't matter.) */
a16e1123 1888
b8f83232 1889 if (serialization) {
664f88a7 1890 fclose(serialization);
b8f83232
LP
1891 serialization = NULL;
1892 }
a16e1123 1893
b8f83232 1894 if (fds) {
664f88a7 1895 fdset_free(fds);
b8f83232
LP
1896 fds = NULL;
1897 }
a16e1123 1898
a504223d
HH
1899 /* Reopen the console */
1900 make_console_stdio();
1901
b8f83232 1902 for (j = 1, i = 1; j < argc; j++)
664f88a7 1903 args[i++] = argv[j];
a16e1123 1904 args[i++] = NULL;
e564a982 1905 assert(i <= args_size);
b8f83232
LP
1906
1907 if (switch_root_init) {
1908 args[0] = switch_root_init;
1909 execv(args[0], (char* const*) args);
1910 log_warning("Failed to execute configured init, trying fallback: %m");
1911 }
1912
1913 args[0] = "/sbin/init";
a16e1123
LP
1914 execv(args[0], (char* const*) args);
1915
745e2fb7
KS
1916 if (errno == ENOENT) {
1917 log_warning("No /sbin/init, trying fallback");
b8f83232 1918
745e2fb7
KS
1919 args[0] = "/bin/sh";
1920 args[1] = NULL;
1921 execv(args[0], (char* const*) args);
1922 log_error("Failed to execute /bin/sh, giving up: %m");
1923 } else
1924 log_warning("Failed to execute /sbin/init, giving up: %m");
a16e1123
LP
1925 }
1926
1927 if (serialization)
1928 fclose(serialization);
1929
1930 if (fds)
1931 fdset_free(fds);
1932
b9080b03
FF
1933 if (shutdown_verb) {
1934 const char * command_line[] = {
1935 SYSTEMD_SHUTDOWN_BINARY_PATH,
1936 shutdown_verb,
1937 NULL
1938 };
d18f337c 1939 char **env_block;
b9080b03 1940
e96d6be7 1941 if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
d18f337c
LP
1942 char e[32];
1943
e96d6be7
LP
1944 /* If we reboot let's set the shutdown
1945 * watchdog and tell the shutdown binary to
1946 * repeatedly ping it */
1947 watchdog_set_timeout(&arg_shutdown_watchdog);
1948 watchdog_close(false);
1949
1950 /* Tell the binary how often to ping */
1951 snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
1952 char_array_0(e);
d18f337c
LP
1953
1954 env_block = strv_append(environ, e);
1955 } else {
1956 env_block = strv_copy(environ);
e96d6be7 1957 watchdog_close(true);
d18f337c 1958 }
e96d6be7 1959
d18f337c
LP
1960 execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
1961 free(env_block);
b9080b03
FF
1962 log_error("Failed to execute shutdown binary, freezing: %m");
1963 }
1964
c3b3c274
LP
1965 if (getpid() == 1)
1966 freeze();
1967
60918275
LP
1968 return retval;
1969}