Skip to content

Commit c3fcfe5

Browse files
martinezjavierlsandov1
authored andcommitted
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>
1 parent bb9b5f8 commit c3fcfe5

1 file changed

Lines changed: 13 additions & 10 deletions

File tree

grub-core/normal/menu.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name)
285285
}
286286

287287
/* Run a menu entry. */
288-
static void
288+
static grub_err_t
289289
grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
290290
{
291291
grub_err_t err = GRUB_ERR_NONE;
@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
302302
{
303303
grub_print_error ();
304304
grub_errno = GRUB_ERR_NONE;
305-
return;
305+
return grub_errno;
306306
}
307307

308308
errs_before = grub_err_printed_errors;
@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
315315
grub_env_context_open ();
316316
menu = grub_zalloc (sizeof (*menu));
317317
if (! menu)
318-
return;
318+
return grub_errno;
319319
grub_env_set_menu (menu);
320320
if (auto_boot)
321321
grub_env_set ("timeout", "0");
@@ -385,7 +385,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
385385

386386
if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
387387
/* Implicit execution of boot, only if something is loaded. */
388-
grub_command_execute ("boot", 0, 0);
388+
err = grub_command_execute ("boot", 0, 0);
389389

390390
if (errs_before != grub_err_printed_errors)
391391
grub_wait_after_message ();
@@ -408,6 +408,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
408408
else
409409
grub_env_unset ("default");
410410
grub_env_unset ("timeout");
411+
412+
return err;
411413
}
412414

413415
/* Execute ENTRY from the menu MENU, falling back to entries specified
@@ -422,10 +424,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
422424
void *callback_data)
423425
{
424426
int fallback_entry;
427+
grub_err_t err;
425428

426429
callback->notify_booting (entry, callback_data);
427430

428-
grub_menu_execute_entry (entry, 1);
431+
err = grub_menu_execute_entry (entry, 1);
432+
if (err == GRUB_ERR_NONE)
433+
return;
429434

430435
/* Deal with fallback entries. */
431436
while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback"))
@@ -436,11 +441,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu,
436441

437442
entry = grub_menu_get_entry (menu, fallback_entry);
438443
callback->notify_fallback (entry, callback_data);
439-
grub_menu_execute_entry (entry, 1);
440-
/* If the function call to execute the entry returns at all, then this is
441-
taken to indicate a boot failure. For menu entries that do something
442-
other than actually boot an operating system, this could assume
443-
incorrectly that something failed. */
444+
err = grub_menu_execute_entry (entry, 1);
445+
if (err == GRUB_ERR_NONE)
446+
return;
444447
}
445448

446449
if (!autobooted)

0 commit comments

Comments
 (0)