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