From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <s.ivanov@proxmox.com>
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 8F395765E9
 for <pve-devel@lists.proxmox.com>; Fri, 23 Apr 2021 11:05:41 +0200 (CEST)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
 by firstgate.proxmox.com (Proxmox) with ESMTP id 0971325A79
 for <pve-devel@lists.proxmox.com>; Fri, 23 Apr 2021 11:05:11 +0200 (CEST)
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 4F07525952
 for <pve-devel@lists.proxmox.com>; Fri, 23 Apr 2021 11:05:05 +0200 (CEST)
Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1])
 by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 28F3842821
 for <pve-devel@lists.proxmox.com>; Fri, 23 Apr 2021 11:05:05 +0200 (CEST)
From: Stoiko Ivanov <s.ivanov@proxmox.com>
To: pve-devel@lists.proxmox.com
Date: Fri, 23 Apr 2021 11:04:47 +0200
Message-Id: <20210423090451.2279-6-s.ivanov@proxmox.com>
X-Mailer: git-send-email 2.20.1
In-Reply-To: <20210423090451.2279-1-s.ivanov@proxmox.com>
References: <20210423090451.2279-1-s.ivanov@proxmox.com>
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
X-SPAM-LEVEL: Spam detection results:  0
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pve-devel] [PATCH pve-kernel-meta v2 5/8] proxmox-boot-tool:
 handle legacy boot zfs installs
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
X-List-Received-Date: Fri, 23 Apr 2021 09:05:41 -0000

This patch adds support for booting non-uefi/legacy/bios-boot ZFS
installs, by using proxmox-boot-tool to copy the kernels to the ESP
and then generate a fitting grub config for booting from the vfat ESP:

* grub is installed onto the ESP and the MBR points to the ESP
* after copying/deleting the kernels proxmox-boot-tool bindmounts the
  ESP on /boot (inside the new mount namespace)
* grub-update then manages to generate a fitting config.

Some paths/sanity-checks needed adaptation (to differentiate between
EFI boot and not (based on the existence of /sys/firmware/efi)

The arguments for grub-install are taken from the pve-installer.

The approach is inspired by @avw in our community-forum [0].

[0] https://forum.proxmox.com/threads/zfs-error-no-such-device-error-unknown-filesystem-entering-rescue-mode.75122/post-374799

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
---
v1->v2:
* unchanged
 bin/proxmox-boot-tool        | 26 ++++++++----
 proxmox-boot/zz-proxmox-boot | 81 +++++++++++++++++++++++++-----------
 2 files changed, 75 insertions(+), 32 deletions(-)

diff --git a/bin/proxmox-boot-tool b/bin/proxmox-boot-tool
index ceaf50e..219ea3b 100755
--- a/bin/proxmox-boot-tool
+++ b/bin/proxmox-boot-tool
@@ -150,14 +150,24 @@ init() {
 	echo "Mounting '$part' on '$esp_mp'."
 	mount -t vfat "$part" "$esp_mp"
 
-	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"
+	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 \
+			--boot-directory $esp_mp \
+			--target i386-pc \
+			--no-floppy \
+			--bootloader-id='proxmox' \
+			"/dev/$PKNAME"
+	fi
 	echo "Unmounting '$part'."
 	umount "$part"
 
diff --git a/proxmox-boot/zz-proxmox-boot b/proxmox-boot/zz-proxmox-boot
index b2469d2..42b0f01 100755
--- a/proxmox-boot/zz-proxmox-boot
+++ b/proxmox-boot/zz-proxmox-boot
@@ -75,18 +75,30 @@ update_esp_func() {
 		{ warn "creation of mountpoint ${mountpoint} failed - skipping"; return; }
 	mount "${path}" "${mountpoint}" || \
 		{ warn "mount of ${path} failed - skipping"; return; }
-	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"
+	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
+		warn "${path} contains no grub directory - skipping"
 		return
 	fi
-
 	warn "Copying and configuring kernels on ${path}"
 	copy_and_config_kernels "${mountpoint}"
-	remove_old_kernels "${mountpoint}"
+	if [ -d /sys/firmware/efi ]; then
+		remove_old_kernels_efi "${mountpoint}"
+	else
+		remove_old_kernels_legacy "${mountpoint}"
+		mount --bind "${mountpoint}" "/boot"
+		update-grub
+		umount /boot
+
+	fi
 
 	umount "${mountpoint}" || \
 		{ warn "umount of ${path} failed - failure"; exit 0; }
@@ -112,26 +124,33 @@ copy_and_config_kernels() {
 			continue
 		fi
 
-		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 -u --preserve=timestamps "${linux_image}" "${KERNEL_LIVE_DIR}/"
-		cp -u --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
+		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 -u --preserve=timestamps "${linux_image}" "${KERNEL_LIVE_DIR}/"
+			cp -u --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 -u --preserve=timestamps "${linux_image}" "${esp}/"
+			cp -u --preserve=timestamps "${initrd}" "${esp}/"
+		fi
 	done
 
 }
 
-remove_old_kernels() {
+remove_old_kernels_efi() {
 	esp="$1"
 
 	for kerneldir in "${esp}/${PMX_ESP_DIR}"/*; do
@@ -150,6 +169,20 @@ remove_old_kernels() {
 
 }
 
+remove_old_kernels_legacy() {
+	esp="$1"
+
+	for kernel in "${esp}/"vmlinuz-*; do
+		kver="$(echo "${kernel}" | sed -r "s#^${esp}/vmlinuz-(.+)\$#\\1#")"
+
+		echo "${BOOT_KVERS}" | grep -q "${kver}" && continue;
+		warn "	Removing old version ${kver}"
+		rm -rf "${esp}/vmlinuz-${kver}"
+		rm -rf "${esp}/initrd.img-${kver}"
+	done
+
+}
+
 set -- $DEB_MAINT_PARAMS
 mode="${1#\'}"
 mode="${mode%\'}"
-- 
2.20.1