[pve-devel] [RFC pve-kernel-meta 3/5] proxmox-boot: keep EFI and legacy bootloaders in sync
Stoiko Ivanov
s.ivanov at proxmox.com
Tue Feb 1 23:03:29 CET 2022
The current boot-scheme with grub for legacy boot and systemd-boot for
UEFI makes it quite cumbersome to switch from one boot mode to the
other (by booting a live-cd, chrooting into the system with the
new boot-mode and running p-b-t init for the configured ESPs).
Additionally it causes old, unused kernel+initrd versions to take up
space on the ESPs (if a switch was performed - the old boot-mode files
are never cleaned up)
Sadly FAT does not support symlinks so it is not possible to copy the
kernel+image once and symlink it for both boot-loaders.
However systemd-boot does not need to have the files in a
vendor/version specific subdirectory (although this is against the
recommendations of the boot-loader-specification [0]) - so we can
simply point the entries to boot the kernel+initrd image from the ESPs
root (where grub needs them).
The UEFI spec on the directory structure [1], also should be fine with
it.
With the following patch p-b-t simply installs both boot-loaders in
parallel - if booted in legacy mode bootctl cannot update the efivars
accordingly - but bootctl installs systemd-boot as default boot-loader
($esp_root/EFI/BOOT/BOOTX64.EFI) in any case - so it should at least
be reachable from most UEFI menus.
Quickly tested on two VMs (one with UEFI one with legacy) - and
switching their BIOS setting did not change their ability to boot.
[0] https://systemd.io/BOOT_LOADER_SPECIFICATION/
[1] section 13.3.1.3 of
https://uefi.org/sites/default/files/resources/UEFI_Spec_2_9_2021_03_18.pdf
Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
---
bin/proxmox-boot-tool | 38 ++++++++--------
proxmox-boot/zz-proxmox-boot | 88 ++++++++++--------------------------
2 files changed, 45 insertions(+), 81 deletions(-)
diff --git a/bin/proxmox-boot-tool b/bin/proxmox-boot-tool
index af473a5..5397694 100755
--- a/bin/proxmox-boot-tool
+++ b/bin/proxmox-boot-tool
@@ -150,24 +150,26 @@ init_bootloader() {
echo "Mounting '$part' on '$esp_mp'."
mount -t vfat "$part" "$esp_mp"
- if [ -d /sys/firmware/efi ]; then
- echo "Installing systemd-boot.."
- mkdir -p "$esp_mp/$PMX_ESP_DIR"
- bootctl --path "$esp_mp" install
-
- echo "Configuring systemd-boot.."
- echo "timeout 3" > "$esp_mp/$PMX_LOADER_CONF.tmp"
- echo "default proxmox-*" >> "$esp_mp/$PMX_LOADER_CONF.tmp"
- mv "$esp_mp/$PMX_LOADER_CONF.tmp" "$esp_mp/$PMX_LOADER_CONF"
- else
- echo "Installing grub i386-pc target.."
- grub-install.real \
- --boot-directory $esp_mp \
- --target i386-pc \
- --no-floppy \
- --bootloader-id='proxmox' \
- "/dev/$PKNAME"
- fi
+ echo "Installing systemd-boot.."
+ mkdir -p "$esp_mp/$PMX_ESP_DIR"
+ bootctl_args="--path ${esp_mp}"
+ if [ ! -d /sys/firmware/efi ]; then
+ bootctl_args="${bootctl_args} --no-variables"
+ fi
+
+ bootctl ${bootctl_args} install
+ echo "Configuring systemd-boot.."
+ echo "timeout 3" > "$esp_mp/$PMX_LOADER_CONF.tmp"
+ echo "default proxmox-*" >> "$esp_mp/$PMX_LOADER_CONF.tmp"
+ mv "$esp_mp/$PMX_LOADER_CONF.tmp" "$esp_mp/$PMX_LOADER_CONF"
+
+ echo "Installing grub i386-pc target.."
+ grub-install.real \
+ --boot-directory $esp_mp \
+ --target i386-pc \
+ --no-floppy \
+ --bootloader-id='proxmox' \
+ "/dev/$PKNAME"
echo "Unmounting '$part'."
umount "$part"
diff --git a/proxmox-boot/zz-proxmox-boot b/proxmox-boot/zz-proxmox-boot
index 27448b2..5609af2 100755
--- a/proxmox-boot/zz-proxmox-boot
+++ b/proxmox-boot/zz-proxmox-boot
@@ -75,16 +75,11 @@ update_esp_func() {
{ warn "creation of mountpoint ${mountpoint} failed - skipping"; return; }
mount "${path}" "${mountpoint}" || \
{ warn "mount of ${path} failed - skipping"; return; }
- if [ -d /sys/firmware/efi ]; then
- if [ ! -f "${mountpoint}/$PMX_LOADER_CONF" ]; then
- warn "${path} contains no loader.conf - skipping"
- return
- fi
- if [ ! -d "${mountpoint}/$PMX_ESP_DIR" ]; then
- warn "${path}/$PMX_ESP_DIR does not exist- skipping"
- return
- fi
- elif [ ! -d "${mountpoint}/grub" ]; then
+ if [ ! -f "${mountpoint}/$PMX_LOADER_CONF" ]; then
+ warn "${path} contains no loader.conf - skipping"
+ return
+ fi
+ if [ ! -d "${mountpoint}/grub" ]; then
warn "${path} contains no grub directory - skipping"
return
fi
@@ -94,17 +89,12 @@ update_esp_func() {
if [ -e "${PINNED_KERNEL_CONF}" ]; then
pinned_kernel=$(get_first_line "${PINNED_KERNEL_CONF}")
fi
- if [ -d /sys/firmware/efi ]; then
- set_systemd_boot_default "${mountpoint}" "${pinned_kernel}"
- remove_old_kernels_efi "${mountpoint}"
- else
- set_grub_default "${pinned_kernel}"
- remove_old_kernels_legacy "${mountpoint}"
- mount --bind "${mountpoint}" "/boot"
- update-grub
- umount /boot
-
- fi
+ set_systemd_boot_default "${mountpoint}" "${pinned_kernel}"
+ set_grub_default "${pinned_kernel}"
+ remove_old_kernels "${mountpoint}"
+ mount --bind "${mountpoint}" "/boot"
+ update-grub
+ umount /boot
umount "${mountpoint}" || \
{ warn "umount of ${path} failed - failure"; exit 0; }
@@ -130,52 +120,23 @@ copy_and_config_kernels() {
continue
fi
- if [ -d /sys/firmware/efi ]; then
-
- warn " Copying kernel and creating boot-entry for ${kver}"
- KERNEL_ESP_DIR="${PMX_ESP_DIR}/${kver}"
- KERNEL_LIVE_DIR="${esp}/${KERNEL_ESP_DIR}"
- mkdir -p "${KERNEL_LIVE_DIR}"
- cp --preserve=timestamps "${linux_image}" "${KERNEL_LIVE_DIR}/"
- cp --preserve=timestamps "${initrd}" "${KERNEL_LIVE_DIR}/"
-
- # create loader entry
- cat > "${esp}/loader/entries/proxmox-${kver}.conf" <<- EOF
- title ${LOADER_TITLE}
- version ${kver}
- options ${CMDLINE}
- linux /${KERNEL_ESP_DIR}/vmlinuz-${kver}
- initrd /${KERNEL_ESP_DIR}/initrd.img-${kver}
- EOF
- else
- warn " Copying kernel ${kver}"
- cp --preserve=timestamps "${linux_image}" "${esp}/"
- cp --preserve=timestamps "${initrd}" "${esp}/"
- fi
- done
-
-}
-
-remove_old_kernels_efi() {
- esp="$1"
-
- for kerneldir in "${esp}/${PMX_ESP_DIR}"/*; do
- if [ ! -d "${kerneldir}" ]; then
- warn " ${kerneldir} is not a directory - skipping"
- continue
- fi
-
- kver="$(echo "${kerneldir}" | sed -r "s#^${esp}/${PMX_ESP_DIR}/(.+)\$#\\1#")"
-
- echo "${BOOT_KVERS}" | grep -q "${kver}" && continue;
- warn " Removing old version ${kver}"
- rm -rf "${kerneldir}"
- rm -f "${esp}/loader/entries/proxmox-${kver}.conf"
+ warn " Copying kernel and creating boot-entry for ${kver}"
+ cp --preserve=timestamps "${linux_image}" "${esp}/"
+ cp --preserve=timestamps "${initrd}" "${esp}/"
+
+ # create loader entry
+ cat > "${esp}/loader/entries/proxmox-${kver}.conf" <<- EOF
+ title ${LOADER_TITLE}
+ version ${kver}
+ options ${CMDLINE}
+ linux /vmlinuz-${kver}
+ initrd /initrd.img-${kver}
+ EOF
done
}
-remove_old_kernels_legacy() {
+remove_old_kernels() {
esp="$1"
for kernel in "${esp}/"vmlinuz-*; do
@@ -185,6 +146,7 @@ remove_old_kernels_legacy() {
warn " Removing old version ${kver}"
rm -rf "${esp}/vmlinuz-${kver}"
rm -rf "${esp}/initrd.img-${kver}"
+ rm -f "${esp}/loader/entries/proxmox-${kver}.conf"
done
}
--
2.30.2
More information about the pve-devel
mailing list