Bug#638979: grub-mount, os-prober and symlinks traversal failures

Václav Ovsík vaclav.ovsik at i.cz
Mon Nov 19 08:35:56 UTC 2012


On Sun, Nov 18, 2012 at 10:18:13AM +0000, Colin Watson wrote:
> On Fri, Nov 16, 2012 at 08:04:19PM +0100, Václav Ovsík wrote:
> > affects 638979 +os-prober
> > thanks
> > 
> > There is already a patch?
> > http://lists.gnu.org/archive/html/grub-devel/2012-10/msg00021.html
> 
> No, that fixes a regression in 2.00 which caused any
> symlink-to-directory encountered in a directory's contents to cause the
> directory to appear as though it were empty.  That bug was not present
> in 1.99, where this bug was originally reported in Debian, so please
> don't conflate them.

Sorry for my laziness and the low effort to understand a thread I gave
a link :(.

To prove I can give a more effort to this thing I sit down to change
os-prober code to comply with grub-mount feature (symlink behaviour).

A first level of problem is duplicating output of the same kernel/initrd
filename pairs. Duplicates appears because the patterns tried are not
disjunctive at the line 15 of /usr/lib/linux-boot-probes/mounted/90fallback.

for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \
                "/boot/vmlinux*" "/vmlinuz*" "/vmlinux*" "/kernel-*" "/boot/kernel-*"; do

I don't know why there are pattern pairs /vmlinuz and "/vmlinuz*" and so
on. Shell wild-card "/vmlinuz*" is expanded in the alphabetical order,
so potential /vmlinuz alone is expanded always first if exists. I'm not
certain the reasoning... aha in between is /boot/vmlinuz, so if both
exists /vmlinuz and /boot/vmlinuz, they appear in that order
(/boot/vmlinuz appears before /vmlinuz<something>).


...initrd patterns at the line 27...:
                        initrdname=$(echo "$kernfile" | sed "s/vmlinu[zx]/initrd\*/")
                        # Yellow Dog Linux appends .img to it.
                        initrdname1="${initrdname}.img"

The following patch removes duplicates from expanded patterns of kernels and
initrd images:


--- /usr/lib/linux-boot-probes/mounted/90fallback~	2012-11-18 20:40:05.050334822 +0100
+++ /usr/lib/linux-boot-probes/mounted/90fallback	2012-11-18 21:16:50.846268406 +0100
@@ -21,6 +21,8 @@
 	fi
 	for kernfile in $(eval ls "$mpoint$kernpat" 2>/dev/null); do
 		kernbasefile=$(echo "$kernfile" | sed "s!^$mpoint!!")
+		echo "$kernfile_seen" | fgrep -q " $kernbasefile " && continue
+		kernfile_seen="$kernfile_seen $kernbasefile "
 		if [ -f "$kernfile" ] && [ ! -L "$kernfile" ]; then
 			initrdname=$(echo "$kernfile" | sed "s/vmlinu[zx]/initrd\*/")
 			# Yellow Dog Linux appends .img to it.
@@ -35,7 +37,7 @@
 			# And Gentoo's also
 			initrdname4=$(echo "$kernfile" | sed "s/kernel/initramfs\*/")
 			foundinitrd=0
-			for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null); do
+			for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null | sort | uniq); do
 				if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then
 					initrd=$(echo "$initrd" | sed "s!^$mpoint!!")
 					result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition"

Before the patch:

bobek:~# /usr/lib/linux-boot-probes/50mounted-tests /dev/mapper/vg-deboot 
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/boot/vmlinuz-3.2.0-4-amd64:/boot/initrd.img-3.2.0-4-amd64:root=/dev/dm-23
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23

After the patch:

bobek:~# /usr/lib/linux-boot-probes/50mounted-tests /dev/mapper/vg-deboot 
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/boot/vmlinuz-3.2.0-4-amd64:/boot/initrd.img-3.2.0-4-amd64:root=/dev/dm-23

I hope the above change is worth doing anyway.

We can go further and try to identify the identical file's with
different filenames. (This problem is introduced by grub-mount behaviour
on symlinks.)

--- /usr/lib/linux-boot-probes/mounted/90fallback~zito1	2012-11-19 01:04:58.817863969 +0100
+++ /usr/lib/linux-boot-probes/mounted/90fallback	2012-11-19 01:49:23.941785223 +0100
@@ -9,6 +9,11 @@
 mpoint="$3"
 type="$4"
 
+getmd5()
+{
+	md5sum "$1" | cut -f1 -d ' '
+}
+
 mappedpartition=$(mapdevfs "$partition" 2>/dev/null) || mappedpartition="$partition"
 
 exitcode=1
@@ -24,6 +29,7 @@
 		echo "$kernfile_seen" | fgrep -q " $kernbasefile " && continue
 		kernfile_seen="$kernfile_seen $kernbasefile "
 		if [ -f "$kernfile" ] && [ ! -L "$kernfile" ]; then
+			kernmd5=$(getmd5 "$kernfile")
 			initrdname=$(echo "$kernfile" | sed "s/vmlinu[zx]/initrd\*/")
 			# Yellow Dog Linux appends .img to it.
 			initrdname1="${initrdname}.img"
@@ -39,6 +45,13 @@
 			foundinitrd=0
 			for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null | sort | uniq); do
 				if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then
+					initrdmd5=$(getmd5 "$initrd")
+					pairmd5="$kernmd5:$initrdmd5"
+					if echo "$pairmd5_seen" | fgrep -q " $pairmd5 "; then
+						foundinitrd=1
+						continue
+					fi
+					pairmd5_seen="$pairmd5_seen $pairmd5 "
 					initrd=$(echo "$initrd" | sed "s!^$mpoint!!")
 					result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition"
 					exitcode=0

Adding above change causes:

bobek:~# /usr/lib/linux-boot-probes/50mounted-tests /dev/mapper/vg-deboot 
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/vmlinuz:/initrd.img:root=/dev/dm-23


Maybe better is to get the result with files under /boot directory using
reordered items:


--- 90fallback~zito2	2012-11-19 01:54:11.357776732 +0100
+++ 90fallback	2012-11-19 01:57:53.389770171 +0100
@@ -17,8 +17,8 @@
 mappedpartition=$(mapdevfs "$partition" 2>/dev/null) || mappedpartition="$partition"
 
 exitcode=1
-for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \
-	        "/boot/vmlinux*" "/vmlinuz*" "/vmlinux*" "/kernel-*" "/boot/kernel-*"; do
+for kernpat in /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" "/boot/vmlinux*" "/boot/kernel-*" \
+       		/vmlinuz /vmlinux "/vmlinuz*" "/vmlinux*" "/kernel-*"; do
 	if echo "$kernpat" | grep -q boot/; then
 		kernbootpart="$bootpart"
 	else

Now the result is:

bobek:~# /usr/lib/linux-boot-probes/50mounted-tests /dev/mapper/vg-deboot 
/dev/mapper/vg-deboot:/dev/mapper/vg-deboot::/boot/vmlinuz-3.2.0-4-amd64:/boot/initrd.img-3.2.0-4-amd64:root=/dev/dm-23

This change seems to me better for Debian. I'm not certain about intent
of original writer about ordering items (other probed systems), so maybe
this is not acceptable.

The root file-system root=/dev/dm-23 is resolved inappropriately. I must
change kernel argument root=/dev/dm-23 to root=/dev/mapper/vg-deboot in
the grub by hand to boot. This is another issue, witch should have
different bug number so I'm not solving it there.

Hope the attached complete diff is helpful a bit.

Sorry for my English :(.
Kindly regards
-- 
Zito
-------------- next part --------------
A non-text attachment was scrubbed...
Name: os-prober-duplicates.diff
Type: text/x-diff
Size: 2108 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-grub-devel/attachments/20121119/cce89932/attachment.diff>


More information about the Pkg-grub-devel mailing list