7e98da0
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
7e98da0
From: Javier Martinez Canillas <javierm@redhat.com>
7e98da0
Date: Tue, 9 Apr 2019 13:12:40 +0200
7e98da0
Subject: [PATCH] Don't assume that boot commands will only return on fail
7e98da0
7e98da0
While it's true that for most loaders the boot command never returns, it
7e98da0
may be the case that it does. For example the GRUB emulator boot command
7e98da0
calls to systemctl kexec which in turn does an asynchonous call to kexec.
7e98da0
7e98da0
So in this case GRUB will wrongly assume that the boot command fails and
7e98da0
print a "Failed to boot both default and fallback entries" even when the
7e98da0
kexec call later succeeds.
7e98da0
7e98da0
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
7e98da0
---
46968b6
 grub-core/normal/menu.c | 23 +++++++++++++----------
46968b6
 1 file changed, 13 insertions(+), 10 deletions(-)
7e98da0
7e98da0
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
e622855
index fe2e77a43e..ec0c92bade 100644
7e98da0
--- a/grub-core/normal/menu.c
7e98da0
+++ b/grub-core/normal/menu.c
904d351
@@ -285,7 +285,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name)
7e98da0
 }
7e98da0
 
7e98da0
 /* Run a menu entry.  */
7e98da0
-static void
7e98da0
+static grub_err_t
7e98da0
 grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
7e98da0
 {
7e98da0
   grub_err_t err = GRUB_ERR_NONE;
46968b6
@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
46968b6
     {
46968b6
       grub_print_error ();
46968b6
       grub_errno = GRUB_ERR_NONE;
46968b6
-      return;
46968b6
+      return grub_errno;
46968b6
     }
46968b6
 
46968b6
   errs_before = grub_err_printed_errors;
46968b6
@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
46968b6
       grub_env_context_open ();
46968b6
       menu = grub_zalloc (sizeof (*menu));
46968b6
       if (! menu)
46968b6
-	return;
46968b6
+	return grub_errno;
46968b6
       grub_env_set_menu (menu);
46968b6
       if (auto_boot)
46968b6
 	grub_env_set ("timeout", "0");
904d351
@@ -385,7 +385,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
7e98da0
 
7e98da0
   if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
7e98da0
     /* Implicit execution of boot, only if something is loaded.  */
7e98da0
-    grub_command_execute ("boot", 0, 0);
7e98da0
+    err = grub_command_execute ("boot", 0, 0);
7e98da0
 
7e98da0
   if (errs_before != grub_err_printed_errors)
7e98da0
     grub_wait_after_message ();
904d351
@@ -408,6 +408,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
7e98da0
   else
7e98da0
     grub_env_unset ("default");
7e98da0
   grub_env_unset ("timeout");
7e98da0
+
7e98da0
+  return err;
7e98da0
 }
7e98da0
 
7e98da0
 /* Execute ENTRY from the menu MENU, falling back to entries specified
904d351
@@ -422,10 +424,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
7e98da0
 				 void *callback_data)
7e98da0
 {
7e98da0
   int fallback_entry;
7e98da0
+  grub_err_t err;
7e98da0
 
7e98da0
   callback->notify_booting (entry, callback_data);
7e98da0
 
7e98da0
-  grub_menu_execute_entry (entry, 1);
7e98da0
+  err = grub_menu_execute_entry (entry, 1);
7e98da0
+  if (err == GRUB_ERR_NONE)
7e98da0
+    return;
7e98da0
 
7e98da0
   /* Deal with fallback entries.  */
7e98da0
   while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback"))
904d351
@@ -436,11 +441,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
7e98da0
 
7e98da0
       entry = grub_menu_get_entry (menu, fallback_entry);
7e98da0
       callback->notify_fallback (entry, callback_data);
7e98da0
-      grub_menu_execute_entry (entry, 1);
7e98da0
-      /* If the function call to execute the entry returns at all, then this is
7e98da0
-	 taken to indicate a boot failure.  For menu entries that do something
7e98da0
-	 other than actually boot an operating system, this could assume
7e98da0
-	 incorrectly that something failed.  */
7e98da0
+      err = grub_menu_execute_entry (entry, 1);
7e98da0
+      if (err == GRUB_ERR_NONE)
7e98da0
+        return;
7e98da0
     }
7e98da0
 
7e98da0
   if (!autobooted)