Accepting request 612951 from home:gary_lin:branches:devel:openSUSE:Factory
Add shim-bsc1092000-fallback-menu.patch to show a menu before system reset ((bsc#1092000)) OBS-URL: https://build.opensuse.org/request/show/612951 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=141
This commit is contained in:
parent
ddc96299d3
commit
cdcbabe549
194
shim-bsc1092000-fallback-menu.patch
Normal file
194
shim-bsc1092000-fallback-menu.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 22269728415432718e7757842086785d7daf0cc3 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 28 May 2018 10:57:06 +0800
|
||||
Subject: [PATCH] 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
|
||||
https://bugzilla.opensuse.org/show_bug.cgi?id=1092000
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
fallback.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 144 insertions(+)
|
||||
|
||||
diff --git a/fallback.c b/fallback.c
|
||||
index 886e052..1f3eb78 100644
|
||||
--- a/fallback.c
|
||||
+++ b/fallback.c
|
||||
@@ -13,6 +13,9 @@
|
||||
#include "ucs2.h"
|
||||
#include "variables.h"
|
||||
#include "tpm.h"
|
||||
+#include "console.h"
|
||||
+
|
||||
+#define NO_REBOOT L"FB_NO_REBOOT"
|
||||
|
||||
EFI_LOADED_IMAGE *this_image = NULL;
|
||||
|
||||
@@ -953,6 +956,127 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
|
||||
return rc;
|
||||
}
|
||||
|
||||
+static UINT32
|
||||
+get_fallback_no_reboot(void)
|
||||
+{
|
||||
+ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||
+ EFI_STATUS efi_status;
|
||||
+ UINT32 no_reboot;
|
||||
+ UINTN size = sizeof(UINT32);
|
||||
+
|
||||
+ efi_status = uefi_call_wrapper(RT->GetVariable, 5,
|
||||
+ 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_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
||||
+ EFI_STATUS efi_status;
|
||||
+ UINT32 no_reboot = 1;
|
||||
+ efi_status = uefi_call_wrapper(RT->SetVariable, 5,
|
||||
+ 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 void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
|
||||
+{
|
||||
+ if (!SavedMode) {
|
||||
+ Print(L"Invalid parameter: SavedMode\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ CopyMem(SavedMode, ST->ConOut->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
|
||||
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
||||
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||||
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
||||
+}
|
||||
+
|
||||
+static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
|
||||
+{
|
||||
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
|
||||
+ SavedMode->CursorVisible);
|
||||
+ uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
|
||||
+ SavedMode->CursorColumn, SavedMode->CursorRow);
|
||||
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
||||
+ SavedMode->Attribute);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+draw_countdown(void)
|
||||
+{
|
||||
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
||||
+ EFI_INPUT_KEY key;
|
||||
+ EFI_STATUS status;
|
||||
+ UINTN cols, rows;
|
||||
+ CHAR16 *title[2];
|
||||
+ CHAR16 *message = L"Press any key to stop system reset";
|
||||
+ int timeout = 5, wait = 10000000;
|
||||
+
|
||||
+ console_save_and_set_mode (&SavedMode);
|
||||
+
|
||||
+ title[0] = L"Boot Option Restoration";
|
||||
+ title[1] = NULL;
|
||||
+
|
||||
+ console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1);
|
||||
+
|
||||
+ uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
|
||||
+ ST->ConOut->Mode->Mode, &cols, &rows);
|
||||
+
|
||||
+ PrintAt((cols - StrLen(message))/2, rows/2, message);
|
||||
+ while (1) {
|
||||
+ if (timeout > 1)
|
||||
+ PrintAt(2, rows - 3, L"Booting in %d seconds ", timeout);
|
||||
+ else if (timeout)
|
||||
+ PrintAt(2, rows - 3, L"Booting in %d second ", timeout);
|
||||
+
|
||||
+ status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait);
|
||||
+
|
||||
+ if (status != EFI_TIMEOUT) {
|
||||
+ /* Clear the key in the queue */
|
||||
+ uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
|
||||
+ ST->ConIn, &key);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ timeout--;
|
||||
+ if (!timeout)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ console_restore_mode(&SavedMode);
|
||||
+
|
||||
+ 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);
|
||||
|
||||
@@ -1014,6 +1138,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) {
|
||||
+ rc = set_fallback_no_reboot();
|
||||
+ if (EFI_ERROR(rc))
|
||||
+ goto reset;
|
||||
+ }
|
||||
+ VerbosePrint(L"tpm present, starting the first image\n");
|
||||
+ try_start_first_option(image);
|
||||
+reset:
|
||||
VerbosePrint(L"tpm present, resetting system\n");
|
||||
}
|
||||
|
||||
--
|
||||
2.16.3
|
||||
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Tue May 29 06:41:59 UTC 2018 - glin@suse.com
|
||||
|
||||
- Add shim-bsc1092000-fallback-menu.patch to show a menu before
|
||||
system reset ((bsc#1092000))
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Apr 10 03:45:39 UTC 2018 - glin@suse.com
|
||||
|
||||
|
@ -56,6 +56,8 @@ Patch4: shim-remove-cryptpem.patch
|
||||
Patch5: shim-httpboot-amend-device-path.patch
|
||||
# PATCH-FIX-UPSTREAM shim-bsc1088585-handle-mok-allocations-better.patch bsc#1088585 glin@suse.com -- Handle the mok parameter allocations better
|
||||
Patch6: shim-bsc1088585-handle-mok-allocations-better.patch
|
||||
# PATCH-FIX-UPSTREAM shim-bsc1092000-fallback-menu.patch bsc#1092000 glin@suse.com -- Show a menu before reset
|
||||
Patch7: shim-bsc1092000-fallback-menu.patch
|
||||
# PATCH-FIX-OPENSUSE shim-change-debug-file-path.patch glin@suse.com -- Change the default debug file path
|
||||
Patch50: shim-change-debug-file-path.patch
|
||||
# PATCH-FIX-OPENSUSE shim-opensuse-cert-prompt.patch glin@suse.com -- Show the prompt to ask whether the user trusts openSUSE certificate or not
|
||||
@ -106,6 +108,7 @@ The source code of UEFI shim loader
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch50 -p1
|
||||
%if 0%{?is_opensuse} == 1
|
||||
%patch100 -p1
|
||||
|
Loading…
x
Reference in New Issue
Block a user