Merge pull request #24054 from keszybz/initrd-no-reload

Don't do daemon-reload in the initrd
This commit is contained in:
Frantisek Sumsal
2022-08-18 13:15:14 +00:00
committed by GitHub
15 changed files with 277 additions and 157 deletions
+5
View File
@@ -5,6 +5,11 @@
#define DEFAULT_RESTART_USEC (100*USEC_PER_MSEC)
#define DEFAULT_CONFIRM_USEC (30*USEC_PER_SEC)
/* We use an extra-long timeout for the reload. This is because a reload or reexec means generators are rerun
* which are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can
* have their timeout, and for everything else there's the same time budget in place. */
#define DAEMON_RELOAD_TIMEOUT_SEC (DEFAULT_TIMEOUT_USEC * 2)
#define DEFAULT_START_LIMIT_INTERVAL (10*USEC_PER_SEC)
#define DEFAULT_START_LIMIT_BURST 5
+5 -2
View File
@@ -1838,8 +1838,11 @@ static int verb_status(int argc, char *argv[], void *userdata) {
bool have_bootloader_esp_uuid = efi_loader_get_device_part_uuid(&bootloader_esp_uuid) >= 0;
print_yes_no_line(false, have_bootloader_esp_uuid, "Boot loader sets ESP information");
if (have_bootloader_esp_uuid && !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
printf("WARNING: The boot loader reports a different ESP UUID than detected!\n");
if (have_bootloader_esp_uuid && !sd_id128_is_null(esp_uuid) &&
!sd_id128_equal(esp_uuid, bootloader_esp_uuid))
printf("WARNING: The boot loader reports a different ESP UUID than detected ("SD_ID128_UUID_FORMAT_STR" vs. "SD_ID128_UUID_FORMAT_STR")!\n",
SD_ID128_FORMAT_VAL(bootloader_esp_uuid),
SD_ID128_FORMAT_VAL(esp_uuid));
if (stub) {
printf(" Stub: %s\n", stub);
+1 -1
View File
@@ -52,7 +52,7 @@ static void start_target(const char *target, const char *mode) {
return;
}
log_info("Running request %s/start/%s", target, mode);
log_info("Requesting %s/start/%s", target, mode);
/* Start this unit only if we can replace basic.target with it */
r = sd_bus_call_method(bus,
+110 -8
View File
@@ -5,6 +5,8 @@
#include <unistd.h>
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-locator.h"
#include "chase-symlinks.h"
#include "fd-util.h"
#include "fileio.h"
@@ -20,6 +22,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
#include "process-util.h"
#include "special.h"
#include "specifier.h"
#include "stat-util.h"
@@ -39,6 +42,7 @@ typedef enum MountPointFlags {
MOUNT_RW_ONLY = 1 << 5,
} MountPointFlags;
static bool arg_sysroot_check = false;
static const char *arg_dest = NULL;
static const char *arg_dest_late = NULL;
static bool arg_fstab_enabled = true;
@@ -119,6 +123,11 @@ static int add_swap(
return 0;
}
if (arg_sysroot_check) {
log_info("%s should be enabled in the initrd, will request daemon-reload.", what);
return true;
}
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@@ -175,7 +184,7 @@ static int add_swap(
return r;
}
return 0;
return true;
}
static bool mount_is_network(struct mntent *me) {
@@ -378,6 +387,11 @@ static int add_mount(
mount_point_ignore(where))
return 0;
if (arg_sysroot_check) {
log_info("%s should be mounted in the initrd, will request daemon-reload.", where);
return true;
}
r = fstab_filter_options(opts, "x-systemd.wanted-by\0", NULL, NULL, &wanted_by, NULL);
if (r < 0)
return r;
@@ -567,7 +581,52 @@ static int add_mount(
return r;
}
return 0;
return true;
}
static int do_daemon_reload(void) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r, k;
log_debug("Calling org.freedesktop.systemd1.Manager.Reload()...");
r = bus_connect_system_systemd(&bus);
if (r < 0)
return log_error_errno(r, "Failed to get D-Bus connection: %m");
r = bus_message_new_method_call(bus, &m, bus_systemd_mgr, "Reload");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
if (r < 0)
return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
/* We need to requeue the two targets so that any new units which previously were not part of the
* targets, and which we now added, will be started. */
r = 0;
FOREACH_STRING(unit, SPECIAL_INITRD_FS_TARGET, SPECIAL_SWAP_TARGET) {
log_info("Requesting %s/start/replace...", unit);
k = sd_bus_call_method(bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit",
&error,
NULL,
"ss", unit, "replace");
if (k < 0) {
log_error_errno(k, "Failed to (re)start %s: %s", unit, bus_error_message(&error, r));
if (r == 0)
r = k;
}
}
return r;
}
static const char* sysroot_fstab_path(void) {
@@ -582,8 +641,10 @@ static int parse_fstab(bool initrd) {
if (initrd)
fstab = sysroot_fstab_path();
else
else {
fstab = fstab_path();
assert(!arg_sysroot_check);
}
log_debug("Parsing %s...", fstab);
@@ -700,6 +761,8 @@ static int parse_fstab(bool initrd) {
target_unit);
}
if (arg_sysroot_check && k > 0)
return true; /* We found a mount or swap that would be started… */
if (r >= 0 && k < 0)
r = k;
}
@@ -1126,12 +1189,14 @@ static int determine_usr(void) {
return determine_device(&arg_usr_what, arg_usr_hash, "usr");
}
static int run(const char *dest, const char *dest_early, const char *dest_late) {
/* If arg_sysroot_check is false, run as generator in the usual fashion.
* If it is true, check /sysroot/etc/fstab for any units that we'd want to mount
* in the initrd, and call daemon-reload. We will get reinvoked as a generator,
* with /sysroot/etc/fstab available, and then we can write additional units based
* on that file. */
static int run_generator(void) {
int r, r2 = 0, r3 = 0;
assert_se(arg_dest = dest);
assert_se(arg_dest_late = dest_late);
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");
@@ -1139,6 +1204,15 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
(void) determine_root();
(void) determine_usr();
if (arg_sysroot_check) {
r = parse_fstab(true);
if (r == 0)
log_debug("Nothing interesting found, not doing daemon-reload.");
if (r > 0)
r = do_daemon_reload();
return r;
}
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
r = add_sysroot_mount();
@@ -1164,4 +1238,32 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
return r < 0 ? r : r2 < 0 ? r2 : r3;
}
DEFINE_MAIN_GENERATOR_FUNCTION(run);
static int run(int argc, char **argv) {
arg_sysroot_check = invoked_as(argv, "systemd-sysroot-fstab-check");
if (arg_sysroot_check) {
/* Run as in systemd-sysroot-fstab-check mode */
log_setup();
if (strv_length(argv) > 1)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program takes no arguments.");
if (!in_initrd())
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program is only useful in the initrd.");
} else {
/* Run in generator mode */
log_setup_generator();
if (!IN_SET(strv_length(argv), 2, 4))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program takes one or three arguments.");
arg_dest = ASSERT_PTR(argv[1]);
arg_dest_late = ASSERT_PTR(argv[argc > 3 ? 3 : 1]);
}
return run_generator();
}
DEFINE_MAIN_FUNCTION(run);
+2 -1
View File
@@ -53,7 +53,8 @@ static int open_parent_block_device(dev_t devnum, int *ret_fd) {
r = sd_device_new_from_devnum(&d, 'b', devnum);
if (r < 0)
return log_debug_errno(r, "Failed to open device: %m");
return log_debug_errno(r, "Failed to create device object for block device "DEVNUM_FORMAT_STR": %m",
DEVNUM_FORMAT_VAL(devnum));
if (sd_device_get_devname(d, &name) < 0) {
r = sd_device_get_syspath(d, &name);
+1 -1
View File
@@ -103,7 +103,7 @@ static int change_runlevel(Server *s, int runlevel) {
else
mode = "replace-irreversibly";
log_debug("Running request %s/start/%s", target, mode);
log_debug("Requesting %s/start/%s", target, mode);
r = sd_bus_call_method(
s->bus,
+1 -1
View File
@@ -249,7 +249,7 @@ static int maybe_reload(sd_bus **bus) {
return bus_log_create_error(r);
/* Reloading the daemon may take long, hence set a longer timeout here */
r = sd_bus_call(*bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
r = sd_bus_call(*bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
if (r < 0)
return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
+2 -5
View File
@@ -33,11 +33,8 @@ static int reload_manager(sd_bus *bus) {
if (r < 0)
return bus_log_create_error(r);
/* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
* are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
* their timeout, and for everything else there's the same time budget in place. */
r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
/* Reloading the daemon may take long, hence set a longer timeout here */
r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
if (r < 0)
return log_error_errno(r, "Failed to reload daemon: %s", bus_error_message(&error, r));
+2 -6
View File
@@ -37,12 +37,8 @@ int daemon_reload(enum action action, bool graceful) {
if (r < 0)
return bus_log_create_error(r);
/* Note we use an extra-long timeout here. This is because a reload or reexec means generators are
* rerun which are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the
* generators can have their timeout, and for everything else there's the same time budget in
* place. */
r = sd_bus_call(bus, m, DEFAULT_TIMEOUT_USEC * 2, &error, NULL);
/* Reloading the daemon may take long, hence set a longer timeout here */
r = sd_bus_call(bus, m, DAEMON_RELOAD_TIMEOUT_SEC, &error, NULL);
/* On reexecution, we expect a disconnect, not a reply */
if (IN_SET(r, -ETIMEDOUT, -ECONNRESET) && action == ACTION_REEXEC)