diff --git a/man/bootctl.xml b/man/bootctl.xml index fbd6574418..c038c4686d 100644 --- a/man/bootctl.xml +++ b/man/bootctl.xml @@ -183,6 +183,12 @@ Do not touch the firmware's boot loader list stored in EFI variables. + + + Ignore failure when the EFI System Partition cannot be found, or when EFI variables + cannot be written. Currently only applies to random seed operations. + + diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index f8845369ec..a90502b4c3 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -51,6 +51,7 @@ static bool arg_print_esp_path = false; static bool arg_print_dollar_boot_path = false; static bool arg_touch_variables = true; static PagerFlags arg_pager_flags = 0; +static bool arg_graceful = false; STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep); STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep); @@ -1055,6 +1056,8 @@ static int help(int argc, char *argv[], void *userdata) { " -x --print-boot-path Print path to the $BOOT partition\n" " --no-variables Don't touch EFI variables\n" " --no-pager Do not pipe output into a pager\n" + " --graceful Don't fail when the ESP cannot be found or EFI\n" + " variables cannot be written\n" "\nSee the %s for details.\n" , program_invocation_short_name , ansi_highlight() @@ -1071,6 +1074,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION, ARG_NO_VARIABLES, ARG_NO_PAGER, + ARG_GRACEFUL, }; static const struct option options[] = { @@ -1084,6 +1088,7 @@ static int parse_argv(int argc, char *argv[]) { { "print-boot-path", no_argument, NULL, 'x' }, { "no-variables", no_argument, NULL, ARG_NO_VARIABLES }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, + { "graceful", no_argument, NULL, ARG_GRACEFUL }, {} }; @@ -1136,6 +1141,10 @@ static int parse_argv(int argc, char *argv[]) { arg_pager_flags |= PAGER_DISABLE; break; + case ARG_GRACEFUL: + arg_graceful = true; + break; + case '?': return -EINVAL; @@ -1458,11 +1467,18 @@ static int install_random_seed(const char *esp) { * state. */ RUN_WITH_UMASK(0077) { r = efi_set_variable(EFI_VENDOR_LOADER, "LoaderSystemToken", buffer, sz); - if (r < 0) - return log_error_errno(r, "Failed to set LoaderSystemToken EFI variable: %m"); + if (r < 0) { + if (!arg_graceful) + return log_error_errno(r, "Failed to write 'LoaderSystemToken' EFI variable: %m"); + + if (r == -EINVAL) + log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable (firmware problem?), ignoring: %m"); + else + log_warning_errno(r, "Unable to write 'LoaderSystemToken' EFI variable, ignoring: %m"); + } else + log_info("Successfully initialized system token in EFI variable with %zu bytes.", sz); } - log_info("Successfully initialized system token in EFI variable with %zu bytes.", sz); return 0; } @@ -1704,7 +1720,15 @@ static int verb_set_default(int argc, char *argv[], void *userdata) { static int verb_random_seed(int argc, char *argv[], void *userdata) { int r; - r = acquire_esp(false, NULL, NULL, NULL, NULL); + r = find_esp_and_warn(arg_esp_path, false, &arg_esp_path, NULL, NULL, NULL, NULL); + if (r == -ENOKEY) { + /* find_esp_and_warn() doesn't warn about ENOKEY, so let's do that on our own */ + if (!arg_graceful) + return log_error_errno(r, "Unable to find ESP."); + + log_notice("No ESP found, not initializing random seed."); + return 0; + } if (r < 0) return r; diff --git a/units/systemd-boot-system-token.service.in b/units/systemd-boot-system-token.service.in index 5bc29b0cb7..e9b742c5c7 100644 --- a/units/systemd-boot-system-token.service.in +++ b/units/systemd-boot-system-token.service.in @@ -31,4 +31,4 @@ ConditionPathExists=|!/sys/firmware/efi/efivars/LoaderRandomSeed-4a67b082-0a4c-4 [Service] Type=oneshot RemainAfterExit=yes -ExecStart=@bindir@/bootctl random-seed +ExecStart=@bindir@/bootctl random-seed --graceful