chiark / gitweb /
service: remove unneccesary Socket.got_socket_fd
[elogind.git] / src / core / main.c
index 0629d142ff556b519214c8e7d683210cdb5343a6..6c3d9bfb189d071000d120e33e43338be01f1253 100644 (file)
@@ -19,8 +19,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <dbus/dbus.h>
-
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/prctl.h>
 #include <sys/mount.h>
 
+#ifdef HAVE_VALGRIND_VALGRIND_H
+#include <valgrind/valgrind.h>
+#endif
+
+#include "sd-daemon.h"
+#include "sd-messages.h"
+#include "sd-bus.h"
 #include "manager.h"
 #include "log.h"
 #include "load-fragment.h"
 #include "fdset.h"
 #include "special.h"
 #include "conf-parser.h"
-#include "dbus-common.h"
 #include "missing.h"
 #include "label.h"
 #include "build.h"
 #include "killall.h"
 #include "env-util.h"
 #include "hwclock.h"
-#include "sd-daemon.h"
-#include "sd-messages.h"
+#include "fileio.h"
+#include "dbus-manager.h"
+#include "bus-error.h"
+#include "bus-util.h"
 
 #include "mount-setup.h"
 #include "loopback-setup.h"
-#ifdef HAVE_KMOD
-#include "kmod-setup.h"
-#endif
 #include "hostname-setup.h"
 #include "machine-id-setup.h"
 #include "selinux-setup.h"
 #include "ima-setup.h"
-#include "fileio.h"
 #include "smack-setup.h"
+#ifdef HAVE_KMOD
+#include "kmod-setup.h"
+#endif
 
 static enum {
         ACTION_RUN,
@@ -90,6 +95,11 @@ static bool arg_switched_root = false;
 static char ***arg_join_controllers = NULL;
 static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
 static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
+static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
+static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
+static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
+static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
+static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
 static usec_t arg_runtime_watchdog = 0;
 static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
 static char **arg_default_environment = NULL;
@@ -121,7 +131,7 @@ _noreturn_ static void crash(int sig) {
 
                 pid = fork();
                 if (pid < 0)
-                        log_error("Caught <%s>, cannot fork for core dump: %s", signal_to_string(sig), strerror(errno));
+                        log_error("Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
 
                 else if (pid == 0) {
                         struct rlimit rl = {};
@@ -425,6 +435,7 @@ static int parse_proc_cmdline_word(const char *word) {
                         const char *filename,                         \
                         unsigned line,                                \
                         const char *section,                          \
+                        unsigned section_line,                        \
                         const char *lvalue,                           \
                         int ltype,                                    \
                         const char *rvalue,                           \
@@ -456,6 +467,7 @@ static int config_parse_cpu_affinity2(const char *unit,
                                       const char *filename,
                                       unsigned line,
                                       const char *section,
+                                      unsigned section_line,
                                       const char *lvalue,
                                       int ltype,
                                       const char *rvalue,
@@ -528,6 +540,7 @@ static int config_parse_join_controllers(const char *unit,
                                          const char *filename,
                                          unsigned line,
                                          const char *section,
+                                         unsigned section_line,
                                          const char *lvalue,
                                          int ltype,
                                          const char *rvalue,
@@ -636,6 +649,11 @@ static int parse_config_file(void) {
                 { "Manager", "CPUAffinity",           config_parse_cpu_affinity2, 0, NULL                    },
                 { "Manager", "DefaultStandardOutput", config_parse_output,       0, &arg_default_std_output  },
                 { "Manager", "DefaultStandardError",  config_parse_output,       0, &arg_default_std_error   },
+                { "Manager", "DefaultTimeoutStartSec", config_parse_sec,         0, &arg_default_timeout_start_usec },
+                { "Manager", "DefaultTimeoutStopSec", config_parse_sec,          0, &arg_default_timeout_stop_usec  },
+                { "Manager", "DefaultRestartSec",     config_parse_sec,          0, &arg_default_restart_usec  },
+                { "Manager", "DefaultStartLimitInterval", config_parse_sec,      0, &arg_default_start_limit_interval },
+                { "Manager", "DefaultStartLimitBurst", config_parse_unsigned,    0, &arg_default_start_limit_burst },
                 { "Manager", "JoinControllers",       config_parse_join_controllers, 0, &arg_join_controllers },
                 { "Manager", "RuntimeWatchdogSec",    config_parse_sec,          0, &arg_runtime_watchdog    },
                 { "Manager", "ShutdownWatchdogSec",   config_parse_sec,          0, &arg_shutdown_watchdog   },
@@ -685,19 +703,14 @@ static int parse_config_file(void) {
 static int parse_proc_cmdline(void) {
         _cleanup_free_ char *line = NULL;
         char *w, *state;
-        int r;
         size_t l;
+        int r;
 
-        /* Don't read /proc/cmdline if we are in a container, since
-         * that is only relevant for the host system */
-        if (detect_container(NULL) > 0)
-                return 0;
-
-        r = read_one_line_file("/proc/cmdline", &line);
-        if (r < 0) {
+        r = proc_cmdline(&line);
+        if (r < 0)
                 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
+        if (r <= 0)
                 return 0;
-        }
 
         FOREACH_WORD_QUOTED(w, l, line, state) {
                 _cleanup_free_ char *word;
@@ -735,7 +748,6 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_SHOW_STATUS,
                 ARG_DESERIALIZE,
                 ARG_SWITCHED_ROOT,
-                ARG_INTROSPECT,
                 ARG_DEFAULT_STD_OUTPUT,
                 ARG_DEFAULT_STD_ERROR
         };
@@ -758,7 +770,6 @@ static int parse_argv(int argc, char *argv[]) {
                 { "show-status",              optional_argument, NULL, ARG_SHOW_STATUS              },
                 { "deserialize",              required_argument, NULL, ARG_DESERIALIZE              },
                 { "switched-root",            no_argument,       NULL, ARG_SWITCHED_ROOT            },
-                { "introspect",               optional_argument, NULL, ARG_INTROSPECT               },
                 { "default-standard-output",  required_argument, NULL, ARG_DEFAULT_STD_OUTPUT,      },
                 { "default-standard-error",   required_argument, NULL, ARG_DEFAULT_STD_ERROR,       },
                 { NULL,                       0,                 NULL, 0                            }
@@ -930,27 +941,6 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_switched_root = true;
                         break;
 
-                case ARG_INTROSPECT: {
-                        const char * const * i = NULL;
-
-                        for (i = bus_interface_table; *i; i += 2)
-                                if (!optarg || streq(i[0], optarg)) {
-                                        fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
-                                              "<node>\n", stdout);
-                                        fputs(i[1], stdout);
-                                        fputs("</node>\n", stdout);
-
-                                        if (optarg)
-                                                break;
-                                }
-
-                        if (!i[0] && optarg)
-                                log_error("Unknown interface %s.", optarg);
-
-                        arg_action = ACTION_DONE;
-                        break;
-                }
-
                 case 'h':
                         arg_action = ACTION_HELP;
                         break;
@@ -996,11 +986,13 @@ static int parse_argv(int argc, char *argv[]) {
                  * relevant for the container, hence we rely on argv[]
                  * instead. */
 
-                for (a = argv; a < argv + argc; a++)
-                        if ((r = parse_proc_cmdline_word(*a)) < 0) {
+                for (a = argv; a < argv + argc; a++) {
+                        r = parse_proc_cmdline_word(*a);
+                        if (r < 0) {
                                 log_error("Failed on cmdline argument %s: %s", *a, strerror(-r));
                                 return r;
                         }
+                }
         }
 
         return 0;
@@ -1013,7 +1005,6 @@ static int help(void) {
                "  -h --help                      Show this help\n"
                "     --test                      Determine startup sequence, dump it and exit\n"
                "     --dump-configuration-items  Dump understood unit configuration items\n"
-               "     --introspect[=INTERFACE]    Extract D-Bus interface data\n"
                "     --unit=UNIT                 Set default unit\n"
                "     --system                    Run a system instance, even if PID != 1\n"
                "     --user                      Run a user instance\n"
@@ -1056,7 +1047,7 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
 
         /* Make sure nothing is really destructed when we shut down */
         m->n_reloading ++;
-        bus_broadcast_reloading(m, true);
+        bus_manager_send_reloading(m, true);
 
         fds = fdset_new();
         if (!fds) {
@@ -1218,6 +1209,8 @@ int main(int argc, char *argv[]) {
         dual_timestamp initrd_timestamp = { 0ULL, 0ULL };
         dual_timestamp userspace_timestamp = { 0ULL, 0ULL };
         dual_timestamp kernel_timestamp = { 0ULL, 0ULL };
+        dual_timestamp security_start_timestamp = { 0ULL, 0ULL };
+        dual_timestamp security_finish_timestamp = { 0ULL, 0ULL };
         static char systemd[] = "systemd";
         bool skip_setup = false;
         int j;
@@ -1282,12 +1275,14 @@ int main(int argc, char *argv[]) {
 
                 if (!skip_setup) {
                         mount_setup_early();
+                        dual_timestamp_get(&security_start_timestamp);
                         if (selinux_setup(&loaded_policy) < 0)
                                 goto finish;
                         if (ima_setup() < 0)
                                 goto finish;
                         if (smack_setup() < 0)
                                 goto finish;
+                        dual_timestamp_get(&security_finish_timestamp);
                 }
 
                 if (label_init(NULL) < 0)
@@ -1426,6 +1421,12 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
+        if (arg_running_as == SYSTEMD_USER &&
+            !getenv("XDG_RUNTIME_DIR")) {
+                log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set.");
+                goto finish;
+        }
+
         assert_se(arg_action == ACTION_RUN || arg_action == ACTION_TEST);
 
         /* Close logging fds, in order not to confuse fdset below */
@@ -1449,9 +1450,6 @@ int main(int argc, char *argv[]) {
         /* Move out of the way, so that we won't block unmounts */
         assert_se(chdir("/")  == 0);
 
-        /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
-        dbus_connection_set_change_sigpipe(FALSE);
-
         /* Reset the console, but only if this is really init and we
          * are freshly booted */
         if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
@@ -1533,7 +1531,7 @@ int main(int argc, char *argv[]) {
         if (arg_running_as == SYSTEMD_SYSTEM)
                 bump_rlimit_nofile(&saved_rlimit_nofile);
 
-        r = manager_new(arg_running_as, !!serialization, &m);
+        r = manager_new(arg_running_as, &m);
         if (r < 0) {
                 log_error("Failed to allocate manager object: %s", strerror(-r));
                 goto finish;
@@ -1542,16 +1540,23 @@ int main(int argc, char *argv[]) {
         m->confirm_spawn = arg_confirm_spawn;
         m->default_std_output = arg_default_std_output;
         m->default_std_error = arg_default_std_error;
+        m->default_restart_usec = arg_default_restart_usec;
+        m->default_timeout_start_usec = arg_default_timeout_start_usec;
+        m->default_timeout_stop_usec = arg_default_timeout_stop_usec;
+        m->default_start_limit_interval = arg_default_start_limit_interval;
+        m->default_start_limit_burst = arg_default_start_limit_burst;
         m->runtime_watchdog = arg_runtime_watchdog;
         m->shutdown_watchdog = arg_shutdown_watchdog;
         m->userspace_timestamp = userspace_timestamp;
         m->kernel_timestamp = kernel_timestamp;
         m->initrd_timestamp = initrd_timestamp;
+        m->security_start_timestamp = security_start_timestamp;
+        m->security_finish_timestamp = security_finish_timestamp;
 
         manager_set_default_rlimits(m, arg_default_rlimit);
 
         if (arg_default_environment)
-                manager_environment_add(m, arg_default_environment);
+                manager_environment_add(m, NULL, arg_default_environment);
 
         manager_set_show_status(m, arg_show_status);
 
@@ -1567,6 +1572,7 @@ int main(int argc, char *argv[]) {
         /* This will close all file descriptors that were opened, but
          * not claimed by any unit. */
         fdset_free(fds);
+        fds = NULL;
 
         if (serialization) {
                 fclose(serialization);
@@ -1574,19 +1580,16 @@ int main(int argc, char *argv[]) {
         }
 
         if (queue_default_job) {
-                DBusError error;
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
                 Unit *target = NULL;
                 Job *default_unit_job;
 
-                dbus_error_init(&error);
-
                 log_debug("Activating default unit: %s", arg_default_unit);
 
                 r = manager_load_unit(m, arg_default_unit, NULL, &error, &target);
-                if (r < 0) {
-                        log_error("Failed to load default target: %s", bus_error(&error, r));
-                        dbus_error_free(&error);
-                } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND)
+                if (r < 0)
+                        log_error("Failed to load default target: %s", bus_error_message(&error, r));
+                else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND)
                         log_error("Failed to load default target: %s", strerror(-target->load_error));
                 else if (target->load_state == UNIT_MASKED)
                         log_error("Default target masked.");
@@ -1596,8 +1599,7 @@ int main(int argc, char *argv[]) {
 
                         r = manager_load_unit(m, SPECIAL_RESCUE_TARGET, NULL, &error, &target);
                         if (r < 0) {
-                                log_error("Failed to load rescue target: %s", bus_error(&error, r));
-                                dbus_error_free(&error);
+                                log_error("Failed to load rescue target: %s", bus_error_message(&error, r));
                                 goto finish;
                         } else if (target->load_state == UNIT_ERROR || target->load_state == UNIT_NOT_FOUND) {
                                 log_error("Failed to load rescue target: %s", strerror(-target->load_error));
@@ -1617,18 +1619,15 @@ int main(int argc, char *argv[]) {
 
                 r = manager_add_job(m, JOB_START, target, JOB_ISOLATE, false, &error, &default_unit_job);
                 if (r == -EPERM) {
-                        log_debug("Default target could not be isolated, starting instead: %s", bus_error(&error, r));
-                        dbus_error_free(&error);
+                        log_debug("Default target could not be isolated, starting instead: %s", bus_error_message(&error, r));
 
                         r = manager_add_job(m, JOB_START, target, JOB_REPLACE, false, &error, &default_unit_job);
                         if (r < 0) {
-                                log_error("Failed to start default target: %s", bus_error(&error, r));
-                                dbus_error_free(&error);
+                                log_error("Failed to start default target: %s", bus_error_message(&error, r));
                                 goto finish;
                         }
                 } else if (r < 0) {
-                        log_error("Failed to isolate default target: %s", bus_error(&error, r));
-                        dbus_error_free(&error);
+                        log_error("Failed to isolate default target: %s", bus_error_message(&error, r));
                         goto finish;
                 }
 
@@ -1724,7 +1723,6 @@ finish:
         free(arg_default_unit);
         free_join_controllers();
 
-        dbus_shutdown();
         label_finish();
 
         if (reexecute) {
@@ -1747,7 +1745,7 @@ finish:
                          * initrd, but don't wait for them, so that we
                          * can handle the SIGCHLD for them after
                          * deserializing. */
-                        broadcast_signal(SIGTERM, false);
+                        broadcast_signal(SIGTERM, false, true);
 
                         /* And switch root */
                         r = switch_root(switch_root_dir);
@@ -1839,6 +1837,15 @@ finish:
         if (fds)
                 fdset_free(fds);
 
+#ifdef HAVE_VALGRIND_VALGRIND_H
+        /* If we are PID 1 and running under valgrind, then let's exit
+         * here explicitly. valgrind will only generate nice output on
+         * exit(), not on exec(), hence let's do the former not the
+         * latter here. */
+        if (getpid() == 1 && RUNNING_ON_VALGRIND)
+                return 0;
+#endif
+
         if (shutdown_verb) {
                 const char * command_line[] = {
                         SYSTEMD_SHUTDOWN_BINARY_PATH,