From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id DA5B960401 for ; Tue, 1 Feb 2022 23:03:49 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D871552C0 for ; Tue, 1 Feb 2022 23:03:49 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 32FCB52A9 for ; Tue, 1 Feb 2022 23:03:48 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0B81D4567D for ; Tue, 1 Feb 2022 23:03:48 +0100 (CET) From: Stoiko Ivanov To: pve-devel@lists.proxmox.com Date: Tue, 1 Feb 2022 23:03:29 +0100 Message-Id: <20220201220331.3491615-4-s.ivanov@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220201220331.3491615-1-s.ivanov@proxmox.com> References: <20220201220331.3491615-1-s.ivanov@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.103 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_SHORT 0.001 Use of a URL Shortener for very short URL POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [uefi.org, systemd.io] Subject: [pve-devel] [RFC pve-kernel-meta 3/5] proxmox-boot: keep EFI and legacy bootloaders in sync X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Feb 2022 22:03:50 -0000 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 --- 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