bless-boot: skip gracefully on kexec
If KExecsCount > 0 then do not attempt to mark a UKI, as the stub (and also any addon and the bootloader) will not have been exercised, so there's no guaranteed a full reboot with the same image will actually work. Fixes https://github.com/systemd/systemd/issues/43738
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sd-json.h"
|
||||
#include "sd-varlink.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "build.h"
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "sync-util.h"
|
||||
#include "varlink-util.h"
|
||||
#include "verbs.h"
|
||||
#include "virt.h"
|
||||
|
||||
@@ -443,6 +445,8 @@ VERB_FULL(verb_set, "indeterminate", NULL, VERB_ANY, 1, 0, STATUS_INDETERMINATE,
|
||||
"Undo any marking as good or bad");
|
||||
static int verb_set(int argc, char *argv[], uintptr_t data, void *userdata) {
|
||||
_cleanup_free_ char *path = NULL, *prefix = NULL, *suffix = NULL, *good = NULL, *bad = NULL;
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *link = NULL;
|
||||
sd_json_variant *reply = NULL;
|
||||
const char *target = NULL, *source1 = NULL, *source2 = NULL; /* avoid false maybe-uninitialized warning */
|
||||
uint64_t left, done;
|
||||
Status status = data;
|
||||
@@ -454,6 +458,35 @@ static int verb_set(int argc, char *argv[], uintptr_t data, void *userdata) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* kexec doesn't go through the EFI loaders, so we shouldn't try to mark an image as good/bad.
|
||||
* E.g.: booting the kernel+initrd might work, but the EFI stub might not, and we wouldn't notice */
|
||||
r = sd_varlink_connect_address(&link, "/run/systemd/io.systemd.Manager");
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to service manager: %m");
|
||||
|
||||
r = varlink_call_and_log(link, "io.systemd.Manager.Describe", /* parameters= */ NULL, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
static const sd_json_dispatch_field dispatch_table[] = {
|
||||
{ "KExecCount", SD_JSON_VARIANT_UNSIGNED, sd_json_dispatch_uint64, 0, 0 },
|
||||
{},
|
||||
};
|
||||
uint64_t kexec_count = 0;
|
||||
|
||||
r = sd_json_dispatch(
|
||||
sd_json_variant_by_key(reply, "runtime"),
|
||||
dispatch_table,
|
||||
SD_JSON_LOG|SD_JSON_ALLOW_EXTENSIONS,
|
||||
&kexec_count);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (kexec_count > 0) {
|
||||
log_info("System was booted via kexec, skipping boot entry marking.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = acquire_boot_count_path(&path, &prefix, &left, &done, &suffix);
|
||||
if (r == -EUNATCH) /* acquire_boot_count_path() won't log on its own for this specific error */
|
||||
return log_error_errno(r, "Not booted with boot counting in effect.");
|
||||
|
||||
Reference in New Issue
Block a user