From 62a05cdcd46717732b142d43bb77fb8c79e5433c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 16 Apr 2019 18:34:31 +0200 Subject: [PATCH] Some grub2-emu, HTTP boot and fallback fixes Signed-off-by: Javier Martinez Canillas --- ...-boot-success-reset-from-menu-auto-h.patch | 152 ++++++++++++++++++ ...HTTP-boot-strncmp-returns-0-on-equal.patch | 22 +++ ...ix-systemctl-kexec-exit-status-check.patch | 37 +++++ ...b-emu-linux-loader-messages-as-debug.patch | 34 ++++ ...t-boot-commands-will-only-return-on-.patch | 79 +++++++++ grub.patches | 5 + grub2.spec | 11 +- 7 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 0293-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch create mode 100644 0294-HTTP-boot-strncmp-returns-0-on-equal.patch create mode 100644 0295-Fix-systemctl-kexec-exit-status-check.patch create mode 100644 0296-Print-grub-emu-linux-loader-messages-as-debug.patch create mode 100644 0297-Don-t-assume-that-boot-commands-will-only-return-on-.patch diff --git a/0293-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch b/0293-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch new file mode 100644 index 00000000..691380d6 --- /dev/null +++ b/0293-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch @@ -0,0 +1,152 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Christian Glombek +Date: Tue, 2 Apr 2019 16:22:21 +0200 +Subject: [PATCH] grub.d: Split out boot success reset from menu auto hide + script + +Also rename fallback and menu auto hide script to be executed +before and after boot success reset script. +In menu auto hide script, rename last_boot_ok var to menu_hide_ok +--- + Makefile.util.def | 8 +++---- + ...allback_counting.in => 08_fallback_counting.in} | 14 ++++++------ + util/grub.d/10_reset_boot_success.in | 25 ++++++++++++++++++++++ + .../{01_menu_auto_hide.in => 12_menu_auto_hide.in} | 23 +++++--------------- + 4 files changed, 42 insertions(+), 28 deletions(-) + rename util/grub.d/{01_fallback_counting.in => 08_fallback_counting.in} (65%) + create mode 100644 util/grub.d/10_reset_boot_success.in + rename util/grub.d/{01_menu_auto_hide.in => 12_menu_auto_hide.in} (58%) + +diff --git a/Makefile.util.def b/Makefile.util.def +index eca3dfa753f..cae6002d2e3 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -449,14 +449,14 @@ script = { + }; + + script = { +- name = '01_fallback_counting'; +- common = util/grub.d/01_fallback_counting.in; ++ name = '08_fallback_counting'; ++ common = util/grub.d/08_fallback_counting.in; + installdir = grubconf; + }; + + script = { +- name = '01_menu_auto_hide'; +- common = util/grub.d/01_menu_auto_hide.in; ++ name = '12_menu_auto_hide'; ++ common = util/grub.d/12_menu_auto_hide.in; + installdir = grubconf; + }; + +diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/08_fallback_counting.in +similarity index 65% +rename from util/grub.d/01_fallback_counting.in +rename to util/grub.d/08_fallback_counting.in +index be0e770ea82..2e2c3ff7d31 100644 +--- a/util/grub.d/01_fallback_counting.in ++++ b/util/grub.d/08_fallback_counting.in +@@ -1,15 +1,17 @@ + #! /bin/sh -e +- +-# Boot Counting ++# Fallback Countdown ++# ++# This snippet depends on 10_reset_boot_success and needs to be kept in sync. ++# + # The boot_counter env var can be used to count down boot attempts after an +-# OSTree upgrade and choose the rollback deployment when 0 is reached. Both +-# boot_counter and boot_success need to be (re-)set from userspace. ++# OSTree upgrade and choose the rollback deployment when 0 is reached. ++# Both boot_counter=X and boot_success=1 need to be set from userspace. + cat << EOF + insmod increment + # Check if boot_counter exists and boot_success=0 to activate this behaviour. + if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then +- # if countdown has ended, choose to boot rollback deployment (default=1 on +- # OSTree-based systems) ++ # if countdown has ended, choose to boot rollback deployment, ++ # i.e. default=1 on OSTree-based systems. + if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then + set default=1 + set boot_counter=-1 +diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in +new file mode 100644 +index 00000000000..6c88d933dde +--- /dev/null ++++ b/util/grub.d/10_reset_boot_success.in +@@ -0,0 +1,25 @@ ++#! /bin/sh -e ++# Reset Boot Success ++# ++# The 08_fallback_counting and 12_menu_auto_hide snippets rely on this one ++# and need to be kept in sync. ++# ++# The boot_success var needs to be set to 1 from userspace to mark a boot successful. ++cat << EOF ++insmod increment ++# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry ++if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then ++ set menu_hide_ok=1 ++else ++ set menu_hide_ok=0 ++fi ++# Reset boot_indeterminate after a successful boot, increment otherwise ++if [ "\${boot_success}" = "1" ] ; then ++ set boot_indeterminate=0 ++else ++ increment boot_indeterminate ++fi ++# Reset boot_success for current boot ++set boot_success=0 ++save_env boot_success boot_indeterminate ++EOF +diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/12_menu_auto_hide.in +similarity index 58% +rename from util/grub.d/01_menu_auto_hide.in +rename to util/grub.d/12_menu_auto_hide.in +index ad175870a54..6a7c0fa0d43 100644 +--- a/util/grub.d/01_menu_auto_hide.in ++++ b/util/grub.d/12_menu_auto_hide.in +@@ -1,5 +1,8 @@ + #! /bin/sh +- ++# Menu Auto Hide ++# ++# This snippet depends on 10_reset_boot_success and needs to be kept in sync. ++# + # Disable / skip generating menu-auto-hide config parts on serial terminals + for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do + case "$x" in +@@ -10,29 +13,13 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do + done + + cat << EOF +-if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then +- set last_boot_ok=1 +-else +- set last_boot_ok=0 +-fi +- +-# Reset boot_indeterminate after a successful boot +-if [ "\${boot_success}" = "1" ] ; then +- set boot_indeterminate=0 +-# Avoid boot_indeterminate causing the menu to be hidden more then once +-elif [ "\${boot_indeterminate}" = "1" ]; then +- set boot_indeterminate=2 +-fi +-set boot_success=0 +-save_env boot_success boot_indeterminate +- + if [ x\$feature_timeout_style = xy ] ; then + if [ "\${menu_show_once}" ]; then + unset menu_show_once + save_env menu_show_once + set timeout_style=menu + set timeout=60 +- elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then ++ elif [ "\${menu_auto_hide}" -a "\${menu_hide_ok}" = "1" ]; then + set orig_timeout_style=\${timeout_style} + set orig_timeout=\${timeout} + if [ "\${fastboot}" = "1" ]; then diff --git a/0294-HTTP-boot-strncmp-returns-0-on-equal.patch b/0294-HTTP-boot-strncmp-returns-0-on-equal.patch new file mode 100644 index 00000000..09cbcb30 --- /dev/null +++ b/0294-HTTP-boot-strncmp-returns-0-on-equal.patch @@ -0,0 +1,22 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Stephen Benjamin +Date: Fri, 12 Apr 2019 10:43:13 -0400 +Subject: [PATCH] HTTP boot: strncmp returns 0 on equal + +--- + grub-core/net/efi/http.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c +index 2a9624dacc4..484e0c68cee 100644 +--- a/grub-core/net/efi/http.c ++++ b/grub-core/net/efi/http.c +@@ -19,7 +19,7 @@ http_configure (struct grub_efi_net_device *dev, int prefer_ip6) + const char *rest, *http_server, *http_path = NULL; + + http_server = grub_env_get ("root"); +- https = grub_strncmp (http_server, "https", 5) ? 1 : 0; ++ https = (grub_strncmp (http_server, "https", 5) == 0) ? 1 : 0; + + /* extract http server + port */ + if (http_server) diff --git a/0295-Fix-systemctl-kexec-exit-status-check.patch b/0295-Fix-systemctl-kexec-exit-status-check.patch new file mode 100644 index 00000000..74ecedcc --- /dev/null +++ b/0295-Fix-systemctl-kexec-exit-status-check.patch @@ -0,0 +1,37 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 9 Apr 2019 12:30:38 +0200 +Subject: [PATCH] Fix systemctl kexec exit status check + +There's always an error printed even when the systemctl kexec command does +succeed. That's because systemctl executes it asynchronously, but the emu +loader seems to expect it to be synchronous and that should never return. + +Also, it's wrong to test if kexecute == 1 since we already know that's the +case or otherwise the function wouldn't had called grub_fatal() earlier. + +Finally, systemctl kexec failing shouldn't be a fatal error since the emu +loader fallbacks to executing the kexec command in case of a failure. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/loader/emu/linux.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c +index fda9e00d24c..5b85b225eed 100644 +--- a/grub-core/loader/emu/linux.c ++++ b/grub-core/loader/emu/linux.c +@@ -71,8 +71,10 @@ grub_linux_boot (void) + (kexecute==1) ? "do-or-die" : "just-in-case"); + rc = grub_util_exec (systemctl); + +- if (kexecute == 1) +- grub_fatal (N_("Error trying to perform 'systemctl kexec'")); ++ if (rc == GRUB_ERR_NONE) ++ return rc; ++ ++ grub_error (rc, N_("Error trying to perform 'systemctl kexec'")); + + /* need to check read-only root before resetting hard!? */ + grub_printf("Performing 'kexec -e'"); diff --git a/0296-Print-grub-emu-linux-loader-messages-as-debug.patch b/0296-Print-grub-emu-linux-loader-messages-as-debug.patch new file mode 100644 index 00000000..a49ec44c --- /dev/null +++ b/0296-Print-grub-emu-linux-loader-messages-as-debug.patch @@ -0,0 +1,34 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 9 Apr 2019 12:42:37 +0200 +Subject: [PATCH] Print grub-emu linux loader messages as debug + +They just polute the output and should better be debug messages instead. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/loader/emu/linux.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c +index 5b85b225eed..22ab6af1727 100644 +--- a/grub-core/loader/emu/linux.c ++++ b/grub-core/loader/emu/linux.c +@@ -50,7 +50,7 @@ grub_linux_boot (void) + initrd_param = grub_xasprintf("%s", ""); + } + +- grub_printf("%serforming 'kexec -l %s %s %s'\n", ++ grub_dprintf ("linux", "%serforming 'kexec -l %s %s %s'\n", + (kexecute) ? "P" : "Not p", + kernel_path, initrd_param, boot_cmdline); + +@@ -67,7 +67,7 @@ grub_linux_boot (void) + if (kexecute < 1) + grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart.")); + +- grub_printf("Performing 'systemctl kexec' (%s) ", ++ grub_dprintf ("linux", "Performing 'systemctl kexec' (%s) ", + (kexecute==1) ? "do-or-die" : "just-in-case"); + rc = grub_util_exec (systemctl); + diff --git a/0297-Don-t-assume-that-boot-commands-will-only-return-on-.patch b/0297-Don-t-assume-that-boot-commands-will-only-return-on-.patch new file mode 100644 index 00000000..1d071bd6 --- /dev/null +++ b/0297-Don-t-assume-that-boot-commands-will-only-return-on-.patch @@ -0,0 +1,79 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Tue, 9 Apr 2019 13:12:40 +0200 +Subject: [PATCH] Don't assume that boot commands will only return on fail + +While it's true that for most loaders the boot command never returns, it +may be the case that it does. For example the GRUB emulator boot command +calls to systemctl kexec which in turn does an asynchonous call to kexec. + +So in this case GRUB will wrongly assume that the boot command fails and +print a "Failed to boot both default and fallback entries" even when the +kexec call later succeeds. + +Signed-off-by: Javier Martinez Canillas +--- + grub-core/normal/menu.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index d087153f276..050d0adf6ce 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -286,7 +286,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) + } + + /* Run a menu entry. */ +-static void ++static grub_err_t + grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + { + grub_err_t err = GRUB_ERR_NONE; +@@ -386,7 +386,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + + if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) + /* Implicit execution of boot, only if something is loaded. */ +- grub_command_execute ("boot", 0, 0); ++ err = grub_command_execute ("boot", 0, 0); + + if (errs_before != grub_err_printed_errors) + grub_wait_after_message (); +@@ -409,6 +409,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) + else + grub_env_unset ("default"); + grub_env_unset ("timeout"); ++ ++ return err; + } + + /* Execute ENTRY from the menu MENU, falling back to entries specified +@@ -423,10 +425,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu, + void *callback_data) + { + int fallback_entry; ++ grub_err_t err; + + callback->notify_booting (entry, callback_data); + +- grub_menu_execute_entry (entry, 1); ++ err = grub_menu_execute_entry (entry, 1); ++ if (err == GRUB_ERR_NONE) ++ return; + + /* Deal with fallback entries. */ + while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) +@@ -437,11 +442,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu, + + entry = grub_menu_get_entry (menu, fallback_entry); + callback->notify_fallback (entry, callback_data); +- grub_menu_execute_entry (entry, 1); +- /* If the function call to execute the entry returns at all, then this is +- taken to indicate a boot failure. For menu entries that do something +- other than actually boot an operating system, this could assume +- incorrectly that something failed. */ ++ err = grub_menu_execute_entry (entry, 1); ++ if (err == GRUB_ERR_NONE) ++ return; + } + + if (!autobooted) diff --git a/grub.patches b/grub.patches index e6a601bf..3ecf45f8 100644 --- a/grub.patches +++ b/grub.patches @@ -290,3 +290,8 @@ Patch0289: 0289-mkimage-Use-EFI32_HEADER_SIZE-define-in-arm-efi-case.patch Patch0290: 0290-mkimage-Align-efi-sections-on-4k-boundary.patch Patch0291: 0291-mkimage-Clarify-file-alignment-in-efi-case.patch Patch0292: 0292-10_linux_bls-don-t-add-users-option-to-generated-men.patch +Patch0293: 0293-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch +Patch0294: 0294-HTTP-boot-strncmp-returns-0-on-equal.patch +Patch0295: 0295-Fix-systemctl-kexec-exit-status-check.patch +Patch0296: 0296-Print-grub-emu-linux-loader-messages-as-debug.patch +Patch0297: 0297-Don-t-assume-that-boot-commands-will-only-return-on-.patch diff --git a/grub2.spec b/grub2.spec index e53b22ec..b99a0fa0 100644 --- a/grub2.spec +++ b/grub2.spec @@ -7,7 +7,7 @@ Name: grub2 Epoch: 1 Version: 2.02 -Release: 76%{?dist} +Release: 77%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ @@ -476,6 +476,15 @@ rm -r /boot/grub2.tmp/ || : %endif %changelog +* Thu Apr 18 2019 Javier Martinez Canillas - 2.02-77 +- Never remove boot loader configuration for other boot loaders from the ESP. + This would render machines with sd-boot unbootable (zbyszek) +- Execute grub2-switch-to-blscfg script in %%posttrans instead of %%post +- grub.d: Split out boot success reset from menu auto hide script (lorbus) +- HTTP boot: strncmp returns 0 on equal (stephen) +- Some grub2-emu fixes and make it to not print unnecessary messages +- Don't assume that boot commands will only return on fail + * Thu Mar 28 2019 Javier Martinez Canillas - 2.02-76 - 10_linux_bls: don't add --users option to generated menu entries Resolves: rhbz#1693515