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