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