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