Some grub2-emu, HTTP boot and fallback fixes

Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
This commit is contained in:
Javier Martinez Canillas 2019-04-16 18:34:31 +02:00
parent 173fb18386
commit 62a05cdcd4
No known key found for this signature in database
GPG Key ID: C751E590D63F3D69
7 changed files with 339 additions and 1 deletions

View File

@ -0,0 +1,152 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Christian Glombek <lorbus@fedoraproject.org>
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

View File

@ -0,0 +1,22 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stephen Benjamin <stephen@redhat.com>
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)

View File

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
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 <javierm@redhat.com>
---
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'");

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
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 <javierm@redhat.com>
---
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);

View File

@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
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 <javierm@redhat.com>
---
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)

View File

@ -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

View File

@ -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 <javierm@redhat.com> - 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 <javierm@redhat.com> - 2.02-76
- 10_linux_bls: don't add --users option to generated menu entries
Resolves: rhbz#1693515