#649217 grub-common: grub-mkconfig, an os-prober part generates multiple menuentry for same os

Package:
os-prober
Source:
os-prober
Description:
utility to detect other OSes on a set of drives
Submitter:
Mark Poks
Date:
2012-11-19 08:39:06 UTC
Severity:
normal
#649217#5
Date:
2011-11-18 19:31:34 UTC
From:
To:
hello.

grub-mkconfig gives me multimple times a same menu entry (of the same name in fact).
i have discovered linux-boot-prober is responsible for that (the output as follows):
    /dev/sda6:/dev/sda6::/vmlinuz:/initrd.img:root=/dev/sda6
    /dev/sda6:/dev/sda6::/vmlinuz:/initrd.img:root=/dev/sda6
    /dev/sda6:/dev/sda6::/boot/vmlinuz-2.6.30-2-amd64:/boot/initrd.img-2.6.30-2-amd64:root=/dev/sda6
    /dev/sda6:/dev/sda6::/vmlinuz:/initrd.img:root=/dev/sda6
    /dev/sda6:/dev/sda6::/vmlinuz:/initrd.img:root=/dev/sda6
    /dev/sda6:/dev/sda6::/boot/vmlinuz-2.6.30-2-amd64:/boot/initrd.img-2.6.30-2-amd64:root=/dev/sda6

i believe it's not ok and somebody will figure it out.

for now i am dealing with the problem through a little modification to /etc/grub.d/30_os-prober
by adding a " | sort | uniq" after "linux-boot-prober ${DEVICE}", but i think somebody should correct it, somehow

sincerelly,
markO

#649217#14
Date:
2012-11-15 22:38:11 UTC
From:
To:
Hi,
I am hit by this problem too. I am running Sid.
I debootstrap a second root filesystem into logical volume vg/deboot to
reinstall my original root filesystem. After re-installation of my system from
i386 to amd64 (deboostrap) I decided to save second root filesystem as second
"rescue" system.

  deboot     vg   -wi-a---   1.00g

It is ext4 including boot directory, important items follows:

bobek:/tmp# mount /dev/mapper/vg-deboot /mnt/

bobek:/mnt# ls -la vmlinuz initrd.img boot/
lrwxrwxrwx 1 root root   30 Nov 10 18:30 initrd.img -> /boot/initrd.img-3.2.0-4-amd64
lrwxrwxrwx 1 root root   26 Nov 10 18:30 vmlinuz -> boot/vmlinuz-3.2.0-4-amd64

boot/:
total 15864
drwxr-xr-x  2 root root     4096 Nov 10 18:34 .
drwxr-xr-x 24 root root     4096 Nov 10 21:58 ..
-rw-r--r--  1 root root  2100042 Oct 22 18:57 System.map-3.2.0-4-amd64
-rw-r--r--  1 root root   128869 Oct 22 18:57 config-3.2.0-4-amd64
-rw-r--r--  1 root root 11170966 Nov 10 18:34 initrd.img-3.2.0-4-amd64
-rw-r--r--  1 root root  2828288 Oct 22 18:54 vmlinuz-3.2.0-4-amd64


After update-grub I ended with 5 times menuentry for vg-deboot :(.

Investigating the problem I found a kernel/initrd is searched on mounted
partition. A partition is mounted using grub-mount preferably.
You can see this in the /usr/lib/linux-boot-probes/50mounted-tests
Grub-mount is in reality based on fuse.

bobek:/usr/lib/linux-boot-probes# grub-mount /dev/mapper/vg-deboot /mnt/1

bobek:/usr/lib/linux-boot-probes# mount|grep /mnt/1
grub-mount on /mnt/1 type fuse.grub-mount (rw,nosuid,nodev,relatime,user_id=0,group_id=0)


bobek:/usr/lib/linux-boot-probes# ls -la /mnt/1/{vmlinuz,initrd.img,boot/}
-r--r--r-- 0 root root 32979968 Nov 10 18:30 /mnt/1/initrd.img
-r--r--r-- 0 root root  2828288 Nov 10 18:30 /mnt/1/vmlinuz

/mnt/1/boot/:
total 37147
dr-xr-xr-x 0 root root        0 Nov 10 18:34 .
dr-xr-xr-x 0 root root        0 Jan  1  1970 ..
-r--r--r-- 0 root root  2100042 Oct 22 18:57 System.map-3.2.0-4-amd64
-r--r--r-- 0 root root   128869 Oct 22 18:57 config-3.2.0-4-amd64
-r--r--r-- 0 root root 32979968 Nov 10 18:34 initrd.img-3.2.0-4-amd64
-r--r--r-- 0 root root  2828288 Oct 22 18:54 vmlinuz-3.2.0-4-amd64

Symlinks are converted into regular files! :(.
A code in the /usr/lib/linux-boot-probes/mounted/90fallback:

    ...
    21			if [ -f "$kernfile" ] && [ ! -L "$kernfile" ]; then
    ...

There is a test on "$kernfile" and body of condition is processed only for
regular file - no symlink. And this is the problem with grub-mount.
The symlink in the root directory is not recognized and things are processed
several times.


bobek:/tmp/xxx# /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


Disabling grub-mount in ./50mounted-tests uncovers the problem.

bobek:/tmp/xxx# ./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


bobek:/tmp/xxx# diff /usr/lib/linux-boot-probes/50mounted-tests 50mounted-tests
37c37
< if type grub-mount >/dev/null 2>&1 && \
---


Cheers

#649217#19
Date:
2012-11-16 19:04:19 UTC
From:
To:
affects 638979 +os-prober
thanks

There is already a patch?
http://lists.gnu.org/archive/html/grub-devel/2012-10/msg00021.html
Cheers

#649217#24
Date:
2012-11-18 10:18:13 UTC
From:
To:
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.

#649217#29
Date:
2012-11-19 08:35:56 UTC
From:
To:
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