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
					
				
					 3 changed files with 179 additions and 1 deletions
				
			
		| 
						 | 
					@ -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;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
		Reference in a new issue