X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmain.c;h=1b1741a64513ff1b7f7e446d86824bf61ee69d09;hb=ca76186598c56da9f08b7eb55b6915d9e2344570;hp=d161968bb39125c690f576af5c99dd69c7dbb6c6;hpb=3f6da75bcef8293382ce2674322f6c50428eb39f;p=elogind.git
diff --git a/src/core/main.c b/src/core/main.c
index d161968bb..1b1741a64 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,
@@ -93,6 +98,8 @@ 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;
@@ -105,7 +112,7 @@ static FILE* serialization = NULL;
static void nop_handler(int sig) {
}
-_noreturn_ static void crash(int sig) {
+noreturn static void crash(int sig) {
if (getpid() != 1)
/* Pass this on immediately, if this is not PID 1 */
@@ -124,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 = {};
@@ -159,7 +166,7 @@ _noreturn_ static void crash(int sig) {
else if (status.si_code != CLD_DUMPED)
log_error("Caught <%s>, core dump failed.", signal_to_string(sig));
else
- log_error("Caught <%s>, dumped core as pid %lu.", signal_to_string(sig), (unsigned long) pid);
+ log_error("Caught <%s>, dumped core as pid "PID_FMT".", signal_to_string(sig), pid);
}
}
@@ -190,7 +197,7 @@ _noreturn_ static void crash(int sig) {
_exit(1);
}
- log_info("Successfully spawned crash shell as pid %lu.", (unsigned long) pid);
+ log_info("Successfully spawned crash shell as pid "PID_FMT".", pid);
}
log_info("Freezing execution.");
@@ -410,7 +417,7 @@ static int parse_proc_cmdline_word(const char *word) {
* will block with every log message for for 60 seconds,
* before they give up. */
log_set_max_level(LOG_DEBUG);
- log_set_target(LOG_TARGET_KMSG);
+ log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG);
} else if (!in_initrd()) {
unsigned i;
@@ -428,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, \
@@ -454,11 +462,11 @@ DEFINE_SETTER(config_parse_target, log_set_target_from_string, "target")
DEFINE_SETTER(config_parse_color, log_show_color_from_string, "color" )
DEFINE_SETTER(config_parse_location, log_show_location_from_string, "location")
-
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,
@@ -531,6 +539,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,
@@ -590,17 +599,12 @@ static int config_parse_join_controllers(const char *unit,
for (a = arg_join_controllers; *a; a++) {
if (strv_overlap(*a, l)) {
- char **c;
-
- c = strv_merge(*a, l);
- if (!c) {
+ if (strv_extend_strv(&l, *a) < 0) {
strv_free(l);
strv_free_free(t);
return log_oom();
}
- strv_free(l);
- l = c;
} else {
char **c;
@@ -642,6 +646,8 @@ static int parse_config_file(void) {
{ "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 },
@@ -1035,7 +1041,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) {
@@ -1197,6 +1203,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;
@@ -1261,12 +1269,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)
@@ -1312,6 +1322,7 @@ int main(int argc, char *argv[]) {
/* Running inside a container, as PID 1 */
arg_running_as = SYSTEMD_SYSTEM;
log_set_target(LOG_TARGET_CONSOLE);
+ log_close_console(); /* force reopen of /dev/console */
log_open();
/* For the later on, see above... */
@@ -1383,12 +1394,6 @@ 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;
- }
-
if (arg_running_as == SYSTEMD_SYSTEM &&
arg_action == ACTION_RUN &&
running_in_chroot() > 0) {
@@ -1411,6 +1416,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 */
@@ -1434,9 +1445,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)
@@ -1475,7 +1483,8 @@ int main(int argc, char *argv[]) {
status_welcome();
#ifdef HAVE_KMOD
- kmod_setup();
+ if (detect_container(NULL) <= 0)
+ kmod_setup();
#endif
hostname_setup();
machine_id_setup();
@@ -1518,7 +1527,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;
@@ -1530,16 +1539,20 @@ int main(int argc, char *argv[]) {
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);
@@ -1563,19 +1576,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.");
@@ -1585,8 +1595,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));
@@ -1606,18 +1615,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;
}
@@ -1713,7 +1719,6 @@ finish:
free(arg_default_unit);
free_join_controllers();
- dbus_shutdown();
label_finish();
if (reexecute) {
@@ -1736,7 +1741,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);
@@ -1828,16 +1833,26 @@ 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,
shutdown_verb,
NULL
};
- char **env_block;
+ _cleanup_strv_free_ char **env_block = NULL;
+ env_block = strv_copy(environ);
if (arm_reboot_watchdog && arg_shutdown_watchdog > 0) {
- char e[32];
+ char *e;
/* If we reboot let's set the shutdown
* watchdog and tell the shutdown binary to
@@ -1845,15 +1860,11 @@ finish:
watchdog_set_timeout(&arg_shutdown_watchdog);
watchdog_close(false);
- /* Tell the binary how often to ping */
- snprintf(e, sizeof(e), "WATCHDOG_USEC=%llu", (unsigned long long) arg_shutdown_watchdog);
- char_array_0(e);
-
- env_block = strv_append(environ, e);
- } else {
- env_block = strv_copy(environ);
+ /* Tell the binary how often to ping, ignore failure */
+ if (asprintf(&e, "WATCHDOG_USEC="USEC_FMT, arg_shutdown_watchdog) > 0)
+ strv_push(&env_block, e);
+ } else
watchdog_close(true);
- }
/* Avoid the creation of new processes forked by the
* kernel; at this point, we will not listen to the
@@ -1862,7 +1873,6 @@ finish:
cg_uninstall_release_agent(SYSTEMD_CGROUP_CONTROLLER);
execve(SYSTEMD_SHUTDOWN_BINARY_PATH, (char **) command_line, env_block);
- free(env_block);
log_error("Failed to execute shutdown binary, freezing: %m");
}