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