Merge ~ubuntu-core-dev/grub/+git/ubuntu:sil2100/auto-nvram into ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu

Proposed by Łukasz Zemczak
Status: Merged
Approved by: Mathieu Trudel-Lapierre
Approved revision: 7b18c6eb099df89c5bd4a8f1404c52c5267b8c29
Merge reported by: Mathieu Trudel-Lapierre
Merged at revision: 0ef4190ef99c4b0762afd7f4b634e1861a7ac30b
Proposed branch: ~ubuntu-core-dev/grub/+git/ubuntu:sil2100/auto-nvram
Merge into: ~ubuntu-core-dev/grub/+git/ubuntu:ubuntu
Diff against target: 210 lines (+47/-14)
5 files modified
grub-core/osdep/basic/no_platform.c (+3/-2)
grub-core/osdep/unix/platform.c (+23/-2)
grub-core/osdep/windows/platform.c (+3/-2)
include/grub/util/install.h (+3/-2)
util/grub-install.c (+15/-6)
Reviewer Review Type Date Requested Status
Mathieu Trudel-Lapierre Approve
Review via email: mp+341670@code.launchpad.net

Commit message

Add the auto-nvram functionality of only attempting the NVRAM variable update if the system has access to those. Useful for dual BIOS-EFI devices.

Description of the change

Add the auto-nvram functionality of only attempting the NVRAM variable update if the system has access to those. Useful for dual BIOS-EFI devices.

This branch's approach is to add a new parameter to the existing update procedures for EFI/IEEE1275. I like this approach since it's not adding any new functions to the namespace that need re-implementation for each platform. That being said, another MP will be following with the approach of simply adding new functions for doing the NVRAM existence checks which might be 'cleaner'.

This is the first time I'm submitting an MP for grub2 which is git-dpm based. I know this branch probably needs to have a git-dpm update-patches + dch run done, but for review's sake I'm not doing this step right now.

To post a comment you must log in.
7b18c6e... by Łukasz Zemczak

Fix a typo due to cherry-picking. Add the missing auto-nvram check for ieee1275.

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

The 'alternative' approach can be found here:

https://code.launchpad.net/~sil2100/grub2/+git/ubuntu/+ref/sil2100/auto-nvram-alternative

But as I said, I am more in favor of the one that's being proposed for merging here.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) wrote :

What is the use of this new feature? How does it differ from --no-nvram?

I'm curious because it seems like this is simply "warning" and skipping setting variables, yet you usually do want to update variables in nearly all cases -- when you can't, this probably should be a critical bug and a proper failure.

I'm also unsure about the implementation, this looks like the behavior of "auto-nvram" and "no-nvram" probably could be merged to some degree.

This won't exactly help dual EFI/non-EFI devices much -- in the case where you're installing from a BIOS-installed system, you won't find the variables anyway to try to update them, and if you're booted in EFI mode, you're detecting whether the variables are there (and they should, as above, if they're not, this is potentially a critical issue; these special cases might well be best served with just --no-nvram). Maybe I've missed some important piece, but I see no logic handling the "I booted in BIOS mode, but I really want both things updated". I also have no idea how to handle such a case anyway.

review: Needs Information
Revision history for this message
Łukasz Zemczak (sil2100) wrote :

It differs from --no-nvram as it does attempt updating the EFI variables if present. So my understanding here, and I'm not an expert of the dual EFI/non-EFI installation, is that we would want grub-install for Ubuntu to use --auto-nvram by default for both BIOS and EFI (in all cases).

If we want to have both grub-pc and shim-efi installed, normally a grub-install --target=x86_64-efi from shim-efi would just fail on a BIOS booted system. We can't append --no-nvram to it unconditionally as then in cases when we're booted in EFI, we won't get the variables updated while we should. Instead of detecting from inside shim-efi if we're running in BIOS mode or not, Steve's proposition was to just add the --auto-nvram option which tells grub-install: "if your target is x86_64-efi but there is no access to the NVRAM, don't fail the install as it just means we're in BIOS mode and this is not a critical error as we're probably handling a dual EFI/non-EFI situation".
This would mean we'd just be doing grub-install --target=x86_64-efi --auto-nvram for shim-efi instead. This way, if I understand it correctly of course, we could have both packages co-installed and not erroring out. It's really just migrating the detection from the packaging side (like doing things in postinst) to grub-install getting slightly smarter.

That's my understanding of what I was working on - I might be terribly wrong of course! Steve can give a more detailed explanation probably as he's the author of the proposal.

Revision history for this message
Mathieu Trudel-Lapierre (cyphermox) :
review: Approve
0ef4190... by Łukasz Zemczak

Upstream prefers ignoring the no-NVRAM access silently.

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c
index d76c34c..b39e97f 100644
--- a/grub-core/osdep/basic/no_platform.c
+++ b/grub-core/osdep/basic/no_platform.c
@@ -25,7 +25,7 @@
2525
26void26void
27grub_install_register_ieee1275 (int is_prep, const char *install_device,27grub_install_register_ieee1275 (int is_prep, const char *install_device,
28 int partno, const char *relpath)28 int partno, const char *relpath, int detect_nvram)
29{29{
30 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));30 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));
31}31}
@@ -33,7 +33,8 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
33void33void
34grub_install_register_efi (grub_device_t efidir_grub_dev,34grub_install_register_efi (grub_device_t efidir_grub_dev,
35 const char *efifile_path,35 const char *efifile_path,
36 const char *efi_distributor)36 const char *efi_distributor,
37 int detect_nvram)
37{38{
38 grub_util_error ("%s", _("no EFI routines are available for your platform"));39 grub_util_error ("%s", _("no EFI routines are available for your platform"));
39}40}
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
index f9c376c..ddfa4dd 100644
--- a/grub-core/osdep/unix/platform.c
+++ b/grub-core/osdep/unix/platform.c
@@ -134,7 +134,8 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
134int134int
135grub_install_register_efi (grub_device_t efidir_grub_dev,135grub_install_register_efi (grub_device_t efidir_grub_dev,
136 const char *efifile_path,136 const char *efifile_path,
137 const char *efi_distributor)137 const char *efi_distributor,
138 int detect_nvram)
138{139{
139 const char * efidir_disk;140 const char * efidir_disk;
140 int efidir_part;141 int efidir_part;
@@ -153,6 +154,18 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
153#ifdef __linux__154#ifdef __linux__
154 grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });155 grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
155#endif156#endif
157
158 /* If requested, we try to detect if NVRAM access is available and if not,
159 warn the user and resume normal operation. */
160 if (detect_nvram)
161 {
162 error = grub_util_exec_redirect_null ((const char * []){ "efibootmgr", NULL });
163 if (error == 2)
164 return 0;
165 else if (error)
166 return error;
167 }
168
156 /* Delete old entries from the same distributor. */169 /* Delete old entries from the same distributor. */
157 error = grub_install_remove_efi_entries_by_distributor (efi_distributor);170 error = grub_install_remove_efi_entries_by_distributor (efi_distributor);
158 if (error)171 if (error)
@@ -178,7 +191,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
178191
179void192void
180grub_install_register_ieee1275 (int is_prep, const char *install_device,193grub_install_register_ieee1275 (int is_prep, const char *install_device,
181 int partno, const char *relpath)194 int partno, const char *relpath, int detect_nvram)
182{195{
183 char *boot_device;196 char *boot_device;
184197
@@ -189,6 +202,14 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
189 grub_util_error (_("%s: not found"), "ofpathname");202 grub_util_error (_("%s: not found"), "ofpathname");
190 }203 }
191204
205 /* If requested, we try to detect if NVRAM access is available and if not,
206 warn the user and resume normal operation. */
207 if (detect_nvram && grub_util_exec_redirect_null ((const char * []){ "nvram", NULL }))
208 {
209 grub_util_warn ("%s", _("Auto-NVRAM selected and no IEEE1275 variable support detected on the system."));
210 return;
211 }
212
192 /* Get the Open Firmware device tree path translation. */213 /* Get the Open Firmware device tree path translation. */
193 if (!is_prep)214 if (!is_prep)
194 {215 {
diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
index c30025b..1c96959 100644
--- a/grub-core/osdep/windows/platform.c
+++ b/grub-core/osdep/windows/platform.c
@@ -210,7 +210,8 @@ set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len)
210void210void
211grub_install_register_efi (grub_device_t efidir_grub_dev,211grub_install_register_efi (grub_device_t efidir_grub_dev,
212 const char *efifile_path,212 const char *efifile_path,
213 const char *efi_distributor)213 const char *efi_distributor,
214 int detect_nvram)
214{215{
215 grub_uint16_t *boot_order, *new_boot_order;216 grub_uint16_t *boot_order, *new_boot_order;
216 grub_uint16_t *distributor16;217 grub_uint16_t *distributor16;
@@ -417,7 +418,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
417418
418void419void
419grub_install_register_ieee1275 (int is_prep, const char *install_device,420grub_install_register_ieee1275 (int is_prep, const char *install_device,
420 int partno, const char *relpath)421 int partno, const char *relpath, int detect_nvram)
421{422{
422 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));423 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));
423}424}
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index 58648e2..1151883 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -212,11 +212,12 @@ grub_install_get_default_powerpc_machtype (void);
212int212int
213grub_install_register_efi (grub_device_t efidir_grub_dev,213grub_install_register_efi (grub_device_t efidir_grub_dev,
214 const char *efifile_path,214 const char *efifile_path,
215 const char *efi_distributor);215 const char *efi_distributor,
216 int detect_nvram);
216217
217void218void
218grub_install_register_ieee1275 (int is_prep, const char *install_device,219grub_install_register_ieee1275 (int is_prep, const char *install_device,
219 int partno, const char *relpath);220 int partno, const char *relpath, int detect_nvram);
220221
221void222void
222grub_install_sgi_setup (const char *install_device,223grub_install_sgi_setup (const char *install_device,
diff --git a/util/grub-install.c b/util/grub-install.c
index 2214e45..b8f9110 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -59,6 +59,7 @@ static int removable = 0;
59static int no_extra_removable = 0;59static int no_extra_removable = 0;
60static int recheck = 0;60static int recheck = 0;
61static int update_nvram = 1;61static int update_nvram = 1;
62static int auto_nvram = 0;
62static char *install_device = NULL;63static char *install_device = NULL;
63static char *debug_image = NULL;64static char *debug_image = NULL;
64static char *rootdir = NULL;65static char *rootdir = NULL;
@@ -115,7 +116,8 @@ enum
115 OPTION_PRODUCT_VERSION,116 OPTION_PRODUCT_VERSION,
116 OPTION_UEFI_SECURE_BOOT,117 OPTION_UEFI_SECURE_BOOT,
117 OPTION_NO_UEFI_SECURE_BOOT,118 OPTION_NO_UEFI_SECURE_BOOT,
118 OPTION_NO_EXTRA_REMOVABLE119 OPTION_NO_EXTRA_REMOVABLE,
120 OPTION_AUTO_NVRAM
119 };121 };
120122
121static int fs_probe = 1;123static int fs_probe = 1;
@@ -206,6 +208,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
206 update_nvram = 0;208 update_nvram = 0;
207 return 0;209 return 0;
208210
211 case OPTION_AUTO_NVRAM:
212 auto_nvram = 1;
213 return 0;
214
209 case OPTION_FORCE:215 case OPTION_FORCE:
210 force = 1;216 force = 1;
211 return 0;217 return 0;
@@ -296,6 +302,9 @@ static struct argp_option options[] = {
296 {"no-nvram", OPTION_NO_NVRAM, 0, 0,302 {"no-nvram", OPTION_NO_NVRAM, 0, 0,
297 N_("don't update the `boot-device'/`Boot*' NVRAM variables. "303 N_("don't update the `boot-device'/`Boot*' NVRAM variables. "
298 "This option is only available on EFI and IEEE1275 targets."), 2},304 "This option is only available on EFI and IEEE1275 targets."), 2},
305 {"auto-nvram", OPTION_AUTO_NVRAM, 0, 0,
306 N_("only update NVRAM variables if possible. "
307 "This option is only available on EFI and IEEE1275 targets."), 2},
299 {"skip-fs-probe",'s',0, 0,308 {"skip-fs-probe",'s',0, 0,
300 N_("do not probe for filesystems in DEVICE"), 0},309 N_("do not probe for filesystems in DEVICE"), 0},
301 {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,310 {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
@@ -1924,7 +1933,7 @@ main (int argc, char *argv[])
1924 ? ins_dev->disk->partition->number + 1 : 0;1933 ? ins_dev->disk->partition->number + 1 : 0;
1925 dev = grub_util_get_os_disk (install_device);1934 dev = grub_util_get_os_disk (install_device);
1926 grub_install_register_ieee1275 (0, dev, partno,1935 grub_install_register_ieee1275 (0, dev, partno,
1927 "\\\\BootX");1936 "\\\\BootX", auto_nvram);
1928 }1937 }
1929 grub_device_close (ins_dev);1938 grub_device_close (ins_dev);
1930 free (grub_elf);1939 free (grub_elf);
@@ -1956,7 +1965,7 @@ main (int argc, char *argv[])
1956 grub_device_close (ins_dev);1965 grub_device_close (ins_dev);
1957 if (update_nvram)1966 if (update_nvram)
1958 grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),1967 grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
1959 0, NULL);1968 0, NULL, auto_nvram);
1960 break;1969 break;
1961 }1970 }
1962 /* fallthrough. */1971 /* fallthrough. */
@@ -1971,7 +1980,7 @@ main (int argc, char *argv[])
1971 ? grub_dev->disk->partition->number + 1 : 0;1980 ? grub_dev->disk->partition->number + 1 : 0;
1972 dev = grub_util_get_os_disk (grub_devices[0]);1981 dev = grub_util_get_os_disk (grub_devices[0]);
1973 grub_install_register_ieee1275 (0, dev,1982 grub_install_register_ieee1275 (0, dev,
1974 partno, relpath);1983 partno, relpath, auto_nvram);
1975 }1984 }
1976 break;1985 break;
1977 case GRUB_INSTALL_PLATFORM_MIPS_ARC:1986 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
@@ -2020,7 +2029,7 @@ main (int argc, char *argv[])
2020 int error = 0;2029 int error = 0;
2021 error = grub_install_register_efi (efidir_grub_dev,2030 error = grub_install_register_efi (efidir_grub_dev,
2022 "\\System\\Library\\CoreServices",2031 "\\System\\Library\\CoreServices",
2023 efi_distributor);2032 efi_distributor, auto_nvram);
2024 if (error)2033 if (error)
2025 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),2034 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
2026 strerror (error));2035 strerror (error));
@@ -2135,7 +2144,7 @@ main (int argc, char *argv[])
2135 (part ? ",": ""), (part ? : ""));2144 (part ? ",": ""), (part ? : ""));
2136 grub_free (part);2145 grub_free (part);
2137 error = grub_install_register_efi (efidir_grub_dev,2146 error = grub_install_register_efi (efidir_grub_dev,
2138 efifile_path, efi_distributor);2147 efifile_path, efi_distributor, auto_nvram);
2139 if (error)2148 if (error)
2140 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),2149 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
2141 strerror (error));2150 strerror (error));

Subscribers

People subscribed via source and target branches