gnu: GRUB: Check for errors from efibootmgr.
* gnu/packages/patches/grub-check-error-efibootmgr.patch: New file. * gnu/local.mk (dist_patch_DATA): Register it. * gnu/packages/bootloaders.scm (grub)[source](patches): New field.
This commit is contained in:
parent
2987b2e0d2
commit
526ce41930
@ -769,6 +769,7 @@ dist_patch_DATA = \
|
|||||||
%D%/packages/patches/grep-timing-sensitive-test.patch \
|
%D%/packages/patches/grep-timing-sensitive-test.patch \
|
||||||
%D%/packages/patches/groff-source-date-epoch.patch \
|
%D%/packages/patches/groff-source-date-epoch.patch \
|
||||||
%D%/packages/patches/groovy-add-exceptionutilsgenerator.patch \
|
%D%/packages/patches/groovy-add-exceptionutilsgenerator.patch \
|
||||||
|
%D%/packages/patches/grub-check-error-efibootmgr.patch \
|
||||||
%D%/packages/patches/gsl-test-i686.patch \
|
%D%/packages/patches/gsl-test-i686.patch \
|
||||||
%D%/packages/patches/gspell-dash-test.patch \
|
%D%/packages/patches/gspell-dash-test.patch \
|
||||||
%D%/packages/patches/guile-1.8-cpp-4.5.patch \
|
%D%/packages/patches/guile-1.8-cpp-4.5.patch \
|
||||||
|
@ -85,7 +85,8 @@
|
|||||||
(uri (string-append "mirror://gnu/grub/grub-" version ".tar.xz"))
|
(uri (string-append "mirror://gnu/grub/grub-" version ".tar.xz"))
|
||||||
(sha256
|
(sha256
|
||||||
(base32
|
(base32
|
||||||
"03vvdfhdmf16121v7xs8is2krwnv15wpkhkf16a4yf8nsfc3f2w1"))))
|
"03vvdfhdmf16121v7xs8is2krwnv15wpkhkf16a4yf8nsfc3f2w1"))
|
||||||
|
(patches (search-patches "grub-check-error-efibootmgr.patch"))))
|
||||||
(build-system gnu-build-system)
|
(build-system gnu-build-system)
|
||||||
(arguments
|
(arguments
|
||||||
`(#:phases (modify-phases %standard-phases
|
`(#:phases (modify-phases %standard-phases
|
||||||
|
176
gnu/packages/patches/grub-check-error-efibootmgr.patch
Normal file
176
gnu/packages/patches/grub-check-error-efibootmgr.patch
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
Without this patch, GRUB may proceed to wipe all firmware boot entries
|
||||||
|
and report a successful installation, even if efibootmgr hit an error.
|
||||||
|
|
||||||
|
Origin URL:
|
||||||
|
https://git.sv.gnu.org/cgit/grub.git/commit/?id=6400613ad0b463abc93362086a491cd2a5e99b0d
|
||||||
|
|
||||||
|
From 6400613ad0b463abc93362086a491cd2a5e99b0d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Steve McIntyre <steve@einval.com>
|
||||||
|
Date: Wed, 31 Jan 2018 21:49:36 +0000
|
||||||
|
Subject: 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.
|
||||||
|
|
||||||
|
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||||
|
index a3fcfca..ca448bc 100644
|
||||||
|
--- a/grub-core/osdep/unix/platform.c
|
||||||
|
+++ b/grub-core/osdep/unix/platform.c
|
||||||
|
@@ -78,19 +78,20 @@ get_ofpathname (const char *dev)
|
||||||
|
dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void
|
||||||
|
+static int
|
||||||
|
grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
pid_t pid = grub_util_exec_pipe ((const char * []){ "efibootmgr", NULL }, &fd);
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len = 0;
|
||||||
|
+ int rc;
|
||||||
|
|
||||||
|
if (!pid)
|
||||||
|
{
|
||||||
|
grub_util_warn (_("Unable to open stream from %s: %s"),
|
||||||
|
"efibootmgr", strerror (errno));
|
||||||
|
- return;
|
||||||
|
+ return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
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"),
|
||||||
|
"efibootmgr", strerror (errno));
|
||||||
|
- return;
|
||||||
|
+ return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
line = xmalloc (80);
|
||||||
|
@@ -119,23 +120,25 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
|
||||||
|
bootnum = line + sizeof ("Boot") - 1;
|
||||||
|
bootnum[4] = '\0';
|
||||||
|
if (!verbosity)
|
||||||
|
- grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||||
|
+ rc = grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||||
|
"-b", bootnum, "-B", NULL });
|
||||||
|
else
|
||||||
|
- grub_util_exec ((const char * []){ "efibootmgr",
|
||||||
|
+ rc = grub_util_exec ((const char * []){ "efibootmgr",
|
||||||
|
"-b", bootnum, "-B", NULL });
|
||||||
|
}
|
||||||
|
|
||||||
|
free (line);
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void
|
||||||
|
+int
|
||||||
|
grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||||
|
const char *efifile_path,
|
||||||
|
const char *efi_distributor)
|
||||||
|
{
|
||||||
|
const char * efidir_disk;
|
||||||
|
int efidir_part;
|
||||||
|
+ int ret;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@@ -151,23 +154,26 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||||
|
grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
|
||||||
|
#endif
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
if (!verbosity)
|
||||||
|
- grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||||
|
+ ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||||
|
"-c", "-d", efidir_disk,
|
||||||
|
"-p", efidir_part_str, "-w",
|
||||||
|
"-L", efi_distributor, "-l",
|
||||||
|
efifile_path, NULL });
|
||||||
|
else
|
||||||
|
- grub_util_exec ((const char * []){ "efibootmgr",
|
||||||
|
+ ret = grub_util_exec ((const char * []){ "efibootmgr",
|
||||||
|
"-c", "-d", efidir_disk,
|
||||||
|
"-p", efidir_part_str, "-w",
|
||||||
|
"-L", efi_distributor, "-l",
|
||||||
|
efifile_path, NULL });
|
||||||
|
free (efidir_part_str);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||||
|
index 5910b0c..0dba8b6 100644
|
||||||
|
--- a/include/grub/util/install.h
|
||||||
|
+++ b/include/grub/util/install.h
|
||||||
|
@@ -210,7 +210,7 @@ grub_install_create_envblk_file (const char *name);
|
||||||
|
const char *
|
||||||
|
grub_install_get_default_x86_platform (void);
|
||||||
|
|
||||||
|
-void
|
||||||
|
+int
|
||||||
|
grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||||
|
const char *efifile_path,
|
||||||
|
const char *efi_distributor);
|
||||||
|
diff --git a/util/grub-install.c b/util/grub-install.c
|
||||||
|
index 5e4cdfd..690f180 100644
|
||||||
|
--- a/util/grub-install.c
|
||||||
|
+++ b/util/grub-install.c
|
||||||
|
@@ -1848,9 +1848,13 @@ main (int argc, char *argv[])
|
||||||
|
if (!removable && update_nvram)
|
||||||
|
{
|
||||||
|
/* Try to make this image bootable using the EFI Boot Manager, if available. */
|
||||||
|
- grub_install_register_efi (efidir_grub_dev,
|
||||||
|
- "\\System\\Library\\CoreServices",
|
||||||
|
- efi_distributor);
|
||||||
|
+ int ret;
|
||||||
|
+ ret = grub_install_register_efi (efidir_grub_dev,
|
||||||
|
+ "\\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);
|
||||||
|
@@ -1871,6 +1875,7 @@ main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char * efifile_path;
|
||||||
|
char * part;
|
||||||
|
+ int ret;
|
||||||
|
|
||||||
|
/* Try to make this image bootable using the EFI Boot Manager, if available. */
|
||||||
|
if (!efi_distributor || efi_distributor[0] == '\0')
|
||||||
|
@@ -1887,8 +1892,11 @@ main (int argc, char *argv[])
|
||||||
|
efidir_grub_dev->disk->name,
|
||||||
|
(part ? ",": ""), (part ? : ""));
|
||||||
|
grub_free (part);
|
||||||
|
- grub_install_register_efi (efidir_grub_dev,
|
||||||
|
- efifile_path, efi_distributor);
|
||||||
|
+ ret = grub_install_register_efi (efidir_grub_dev,
|
||||||
|
+ efifile_path, efi_distributor);
|
||||||
|
+ if (ret)
|
||||||
|
+ grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
|
||||||
|
+ strerror (ret));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user