[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#820838: os-prober: 40grub2 does not handle multiple initrd paths



Control: unmerge 820838 838177
Control: forwarded 820838 https://salsa.debian.org/installer-team/os-prober/-/merge_requests/8
Control: retitle 838177 grub-common: grub.d/30_os-prober does not handle multiple initrd paths
Control: reassign 838177 grub-common 2.02+dfsg1-20
Control: forwarded 838177 https://savannah.gnu.org/bugs/index.php?47681

A recap of this bug for maintainers, since it has been a while:

In Arch Linux and its derivatives like Manjaro, instead of concatenating
CPU microcode and early user-space into a single initrd blob like we
do in Debian, the CPU microcode and the rest of early user-space are
supplied as two separate initrd archives. When Debian's grub integration
scripts detect other operating systems, they successfully identify Arch
Linux and add it to Debian's grub menu, but only the first initrd gets
added to grub.cfg, resulting in boot failure for the Arch menu entry
(because the first initrd happens to be the CPU microcode, so early
user-space is missing).

I can reproduce this on a Debian 11 test system that dual-boots into Arch,
by running update-grub and grub-install while booted into Debian 11.

Solving this requires changes in two packages: os-prober and grub-common.
I have verified that with the patches attached here, Debian's grub menu
boots Arch successfully. Unfortunately, I think we might be in a situation
where grub is waiting for os-prober and os-prober is waiting for grub.

For os-prober, the patch supplied by "General Chaos" in 2016 seems good.
I attach a clean version without the change to the Maintainer field, and
a follow-up patch that just reindents it to match the prevailing style.
Please see attached os-prober-*.patch or the merge request
<https://salsa.debian.org/installer-team/os-prober/-/merge_requests/8>.

On Thu, 23 Feb 2017 at 10:56:22 +0100, Johannes Rohr wrote:
> I've tested the patch. The initrd stanza generated is not totally correct:
> 
> іnitrd /boot/intel-ucode.img^/boot/initramfs-linux-pf.img
> 
> (note the ^ where there should be a blank)

This is a bug in integration scripts supplied by grub2: after
modifying os-prober to be able to emit more than one initrd, it
is also necessary to modify the corresponding script in grub2 to
be able to consume more than one initrd. "General Chaos" proposed
a patch upstream in 2016, which upstream said would be OK to apply
after os-prober was fixed, but there was never a Debian bug report
specifically for this. I'm repurposing 838177 to be that Debian
bug report. Please see attached grub2-*.patch or the merge request
<https://salsa.debian.org/grub-team/grub/-/merge_requests/26>.

At this stage in the freeze these changes seem unlikely to make it into
Debian 11, but it would be great if they can be landed at the beginning
of the Debian 12 cycle, or perhaps even incorporated into a Debian 11
point release.

Thanks,
    smcv
>From 1f982e2a7c35e14d5a92c76db998afafd1bd9e87 Mon Sep 17 00:00:00 2001
From: General Chaos <debianbugs@toeai.com>
Date: Tue, 12 Apr 2016 22:28:52 +0000
Subject: [PATCH] os-prober: Allow initrd to contain spaces

linux-boot-prober produces structured output with newline-terminated rows
representing kernels, each with colon-delimited columns. We translate
this into a sequence of space-separated words representing kernels,
each containing colon-delimited fields where spaces are represented by
carets.

When we parse each of those words into colon-delimited fields, if the
field could conceivably contain spaces then we need to translate
carets back into spaces. We did this for label and parameters, but not
for the initrd.

In particular, when CPU microcode is installed on Arch Linux or its
derivatives, they write CPU microcode into one initrd archive and the
rest of early user-space into another, instead of concatenating the
archives into a single file like Debian derivatives do. To boot Arch
successfully from the grub menu, we need to add all of their initrds
to the grub menu entry (detecting this situation requires an os-prober
patch, for which see <https://bugs.debian.org/820838>).

[Commit message added by Simon McVittie <smcv@collabora.com>]

Bug: https://savannah.gnu.org/bugs/index.php?47681
Bug-Debian: https://bugs.debian.org/838177
Forwarded: https://savannah.gnu.org/bugs/index.php?47681
Closes: #838177
---
 util/grub.d/30_os-prober.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in
index da5f28876..d0609d9a4 100644
--- a/util/grub.d/30_os-prober.in
+++ b/util/grub.d/30_os-prober.in
@@ -243,7 +243,7 @@ EOF
         LBOOT="`echo ${LINUX} | cut -d ':' -f 2`"
         LLABEL="`echo ${LINUX} | cut -d ':' -f 3 | tr '^' ' '`"
         LKERNEL="`echo ${LINUX} | cut -d ':' -f 4`"
-        LINITRD="`echo ${LINUX} | cut -d ':' -f 5`"
+        LINITRD="`echo ${LINUX} | cut -d ':' -f 5 | tr '^' ' '`"
         LPARAMS="`echo ${LINUX} | cut -d ':' -f 6- | tr '^' ' '`"
 
         if [ -z "${LLABEL}" ] ; then
-- 
2.32.0

>From 7641c2da0c81f78c5f2ee2a66a1c21350cab03fc Mon Sep 17 00:00:00 2001
From: General Chaos <debianbugs@toeai.com>
Date: Tue, 12 Apr 2016 23:08:14 +0000
Subject: [PATCH 1/2] Handle multiple initrd paths, as used in some distros

Manjaro uses two paths on the initrd line,
e.g.:

    initrd /boot/intel-ucode.img /boot/initramfs-4.4-x86_64.img

In addition to this change, handling this correctly when updating the
grub menu requires fixing <https://bugs.debian.org/838177> in grub,
so that it can consume the output of this os-prober version
successfully.

[Commit message added by Simon McVittie <smcv@collabora.com>]

Closes: #820838
---
 linux-boot-probes/mounted/common/40grub2 | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
index 885614e..c7f63af 100755
--- a/linux-boot-probes/mounted/common/40grub2
+++ b/linux-boot-probes/mounted/common/40grub2
@@ -78,11 +78,22 @@ parse_grub_menu () {
 				fi
 			;;
 			initrd)
-				initrd="$(echo "$2" | sed 's/(.*)//')"
+				shift
+				initrd=""
+				for initrd_path in "$@"
+				do
+				# sed hack, as above
+				initrd_path="$(echo "$initrd_path" | sed 's/(.*)//')"
 				# Initrd same.
 				if [ "$partition" != "$bootpart" ]; then
-					initrd="/boot$initrd"
+					initrd_path="/boot$initrd_path"
 				fi
+				if [ -z "$initrd" ]; then
+					initrd="$initrd_path"
+				else
+					initrd="$initrd $initrd_path"
+				fi
+				done
 			;;
 			"}")
 				entry_result
-- 
2.32.0

>From 53b920e106f13acf87ef8a275161e20f94feeb8a Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 9 Jun 2021 12:39:14 +0100
Subject: [PATCH 2/2] Re-indent previous commit

No functional changes.
---
 linux-boot-probes/mounted/common/40grub2 | 25 ++++++++++++------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
index c7f63af..e333a66 100755
--- a/linux-boot-probes/mounted/common/40grub2
+++ b/linux-boot-probes/mounted/common/40grub2
@@ -80,19 +80,18 @@ parse_grub_menu () {
 			initrd)
 				shift
 				initrd=""
-				for initrd_path in "$@"
-				do
-				# sed hack, as above
-				initrd_path="$(echo "$initrd_path" | sed 's/(.*)//')"
-				# Initrd same.
-				if [ "$partition" != "$bootpart" ]; then
-					initrd_path="/boot$initrd_path"
-				fi
-				if [ -z "$initrd" ]; then
-					initrd="$initrd_path"
-				else
-					initrd="$initrd $initrd_path"
-				fi
+				for initrd_path in "$@"; do
+					# sed hack, as above
+					initrd_path="$(echo "$initrd_path" | sed 's/(.*)//')"
+					# Initrd same.
+					if [ "$partition" != "$bootpart" ]; then
+						initrd_path="/boot$initrd_path"
+					fi
+					if [ -z "$initrd" ]; then
+						initrd="$initrd_path"
+					else
+						initrd="$initrd $initrd_path"
+					fi
 				done
 			;;
 			"}")
-- 
2.32.0


Reply to: