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
1diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c
2index d76c34c..b39e97f 100644
3--- a/grub-core/osdep/basic/no_platform.c
4+++ b/grub-core/osdep/basic/no_platform.c
5@@ -25,7 +25,7 @@
6
7 void
8 grub_install_register_ieee1275 (int is_prep, const char *install_device,
9- int partno, const char *relpath)
10+ int partno, const char *relpath, int detect_nvram)
11 {
12 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));
13 }
14@@ -33,7 +33,8 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
15 void
16 grub_install_register_efi (grub_device_t efidir_grub_dev,
17 const char *efifile_path,
18- const char *efi_distributor)
19+ const char *efi_distributor,
20+ int detect_nvram)
21 {
22 grub_util_error ("%s", _("no EFI routines are available for your platform"));
23 }
24diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
25index f9c376c..ddfa4dd 100644
26--- a/grub-core/osdep/unix/platform.c
27+++ b/grub-core/osdep/unix/platform.c
28@@ -134,7 +134,8 @@ grub_install_remove_efi_entries_by_distributor (const char *efi_distributor)
29 int
30 grub_install_register_efi (grub_device_t efidir_grub_dev,
31 const char *efifile_path,
32- const char *efi_distributor)
33+ const char *efi_distributor,
34+ int detect_nvram)
35 {
36 const char * efidir_disk;
37 int efidir_part;
38@@ -153,6 +154,18 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
39 #ifdef __linux__
40 grub_util_exec ((const char * []){ "modprobe", "-q", "efivars", NULL });
41 #endif
42+
43+ /* If requested, we try to detect if NVRAM access is available and if not,
44+ warn the user and resume normal operation. */
45+ if (detect_nvram)
46+ {
47+ error = grub_util_exec_redirect_null ((const char * []){ "efibootmgr", NULL });
48+ if (error == 2)
49+ return 0;
50+ else if (error)
51+ return error;
52+ }
53+
54 /* Delete old entries from the same distributor. */
55 error = grub_install_remove_efi_entries_by_distributor (efi_distributor);
56 if (error)
57@@ -178,7 +191,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
58
59 void
60 grub_install_register_ieee1275 (int is_prep, const char *install_device,
61- int partno, const char *relpath)
62+ int partno, const char *relpath, int detect_nvram)
63 {
64 char *boot_device;
65
66@@ -189,6 +202,14 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
67 grub_util_error (_("%s: not found"), "ofpathname");
68 }
69
70+ /* If requested, we try to detect if NVRAM access is available and if not,
71+ warn the user and resume normal operation. */
72+ if (detect_nvram && grub_util_exec_redirect_null ((const char * []){ "nvram", NULL }))
73+ {
74+ grub_util_warn ("%s", _("Auto-NVRAM selected and no IEEE1275 variable support detected on the system."));
75+ return;
76+ }
77+
78 /* Get the Open Firmware device tree path translation. */
79 if (!is_prep)
80 {
81diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
82index c30025b..1c96959 100644
83--- a/grub-core/osdep/windows/platform.c
84+++ b/grub-core/osdep/windows/platform.c
85@@ -210,7 +210,8 @@ set_efi_variable_bootn (grub_uint16_t n, void *in, grub_size_t len)
86 void
87 grub_install_register_efi (grub_device_t efidir_grub_dev,
88 const char *efifile_path,
89- const char *efi_distributor)
90+ const char *efi_distributor,
91+ int detect_nvram)
92 {
93 grub_uint16_t *boot_order, *new_boot_order;
94 grub_uint16_t *distributor16;
95@@ -417,7 +418,7 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
96
97 void
98 grub_install_register_ieee1275 (int is_prep, const char *install_device,
99- int partno, const char *relpath)
100+ int partno, const char *relpath, int detect_nvram)
101 {
102 grub_util_error ("%s", _("no IEEE1275 routines are available for your platform"));
103 }
104diff --git a/include/grub/util/install.h b/include/grub/util/install.h
105index 58648e2..1151883 100644
106--- a/include/grub/util/install.h
107+++ b/include/grub/util/install.h
108@@ -212,11 +212,12 @@ grub_install_get_default_powerpc_machtype (void);
109 int
110 grub_install_register_efi (grub_device_t efidir_grub_dev,
111 const char *efifile_path,
112- const char *efi_distributor);
113+ const char *efi_distributor,
114+ int detect_nvram);
115
116 void
117 grub_install_register_ieee1275 (int is_prep, const char *install_device,
118- int partno, const char *relpath);
119+ int partno, const char *relpath, int detect_nvram);
120
121 void
122 grub_install_sgi_setup (const char *install_device,
123diff --git a/util/grub-install.c b/util/grub-install.c
124index 2214e45..b8f9110 100644
125--- a/util/grub-install.c
126+++ b/util/grub-install.c
127@@ -59,6 +59,7 @@ static int removable = 0;
128 static int no_extra_removable = 0;
129 static int recheck = 0;
130 static int update_nvram = 1;
131+static int auto_nvram = 0;
132 static char *install_device = NULL;
133 static char *debug_image = NULL;
134 static char *rootdir = NULL;
135@@ -115,7 +116,8 @@ enum
136 OPTION_PRODUCT_VERSION,
137 OPTION_UEFI_SECURE_BOOT,
138 OPTION_NO_UEFI_SECURE_BOOT,
139- OPTION_NO_EXTRA_REMOVABLE
140+ OPTION_NO_EXTRA_REMOVABLE,
141+ OPTION_AUTO_NVRAM
142 };
143
144 static int fs_probe = 1;
145@@ -206,6 +208,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
146 update_nvram = 0;
147 return 0;
148
149+ case OPTION_AUTO_NVRAM:
150+ auto_nvram = 1;
151+ return 0;
152+
153 case OPTION_FORCE:
154 force = 1;
155 return 0;
156@@ -296,6 +302,9 @@ static struct argp_option options[] = {
157 {"no-nvram", OPTION_NO_NVRAM, 0, 0,
158 N_("don't update the `boot-device'/`Boot*' NVRAM variables. "
159 "This option is only available on EFI and IEEE1275 targets."), 2},
160+ {"auto-nvram", OPTION_AUTO_NVRAM, 0, 0,
161+ N_("only update NVRAM variables if possible. "
162+ "This option is only available on EFI and IEEE1275 targets."), 2},
163 {"skip-fs-probe",'s',0, 0,
164 N_("do not probe for filesystems in DEVICE"), 0},
165 {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0,
166@@ -1924,7 +1933,7 @@ main (int argc, char *argv[])
167 ? ins_dev->disk->partition->number + 1 : 0;
168 dev = grub_util_get_os_disk (install_device);
169 grub_install_register_ieee1275 (0, dev, partno,
170- "\\\\BootX");
171+ "\\\\BootX", auto_nvram);
172 }
173 grub_device_close (ins_dev);
174 free (grub_elf);
175@@ -1956,7 +1965,7 @@ main (int argc, char *argv[])
176 grub_device_close (ins_dev);
177 if (update_nvram)
178 grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
179- 0, NULL);
180+ 0, NULL, auto_nvram);
181 break;
182 }
183 /* fallthrough. */
184@@ -1971,7 +1980,7 @@ main (int argc, char *argv[])
185 ? grub_dev->disk->partition->number + 1 : 0;
186 dev = grub_util_get_os_disk (grub_devices[0]);
187 grub_install_register_ieee1275 (0, dev,
188- partno, relpath);
189+ partno, relpath, auto_nvram);
190 }
191 break;
192 case GRUB_INSTALL_PLATFORM_MIPS_ARC:
193@@ -2020,7 +2029,7 @@ main (int argc, char *argv[])
194 int error = 0;
195 error = grub_install_register_efi (efidir_grub_dev,
196 "\\System\\Library\\CoreServices",
197- efi_distributor);
198+ efi_distributor, auto_nvram);
199 if (error)
200 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
201 strerror (error));
202@@ -2135,7 +2144,7 @@ main (int argc, char *argv[])
203 (part ? ",": ""), (part ? : ""));
204 grub_free (part);
205 error = grub_install_register_efi (efidir_grub_dev,
206- efifile_path, efi_distributor);
207+ efifile_path, efi_distributor, auto_nvram);
208 if (error)
209 grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
210 strerror (error));

Subscribers

People subscribed via source and target branches