latest os-prober and updategrub development ...

Let’s go straight to the point! …

@arvidjaar ,

Your patch works here on a 12.1 UEFI dual-boot (actually triple boot if you count ELILO) with 2 SSDs and 2 ESPs.
I extended your original os-prober-UEFI-support.patch to ELILO boot loader detection (hope you don’t mind). You can see the new patch here: https://build.opensuse.org/package/view_file?file=os-prober-UEFI-support.patch&package=os-prober&project=home%3Aplease_try_again&rev=86ed45a1c45117ad7cc2f97ab8bbba33. I just created one more script that I called 10elilo in /usr/lib/os-probes/mounted/efi.

It seems to work. I’m planning to add an altermate os-prober script (that I will call 30_os-prober_alt) in updategrub. It actually already works and provides new features (such as sorting and skipping menu entries) on BIOS systems. I still need to write UEFI menu entries.

# **lsb_release -sd**
"openSUSE 12.1 (x86_64)"

# **uname -a**
Linux emma 3.1.10-1.16-desktop #1 SMP PREEMPT Wed Jun 27 05:21:40 UTC 2012 (d016078) x86_64 x86_64 x86_64 GNU/Linux

# **zypper info os-prober**
Loading repository data...
Reading installed packages...


Information for package os-prober:

Repository: PTA
Name: os-prober
Version: **1.56**-115.1
Arch: x86_64
Vendor: obs://build.opensuse.org/home:please_try_again
Installed: Yes
Status: up-to-date
Installed Size: 88.0 KiB
Summary: Probes disks on the system for installed operating systems
Description: 
This package detects other OSes available on a system and outputs the results
in a generic machine-readable format. Support for new OSes and Linux
distributions can be added easily.

# **lspart**
Dev  Boot Maj Min  Bsize/Start         Size    Fs                                    ID    Ver   Model/Mount

sdb         8  16        512 B       111.79 GiB                                     gpt    ata   ADATA_SSD_S510_120GB
sdb1        8  17         2048       319488  vfat  C12A7328-F81F-11D2-BA4B-00A0C93EC93B  FAT32   /boot/efi
sdb2        8  18       321536      4208640  swap  0657FD6D-A4AB-43C4-84E5-0933C84B4F4F      2 
sdb3        8  19      4530176     83892224  ext4  EBD0A0A2-B9E5-4433-87C0-68B6B72699C7    1.0   /export/nfs4, /
sdb4        8  20     88422400    146018304  ext4  EBD0A0A2-B9E5-4433-87C0-68B6B72699C7    1.0   /home, /export/nfs4/home

sda         8   0        512 B       111.79 GiB                                     gpt    ata   ADATA_SSD_S510_120GB
sda1        8   1         2048       204800  vfat  C12A7328-F81F-11D2-BA4B-00A0C93EC93B  FAT32 
sda2        8   2       206848       262144     -  E3C9E316-0B5C-4DB8-817D-F92DF00215AE      - 
sda3        8   3       468992    233971712  ntfs  EBD0A0A2-B9E5-4433-87C0-68B6B72699C7      - 

# **os-prober**
  No volume groups found
/dev/sda1@/EFI/Microsoft/Boot/bootmgfw.efi:Windows Boot Manager:Windows:efi
/dev/sdb1@/efi/SuSE/elilo.efi:ELILO Boot Manager:ELILO:efi

I guess we need someone with a talent for organization to pass these os-prober patches upstream (I’m not the right person).

That’s good. I’ll try to submit it upstream. We need first to push it into os-prober (Debian as far as I understand); submission to grub-devel was waved off as “not maintained by us”. Once this is accepted by os-prober we can submit patch for grub.d/30_os-prober to grub-devel again.

Could you PM me your E-Mail so I can add you to Cc?

I already submitted a couple patches in bug reports to openSUSE in the past months. The maintainer couldn’t apply them, because they were against a higher version than the one used in the release, and suggested that I apply to maintain os-prober in factory. Not sure I want to do that … and anyway I never apply to anything.

Please take a look at the other patches in my build. 3,4,5 were borrowed from Fedora (AFAIK already sent upstream). 6,7,8 were added by me.

  • os-prober-mountedtests-ufs2fix.patch
    fixes ufs2 mount and adds a DEBUG flag

  • os-prober-linuxdistro-ufsfix.patch
    excludes BSD slices from search for Linux distros.

  • os-prober-bsd-newprobesfix.patch
    adds detection for FreeBSD, NetBSD and openBSD kernels

I also fixed that kernel options truncate bug that affects version 1.49 (described here: http://forums.opensuse.org/english/get-technical-help-here/install-boot-login/479058-grub-2-boot-menu-boot-options-entry-field-missing.html#post2492063), but I don’t remember where. I probably removed my patch, as a similar one was added by Fedora.

I just built updategrub-2.0 which includes an alternate os-prober script. You can use it with the option -a and make the change permanent with the option -A. Actually it stays permanent until you use option -a again. Option -d below means “display only” (= don’t write the menu):


# updategrub -da
...
...
### BEGIN /etc/grub.d/30_os-prober_alt ###
  No volume groups found
Found Windows Boot Manager in /dev/sda1/EFI/Microsoft/Boot/bootmgfw.efi
menuentry "Windows Boot Manager" {
      insmod part_gpt
      insmod fat
      insmod search_fs_uuid
      insmod chain
      search --fs-uuid --no-floppy --set=root 5e17-7059
      chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
Found ELILO Boot Manager in /dev/sdb1/efi/SuSE/elilo.efi
menuentry "ELILO Boot Manager" {
      insmod part_gpt
      insmod fat
      insmod search_fs_uuid
      insmod chain
      search --fs-uuid --no-floppy --set=root 622e-560e
      chainloader (${root})/efi/SuSE/elilo.efi
}
### END /etc/grub.d/30_os-prober_alt ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
menuentry "Microsoft Windows x86_64 UEFI-GPT" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --no-floppy --set=root 5E17-7059
    chainloader (${root})/efi/Microsoft/Boot/bootmgfw.efi
}

menuentry "ELILO" {
    insmod part_gpt
    insmod fat
    insmod search_fs_uuid
    insmod chain
    search --fs-uuid --no-floppy --set=root 622E-560E
    chainloader (${root})/efi/SuSE/elilo.efi
}
### END /etc/grub.d/40_custom ###
...
....

The two entries here appear twice and are quite identical. The first two were added by /etc/grub.d/30_os-prober_alt. The last two ones got pasted from /etc/grub.d/40_custom - and were written there (once) by efi_chainload, an updategrub function. I might disable this function in the future. For now it is disable if updategrub is run with the option -a. Of course, the entries remain in /etc/grub.d/40_custom. That’s why they appear twice here. You can delete these entries if option -a finds your EFI boot loaders.

I’m not 100% sure that updategrub works on 12.2 EFI, as I don’t have such a system. It works on 12.1 EFI and 12.2 BIOS.

On BIOS systems it adds the ability to sort and skip menu entries (see man updateGrub2).

Notice that “updategrub” is a symlink to updateGrub2 on openSUSE since 12.2 and a symlink to updateLegacyGrub on previous versions. If you installed Grub2 under 12.1, you should change the symlink manually.

I wonder if it makes sense to extract vendor (direct \EFI subdirectory) to make it like “Found SuSE ELILO Boot Manager”.

I don’t know, but it doesn’t hurt for sure. It suffices to insert the vendor string in $long in 10elilo.

Also please notice this (in 30_os-prober_alt, installed by updategrub):

if ( echo ${DEVICE} | grep -q '@' ); then	 
      EFIPATH="`echo ${DEVICE} | cut -d '@' -f 2`"
      DEVNAME="`echo ${DEVICE} | cut -d '@' -f 1`"
      DEVICE="`echo ${DEVICE} | sed 's|@||'`"
      ON="in"		
  else
      ON="on"		
  fi	

  gettext_printf "Found %s %s %s
" "${LONGNAME}" "${ON}" "${DEVICE}" >&2

:wink:

Hope it is grammatically correct. I guess it is.

OK. I modified the patch to include the vendor name. But I guess they prefer to have “SUSE” (according to os-prober-SUSE.patch).


# os-prober     
  No volume groups found
/dev/sda1@/EFI/Microsoft/Boot/bootmgfw.efi:Windows Boot Manager:Windows:efi
/dev/sdb1@/efi/SuSE/elilo.efi:**SUSE** ELILO Boot Manager:ELILO:efi


# updategrub -da
### BEGIN /etc/grub.d/30_os-prober_alt ###
  No volume groups found
Found Windows Boot Manager in /dev/sda1/EFI/Microsoft/Boot/bootmgfw.efi
menuentry "Windows Boot Manager" {
      insmod part_gpt
      insmod fat
      insmod search_fs_uuid
      insmod chain
      search --fs-uuid --no-floppy --set=root 5e17-7059
      chainloader (${root})/EFI/Microsoft/Boot/bootmgfw.efi
}
Found **SUSE** ELILO Boot Manager in /dev/sdb1/efi/SuSE/elilo.efi
menuentry "**SUSE** ELILO Boot Manager" {
      insmod part_gpt
      insmod fat
      insmod search_fs_uuid
      insmod chain
      search --fs-uuid --no-floppy --set=root 622e-560e
      chainloader (${root})/efi/SuSE/elilo.efi
}
### END /etc/grub.d/30_os-prober_alt ###

Here’s the new 10elilo:

# cat /usr/lib/os-probes/mounted/efi/10elilo

#!/bin/sh
# Detects ELILO bootloader on a EFI System Partition

. /usr/share/os-prober/common.sh

efi="$1"

found=

elilo=`find $1 -name "elilo.efi"`
if  -n "$elilo" ]; then
        bdir=`dirname $elilo`
        bdir=`basename $bdir`
        vendor=$(echo $bdir | sed 's|SuSE|SUSE|')
        long="${vendor} ELILO Boot Manager"
        short="ELILO"
        path=${bdir}/elilo.efi
        found=true
fi  

if  -n "$found" ]; then
        label="$(count_next_label "$short")"
        result "${path}:${long}:${label}"
fi
exit 0

Other changes I made for BIOS based systems:

I’d prefer this for lsb info:


# os-prober
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
/dev/sda6:Ubuntu 12.04.1 LTS **(precise)**:Ubuntu:linux
/dev/sda9:openSUSE 12.2 (x86_64):SUSE:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

to that:


# os-prober 
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
/dev/sda6:Ubuntu 12.04.1 LTS **(12.04)**:Ubuntu:linux
/dev/sda9:openSUSE 12.2 (x86_64):SUSE:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

It can be achieved with the following patch:

Index: os-prober/os-probes/mounted/common/40lsb
===================================================================
--- os-prober.orig/os-probes/mounted/common/40lsb
+++ os-prober/os-probes/mounted/common/40lsb
@@ -19,17 +19,20 @@
        exit 1
 fi
 
+codename=$(lsb_field "$file" DISTRIB_CODENAME)
 release=$(lsb_field "$file" DISTRIB_RELEASE)
 if  -z "$release" ]; then
        release=$(lsb_field "$file" DISTRIB_CODENAME)
 fi
 description=$(lsb_field "$file" DISTRIB_DESCRIPTION)
 if  -z "$description" ]; then
-       description=$(lsb_field "$file" DISTRIB_CODENAME)
+       description=$codename
 fi
 
 if  -n "$description" ]; then
-       if  -n "$release" ]; then
+       if  -n "$codename" ]; then
+               long="$description ($codename)"
+       elif  -n "$release" ]; then
                long="$description ($release)"
        else
                long="$description"

I would also like to display the codename for openSUSE to get a more consistant output with other distros, meaning show this:

 # os-prober
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
/dev/sda6:Ubuntu 12.04.1 LTS (precise):Ubuntu:linux
/dev/sda9:**openSUSE 12.2 x86_64 (Mantis)**:SUSE:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

rather than:

# os-prober
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
/dev/sda6:Ubuntu 12.04.1 LTS (precise):Ubuntu:linux
/dev/sda9:**openSUSE 12.2 (x86_64)**:SUSE:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

It could be done with a modified os-prober-SUSE.patch:

Index: os-prober/os-probes/mounted/common/90linux-distro
===================================================================
--- os-prober.orig/os-probes/mounted/common/90linux-distro
+++ os-prober/os-probes/mounted/common/90linux-distro
@@ -80,8 +80,8 @@
                short="RedHat"
                long="$(cat "$dir/etc/redhat-release")"
        elif  -e "$dir/etc/SuSE-release" ]; then
-               short="SuSE"
-               long="$(head -n 1 "$dir/etc/SuSE-release")"
+               short="SUSE"
+               long="$(sed '1s/()]//g;s/CODENAME *= *\(.*\)/ (\1)/;/VERSION/d' $dir/etc/SuSE-release | tr -d "
")"
        elif  -e "$dir/etc/gentoo-release" ]; then
                short="Gentoo"
                long="$(cat "$dir/etc/gentoo-release")"

I have been wondering why I could not detect some BSD installs under openSUSE (with os-prober 1.56 + ufs support and probes for FreeBSD, openBSD and NetBSD) …


# os-prober
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda13:Fedora release 16 (Verne):Fedora:linux
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
/dev/sda6:Ubuntu 12.04.1 LTS (precise):Ubuntu:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

while I was able to see the missing ones under Ubuntu (+ os-prober 1.5.1 and the same probes for FreeBSD, openBSD and NetBSD):


# os-prober
  No volume groups found
/dev/sda1:Windows NT/2000/XP (loader):Windows:chain
/dev/sda13:Fedora release 16 (Verne):Fedora:linux
/dev/sda15:Debian GNU/Linux (squeeze/sid):Debian:linux
**/dev/sda2:OpenBSD:OpenBSD 4.7:openbsd**
**/dev/sda3:FreeBSD:FreeBSD 7.2-RELEASE:freebsd**
/dev/sda6:Ubuntu 12.04.1 LTS (precise):Ubuntu:linux
/dev/sdb1:Windows NT/2000/XP (loader):Windows1:chain
/dev/sdb3:FreeBSD:FreeBSD 8.1-RELEASE:freebsd
/dev/sdb6:Arch Linux (rolling):archlinux:linux

The BSD probes mentioned here are the follwoing scripts included in my os-prober build:

# find /usr/lib/os-probes/ -name "*bsd"
/usr/lib/os-probes/mounted/85netbsd
/usr/lib/os-probes/mounted/85openbsd
/usr/lib/os-probes/mounted/85freebsd

I replaced /usr/lib/os-probes/50mounted-tests in openSUSE (a script I already patched to add ufs2 support) with the one from Ubuntu (that I also already patched but I don’t remember how :O). Hummm, I’m starting to suspect that ufs1 support doesn’t work anymore in my version (as it used to). Anyway, I prefer Ubuntu’s version. Here’s the diff:


# diff -u 50mounted-tests.dist 50mounted-tests
--- 50mounted-tests.dist        2012-10-23 03:29:59.765009276 -0700
+++ 50mounted-tests     2012-10-23 03:39:03.608696534 -0700
@@ -66,23 +66,34 @@
 else
        ro_partition "$partition"
        for type in $types $delaytypes; do
-               opt="ro"
-               if  "$ufstype" ] ; then 
-                       opt="ro,ufstype=ufs2"
-               fi
-               if  "$OSPDEBUG" ] ; then 
-                       if mount -o "$opt" -t "$type" "$partition" "$tmpmnt"; then
-                               debug "mounted as $type filesystem"
-                               mounted=1
-                               break
-                       fi
+               if  "$type" = ufs ]; then
+                       for ufstype in ufs2 44bsd; do
+                               if mount -o ro,ufstype=$ufstype -t "$type" "$partition" "$tmpmnt" 2>/dev/null; then
+                                       mounted=1
+                               fi
+                       done
                else
-                       if mount -o "$opt" -t "$type" "$partition" "$tmpmnt" 2>/dev/null; then
-                               debug "mounted as $type filesystem"
+                       if mount -o ro -t "$type" "$partition" "$tmpmnt" 2>/dev/null; then
                                mounted=1
-                               break
                        fi
                fi
+
+               if  "$mounted" ]; then
+                       debug "mounted as $type filesystem"
+                       case "$type" in
+                           btrfs)
+                               if  -x "$tmpmnt/@/lib" ] && \
+                                  ! mount --bind "$tmpmnt/@" "$tmpmnt"; then
+                                       warn "failed to mount btrfs subvolume @ on $partition"
+                                       if ! umount $tmpmnt; then
+                                               warn "failed to umount $tmpmnt"
+                                       fi
+                                       mounted=
+                               fi
+                               ;;
+                       esac    
+                       break
+               fi
        done
 fi
 
@@ -95,6 +106,15 @@
                                if ! umount "$tmpmnt"; then
                                        warn "failed to umount $tmpmnt"
                                fi
+                               case "$type" in
+                                   btrfs)
+                                       # umount to account for the bind-mount
+                                       if  -x "$tmpmnt/@/lib" ] && \
+                                          ! umount $tmpmnt; then
+                                               warn "failed to umount $tmpmnt"
+                                       fi
+                                       ;;
+                               esac
                                rmdir "$tmpmnt" || true
                                exit 0
                        fi

Notice that since I patched both of these files, this diff is unusable as a patch, but it shows the differences between both scripts.

I read in some Changelog that ufs support had been removed and I wonder if this is not what was meant. This (apparently older) 50mounted-tests also issues some warning about btrfs, which don’t seem to be relevant anymore. I’m going to modify my patch for ufs anyway, because I want os-prober to detect these OSes and add them to Grub menu under openSUSE as well (updateGrub2 -a takes care of that).