[pve-devel] applied: [PATCH installer] mount efivarfs to ensure we can read bigger variables

Thomas Lamprecht t.lamprecht at proxmox.com
Mon Jul 8 16:37:55 CEST 2019


In short, EFI variables can get quite big, and the old sysfs
interface was made for when they couldn't. A few firmwares out there
have such big variables, and if those are accessed through the sysfs
backed interface one gets a "Input/Output Error". 'grub-install'
chokes on that error when it iterates over all variables to do it's
stuff, and thus fails our installation. When we mount the efivarfs,
which does not has this limitations, one can read all variables just
fine - at least as long as the NVRAM backing them is not broken.

from Linux Kernel Documentation/filesystems/efivarfs.txt:
> The efivarfs filesystem was created to address the shortcomings of
> using entries in sysfs to maintain EFI variables. The old sysfs EFI
> variables code only supported variables of up to 1024 bytes. This
> limitation existed in version 0.99 of the EFI specification, but was
> removed before any full releases. Since variables can now be larger
> than a single page, sysfs isn't the best interface for this.
> Variables can be created, deleted and modified with the efivarfs
> filesystem.

Also mount it in the installer environment for debugging purpose.

Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
---

this allows also to remove the "--no-variables" switch from our call to
bootctl, as now the variable store should always be fully functional.

 proxinstall     | 7 ++++++-
 unconfigured.sh | 4 ++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/proxinstall b/proxinstall
index 1f70720..019ae0b 100755
--- a/proxinstall
+++ b/proxinstall
@@ -1097,7 +1097,7 @@ sub prepare_systemd_boot_esp {
     File::Path::make_path("$targetdir/$espmp/EFI/proxmox") ||
 	die "unable to create directory $targetdir/$espmp/EFI/proxmox\n";
 
-    syscmd("chroot $targetdir bootctl --no-variables --path /$espmp install") == 0 ||
+    syscmd("chroot $targetdir bootctl --path /$espmp install") == 0 ||
 	die "unable to install systemd-boot loader\n";
     write_config("timeout 3\ndefault proxmox-*\n",
 	"$targetdir/$espmp/loader/loader.conf");
@@ -1378,6 +1378,10 @@ sub extract_data {
 	    die "unable to mount proc on $targetdir/proc\n";
 	syscmd("mount -n -t sysfs sysfs $targetdir/sys") == 0 ||
 	    die "unable to mount sysfs on $targetdir/sys\n";
+	if ($boot_type eq 'efi') {
+	    syscmd("mount -n -t efivarfs none $targetdir/sys/firmware/efi/efivars") == 0 ||
+		die "unable to mount efivarfs on $targetdir/sys/firmware/efi/efivars: $!\n";
+	}
 	syscmd("chroot $targetdir mount --bind /mnt/hostrun /run") == 0 ||
 	    die "unable to re-bindmount hostrun on /run in chroot\n";
 
@@ -1735,6 +1739,7 @@ _EOD
     syscmd("umount $targetdir/mnt/hostrun");
     syscmd("umount $targetdir/tmp");
     syscmd("umount $targetdir/proc");
+    syscmd("umount $targetdir/sys/firmware/efi/efivars");
     syscmd("umount $targetdir/sys");
 
     if ($use_zfs) {
diff --git a/unconfigured.sh b/unconfigured.sh
index 674605f..d16ea61 100755
--- a/unconfigured.sh
+++ b/unconfigured.sh
@@ -63,6 +63,10 @@ export SYSTEMD_IGNORE_CHROOT=1
 
 mount -n -t proc proc /proc
 mount -n -t sysfs sysfs /sys
+if [ -d /sys/firmware/efi ]; then
+    echo "EFI boot mode detected, mounting efivars filesystem"
+    mount -nt efivarfs none /sys/firmware/efi/efivars
+fi
 mount -n -t tmpfs tmpfs /run
 
 parse_cmdline
-- 
2.20.1





More information about the pve-devel mailing list