X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=dbc98db84ab97886872286c309d00b03b02dce91;hp=0178f107200a300e7f38199204f2f39c5d61a00d;hb=6301a98cdf26dc073f5317506c806bfa69f74cc8;hpb=bd6d2963396061ed068c4c6c54d8104b59ba91dc diff --git a/src/core/main.c b/src/core/main.c index 0178f1072..dbc98db84 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -19,8 +19,6 @@ along with systemd; If not, see . ***/ -#include - #include #include #include @@ -34,13 +32,19 @@ #include #include +#ifdef HAVE_VALGRIND_VALGRIND_H +#include +#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" @@ -54,20 +58,21 @@ #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; @@ -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 - "\n", stdout); - fputs(i[1], stdout); - fputs("\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; @@ -1265,6 +1258,10 @@ int main(int argc, char *argv[]) { log_show_color(isatty(STDERR_FILENO) > 0); + /* Disable the umask logic */ + if (getpid() == 1) + umask(0); + if (getpid() == 1 && detect_container(NULL) <= 0) { /* Running outside of a container as PID 1 */ @@ -1278,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) @@ -1422,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 */ @@ -1438,20 +1443,13 @@ int main(int argc, char *argv[]) { if (serialization) assert_se(fdset_remove(fds, fileno(serialization)) >= 0); - if (arg_running_as == SYSTEMD_SYSTEM) { + if (arg_running_as == SYSTEMD_SYSTEM) /* Become a session leader if we aren't one yet. */ setsid(); - /* Disable the umask logic */ - umask(0); - } - /* 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) @@ -1509,14 +1507,14 @@ int main(int argc, char *argv[]) { log_error("Failed to adjust timer slack: %m"); if (arg_capability_bounding_set_drop) { - r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); if (r < 0) { - log_error("Failed to drop capability bounding set: %s", strerror(-r)); + log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); goto finish; } - r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); + r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); if (r < 0) { - log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r)); + log_error("Failed to drop capability bounding set: %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,