Make grub-install check for errors from efibootmgr

Code is currently ignoring errors from efibootmgr, giving users
clearly bogus output like:

        Setting up grub-efi-amd64 (2.02~beta3-4) ...
        Installing for x86_64-efi platform.
        Could not delete variable: No space left on device
        Could not prepare Boot variable: No space left on device
        Installation finished. No error reported.

and then potentially unbootable systems. If efibootmgr fails, grub-install
should know that and report it!

We've been using similar patch in Debian now for some time, with no ill effects.

Signed-off-by: Steve McIntyre <93sam@debian.org>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Steve McIntyre 2018-01-31 21:49:36 +00:00 committed by Daniel Kiper
parent d85c76b501
commit 6400613ad0
3 changed files with 29 additions and 15 deletions

View file

@ -78,19 +78,20 @@ get_ofpathname (const char *dev)
dev); dev);
} }
static void static int
grub_install_remove_efi_entries_by_distributor (const char *efi_distributor) grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
{ {
int fd; int fd;
pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd); pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
char *line = NULL; char *line = NULL;
size_t len = 0; size_t len = 0;
int rc;
if (!pid) if (!pid)
{ {
grub_util_warn (_("Unable to open stream from %s: %s"), grub_util_warn (_("Unable to open stream from %s: %s"),
"efibootmgr", strerror (errno)); "efibootmgr", strerror (errno));
return; return errno;
} }
FILE *fp = fdopen (fd, "r"); FILE *fp = fdopen (fd, "r");
@ -98,7 +99,7 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
{ {
grub_util_warn (_("Unable to open stream from %s: %s"), grub_util_warn (_("Unable to open stream from %s: %s"),
"efibootmgr", strerror (errno)); "efibootmgr", strerror (errno));
return; return errno;
} }
line = xmalloc (80); line = xmalloc (80);
@ -119,23 +120,25 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
bootnum = line + sizeof ("Boot") - 1; bootnum = line + sizeof ("Boot") - 1;
bootnum[4] = '\0'; bootnum[4] = '\0';
if (!verbosity) if (!verbosity)
grub_util_exec ((const char * []){ "efibootmgr", "-q", rc = grub_util_exec ((const char * []){ "efibootmgr", "-q",
"-b", bootnum, "-B", NULL }); "-b", bootnum, "-B", NULL });
else else
grub_util_exec ((const char * []){ "efibootmgr", rc = grub_util_exec ((const char * []){ "efibootmgr",
"-b", bootnum, "-B", NULL }); "-b", bootnum, "-B", NULL });
} }
free (line); free (line);
return rc;
} }
void int
grub_install_register_efi (grub_device_t efidir_grub_dev, grub_install_register_efi (grub_device_t efidir_grub_dev,
const char *efifile_path, const char *efifile_path,
const char *efi_distributor) const char *efi_distributor)
{ {
const char * efidir_disk; const char * efidir_disk;
int efidir_part; int efidir_part;
int ret;
efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk); efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
@ -151,23 +154,26 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL }); grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
#endif #endif
/* Delete old entries from the same distributor. */ /* Delete old entries from the same distributor. */
grub_install_remove_efi_entries_by_distributor (efi_distributor); ret = grub_install_remove_efi_entries_by_distributor (efi_distributor);
if (ret)
return ret;
char *efidir_part_str = xasprintf ("%d", efidir_part); char *efidir_part_str = xasprintf ("%d", efidir_part);
if (!verbosity) if (!verbosity)
grub_util_exec ((const char * []){ "efibootmgr", "-q", ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
"-c", "-d", efidir_disk, "-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w", "-p", efidir_part_str, "-w",
"-L", efi_distributor, "-l", "-L", efi_distributor, "-l",
efifile_path, NULL }); efifile_path, NULL });
else else
grub_util_exec ((const char * []){ "efibootmgr", ret = grub_util_exec ((const char * []){ "efibootmgr",
"-c", "-d", efidir_disk, "-c", "-d", efidir_disk,
"-p", efidir_part_str, "-w", "-p", efidir_part_str, "-w",
"-L", efi_distributor, "-l", "-L", efi_distributor, "-l",
efifile_path, NULL }); efifile_path, NULL });
free (efidir_part_str); free (efidir_part_str);
return ret;
} }
void void

View file

@ -210,7 +210,7 @@ grub_install_create_envblk_file (const char *name);
const char * const char *
grub_install_get_default_x86_platform (void); grub_install_get_default_x86_platform (void);
void int
grub_install_register_efi (grub_device_t efidir_grub_dev, grub_install_register_efi (grub_device_t efidir_grub_dev,
const char *efifile_path, const char *efifile_path,
const char *efi_distributor); const char *efi_distributor);

View file

@ -1848,9 +1848,13 @@ main (int argc, char *argv[])
if (!removable && update_nvram) if (!removable && update_nvram)
{ {
/* Try to make this image bootable using the EFI Boot Manager, if available. */ /* Try to make this image bootable using the EFI Boot Manager, if available. */
grub_install_register_efi (efidir_grub_dev, int ret;
"\\System\\Library\\CoreServices", ret = grub_install_register_efi (efidir_grub_dev,
efi_distributor); "\\System\\Library\\CoreServices",
efi_distributor);
if (ret)
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
strerror (ret));
} }
grub_device_close (ins_dev); grub_device_close (ins_dev);
@ -1871,6 +1875,7 @@ main (int argc, char *argv[])
{ {
char * efifile_path; char * efifile_path;
char * part; char * part;
int ret;
/* Try to make this image bootable using the EFI Boot Manager, if available. */ /* Try to make this image bootable using the EFI Boot Manager, if available. */
if (!efi_distributor || efi_distributor[0] == '\0') if (!efi_distributor || efi_distributor[0] == '\0')
@ -1887,8 +1892,11 @@ main (int argc, char *argv[])
efidir_grub_dev->disk->name, efidir_grub_dev->disk->name,
(part ? ",": ""), (part ? : "")); (part ? ",": ""), (part ? : ""));
grub_free (part); grub_free (part);
grub_install_register_efi (efidir_grub_dev, ret = grub_install_register_efi (efidir_grub_dev,
efifile_path, efi_distributor); efifile_path, efi_distributor);
if (ret)
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
strerror (ret));
} }
break; break;