Skip to content

Commit

Permalink
Don't assume that boot commands will only return on fail
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
martinezjavier authored and lsandov1 committed Sep 25, 2024
1 parent bb9b5f8 commit c3fcfe5
Showing 1 changed file with 13 additions and 10 deletions.
23 changes: 13 additions & 10 deletions grub-core/normal/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,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;
Expand All @@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
{
grub_print_error ();
grub_errno = GRUB_ERR_NONE;
return;
return grub_errno;
}

errs_before = grub_err_printed_errors;
Expand All @@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
grub_env_context_open ();
menu = grub_zalloc (sizeof (*menu));
if (! menu)
return;
return grub_errno;
grub_env_set_menu (menu);
if (auto_boot)
grub_env_set ("timeout", "0");
Expand Down Expand Up @@ -385,7 +385,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 ();
Expand All @@ -408,6 +408,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
Expand All @@ -422,10 +424,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"))
Expand All @@ -436,11 +441,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)
Expand Down

0 comments on commit c3fcfe5

Please sign in to comment.