mirror of
https://git.proxmox.com/git/efi-boot-shim
synced 2025-06-11 22:28:52 +00:00
fallback: show a countdown menu before reset
Some machines with the faulty firmware may keep booting the default boot path instead of the boot option we create. To avoid the infinite reset loop, this commit introduce a countdown screen before fallback resets the system, so the user can interrupt the system reset and choose to boot the restored boot option. The "Always continue boot" option creates a BS+RT+NV variable, FB_NO_REBOOT, to make fallback boot the first boot option afterward without asking. The user can revert the behavior by removing the variable. https://github.com/rhboot/shim/issues/128 Signed-off-by: Gary Lin <glin@suse.com> This is a backport from devel of: commit da6284569c4b5d60d14e6187f696f54cccb7b3d2 Author: Gary Lin <glin@suse.com> Date: Wed May 23 18:13:05 2018 +0800 fallback: show a countdown menu before reset Some machines with the faulty firmware may keep booting the default boot path instead of the boot option we create. To avoid the infinite reset loop, this commit introduce a countdown screen before fallback resets the system, so the user can interrupt the system reset and choose to boot the restored boot option. The "Always continue boot" option creates a BS+RT+NV variable, FB_NO_REBOOT, to make fallback boot the first boot option afterward without asking. The user can revert the behavior by removing the variable. https://github.com/rhboot/shim/issues/128 Signed-off-by: Gary Lin <glin@suse.com> Signed-off-by: Peter Jones <pjones@redhat.com>
This commit is contained in:
parent
4e111bf1af
commit
a5db51a52e
81
fallback.c
81
fallback.c
@ -9,6 +9,8 @@
|
||||
|
||||
#include "shim.h"
|
||||
|
||||
#define NO_REBOOT L"FB_NO_REBOOT"
|
||||
|
||||
EFI_LOADED_IMAGE *this_image = NULL;
|
||||
|
||||
int
|
||||
@ -971,6 +973,65 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
static UINT32
|
||||
get_fallback_no_reboot(void)
|
||||
{
|
||||
EFI_STATUS efi_status;
|
||||
UINT32 no_reboot;
|
||||
UINTN size = sizeof(UINT32);
|
||||
|
||||
efi_status = gRT->GetVariable(NO_REBOOT, &SHIM_LOCK_GUID,
|
||||
NULL, &size, &no_reboot);
|
||||
if (!EFI_ERROR(efi_status)) {
|
||||
return no_reboot;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static EFI_STATUS
|
||||
set_fallback_no_reboot(void)
|
||||
{
|
||||
EFI_STATUS efi_status;
|
||||
UINT32 no_reboot = 1;
|
||||
efi_status = gRT->SetVariable(NO_REBOOT, &SHIM_LOCK_GUID,
|
||||
EFI_VARIABLE_NON_VOLATILE
|
||||
| EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||
| EFI_VARIABLE_RUNTIME_ACCESS,
|
||||
sizeof(UINT32), &no_reboot);
|
||||
return efi_status;
|
||||
}
|
||||
|
||||
static int
|
||||
draw_countdown(void)
|
||||
{
|
||||
CHAR16 *title = L"Boot Option Restoration";
|
||||
CHAR16 *message = L"Press any key to stop system reset";
|
||||
int timeout;
|
||||
|
||||
timeout = console_countdown(title, message, 5);
|
||||
|
||||
return timeout;
|
||||
}
|
||||
|
||||
static int
|
||||
get_user_choice(void)
|
||||
{
|
||||
int choice;
|
||||
CHAR16 *title[] = {L"Boot Option Restored", NULL};
|
||||
CHAR16 *menu_strings[] = {
|
||||
L"Reset system",
|
||||
L"Continue boot",
|
||||
L"Always continue boot",
|
||||
NULL
|
||||
};
|
||||
|
||||
do {
|
||||
choice = console_select(title, menu_strings, 0);
|
||||
} while (choice < 0 || choice > 2);
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
extern EFI_STATUS
|
||||
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
|
||||
|
||||
@ -1037,6 +1098,26 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
|
||||
VerbosePrint(L"tpm not present, starting the first image\n");
|
||||
try_start_first_option(image);
|
||||
} else {
|
||||
if (get_fallback_no_reboot() == 1) {
|
||||
VerbosePrint(L"NO_REBOOT is set, starting the first image\n");
|
||||
try_start_first_option(image);
|
||||
}
|
||||
|
||||
int timeout = draw_countdown();
|
||||
if (timeout == 0)
|
||||
goto reset;
|
||||
|
||||
int choice = get_user_choice();
|
||||
if (choice == 0) {
|
||||
goto reset;
|
||||
} else if (choice == 2) {
|
||||
efi_status = set_fallback_no_reboot();
|
||||
if (EFI_ERROR(efi_status))
|
||||
goto reset;
|
||||
}
|
||||
VerbosePrint(L"tpm present, starting the first image\n");
|
||||
try_start_first_option(image);
|
||||
reset:
|
||||
VerbosePrint(L"tpm present, resetting system\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user