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

Re: [PATCH] various os-prober patches



Hi debian-boot@,

Please find below a nice mail from Thierry, summarizing a number of
changes that would be great to see merged into os-prober.

If anyone wants to volunteer to coordinate merging those changes into
Debian, to fix all the bugs©®™ for us and our downstream, that would be
great!

Thierry, if nobody steps up in the upcoming weeks, you're welcome to
ping me back; I might try and allocate company time to it, but “when”
would be the big question…


Cheers,
-- 
Cyril Brulebois (kibi@debian.org)            <https://debamax.com/>
D-I release manager -- Release team member -- Freelance Consultant


Thierry Vignaud <thierry.vignaud@gmail.com> (2020-04-02):
> Hi
> There's quite some patches for os-prober that lurks in Mageia, Fedora &
> SUSE packages and it looks like some patches just remain in
> https://bugs.debian.org/cgi-bin/pkgreport.cgi?repeatmerged=no&src=os-prober
> 
> So here's my attempt at getting some of them merged, which would reduce the
> burden on us distro packagers:
> (more chlog and/or comments may be find in them)
> 
> os-prober-SUSE.patch: : Fix spelling of SUSE aj@suse.de
> 
> os-prober-1.49-fix-grub2.cfg-parsing.patch: Fix several problems in parsing
> of grub.cfg by linux-boot-probes/mounted/40grub2 [bnc#796919]
> 
> 1. Look for /boot/grub2-efi/grub.cfg as well (openSUSE 12.2)
> 
> 2. It checked for literal "(on /dev/.*)" to filter out menu entries
> added by another os-prober on target system. But grub.cfg now includes
> TRANSLATED strings, so this check will fail if grub.cfg was created in
> non-English locale. Use menu entry ID to check whether entry was added
> by os-prober (it always starts with osprober-).
> 
> os-prober-probe-MD-devices.patch: Probe also unpartitioned Linux MD devices
> (bnc#811006)
> 
> os-prober-linux-secure-boot.patch: Detect linux secure boot entries too
> (bnc#810912)
> 
> 
> os-prober-btrfsfix.patch: btrfs support from Fedora (rediffed)
> 
> os-prober-EFI-openSUSEfy.patch: Small cosmetic changes to ensure UEFI
> scripts keep content
> after upstream merged (slightly outdated) version of them.
> - retain ELILO vendor prefix in case someone is really using it
> - comment in 05efi is obviously wrong
> 
> os-prober-accept-ESP-on-IMSM.patch: accept ESP on IMSM MD raid (bnc#818871)
> 
> os-prober-dont-load-all-fs-module-and-dont-test-mount.patch: don't modprobe
> all file system modules and don't test mount on unknown partition
> (bnc#851722)
> 
> os-prober-fix-btrfs-subvol-mounted-tests.patch: fix os-prober entries for
> distro on btrfs root-fs not created (bnc#846003)
> 
> os-prober-skip-part-on-multipath.patch: fix os-prober creates many
> unusuable entries on multipath disk (bnc#875327)
> 
> Improve-btrfs-handling-on-os-probing-for-grub2.patch: fix os-prober fails
> to detect other SLES12 installation (bsc#892364)
> 
> os-prober-btrfs-absolute-subvol.patch: fix os-prober mount error, no such
> file or directory (bsc#931955)
> the do_unmount has to be skipped for btrfs as it removes tmp mount point of
> which btrfs is making use (bsc#1024196)
> 
> os-prober-40grub-check-grub2.patch: also skip legacy grub if
> /boot/grub2/grub.cfg is present
> 
> os-prober-btrfs-snapshot-detection.patch: OpenSuSE patch: detect os on
> default subvolume in snapshot (bsc#954225)
> 
> os-prober-btrfs-always-detect-default.patch: os-prober update broke Linux
> detection (bsc#957018)
> 
> os-prober-linux-distro-avoid-expensive-ld-file-test.patch: y2base runs at
> 100% cpu busy from beginning in installation of files to completion
> (bsc#953987)
> 
> os-prober-linux-distro-parse-os-release.patch: Leap does not recognize
> Tumbleweed any more (bsc#997465)
> 
> Improve slow os-prober (rhbz#875356)
> (forward port of https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=694668)
> os-prober-factor-out-logger.patch
> os-prober-factored-logger-efi-fix.patch
> 
> os-prober-umount-fix.patch:  Fix separate /usr partitions for usrmove
> distros (bug #1044760)
> - Fix umount error when directory is temporarily busy (bug #903906)
> 
> os-prober-grepfix.patch: Fix parsing grub2's initrd/linux variations,
> rhbz#1108344
> 
> os-prober-gentoo-fix.patch: - Support a case where a kernel named vmlinuz/x
> is used under Gentoo, bug #1223237
> 
> os-prober-mounted-partitions-fix.patch: Fix a bug in recent btrfs patch
> when an extended partition is examined (H.J. Lu) (bug #906847)
>     - Fix naming of /boot partitions according to their fstab entry (bug
> #893472)
>     - Don't generate .btrfsfix files which will be included in final rpm
>     - Fix wrong boot partition set by linux-boot-prober when / and /boot are
>       mounted (bug #906886)
>     - Factor out 'logger', so that it is run once and logs are piped to it
> (John
>       Reiser) (bug #875356)
> 
> os-prober-bootpart-name-fix.patch:     Fix parsing grub2's initrd/linux
> variations, rhbz #1108344
> 
> os-prober-no-dummy-mach-kernel.patch: Fix using grep for searching binary
> files, fixes #1172405.
>     - Use shell string processing rather than 'basename' (#875356)
>     - Make it possible to disable logging debug messages by assigning a
> value to
>       OS_PROBER_DISABLE_DEBUG environment variable (#893997).
>     - Detect multi btrfs pools/volumes (#888341)
> 
> os-prober-mdraidfix.patch:  Add mdraid detection fix patch
> 
> Can you merge at least part of them in next os-prober release in order to
> reduce our workload rebase on new releases and in order to share fixes with
> all users?
> Thanks








> Index: os-prober-1.76/os-probes/common/50mounted-tests
> ===================================================================
> --- os-prober-1.76.orig/os-probes/common/50mounted-tests
> +++ os-prober-1.76/os-probes/common/50mounted-tests
> @@ -49,19 +49,13 @@ elif [ -z "$types" ]; then
>  		debug "$1 is a LUKS partition; skipping"
>  		exit 0
>  	fi
> -	for type in $(grep -v nodev /proc/filesystems); do
> -		# hfsplus filesystems are mountable as hfs. Try hfs last so
> -		# that we can tell the difference.
> -		if [ "$type" = hfs ]; then
> -			delaytypes="${delaytypes:+$delaytypes }$type"
> -		elif [ "$type" = fuseblk ]; then
> -			if type ntfs-3g >/dev/null 2>&1; then
> -				types="${types:+$types }ntfs-3g"
> -			fi
> -		else
> -			types="${types:+$types }$type"
> -		fi
> -	done
> +
> +	# Simply skip such partition is better than trying to detect
> +	# it by blinded test mounts with all kinds of kernel file system,
> +	# that would lead to unwanted consequence like kernel oops and
> +	# risk to corrupt your system and data.
> +	debug "$1 is a partition without file system; skipping"
> +	exit 0
>  fi
>  
>  tmpmnt=/var/lib/os-prober/mount
> Index: os-prober-1.76/os-probes/init/common/10filesystems
> ===================================================================
> --- os-prober-1.76.orig/os-probes/init/common/10filesystems
> +++ os-prober-1.76/os-probes/init/common/10filesystems
> @@ -1,39 +1,19 @@
>  #!/bin/sh
>  # Make sure filesystems are available.
> -set +e	# ignore errors from modprobe
> -
> -FILESYSTEMS='ext2 ext3 ext4 xfs jfs msdos vfat ntfs minix hfs hfsplus qnx4 ufs btrfs'
> -# fuse is needed to make grub-mount work.
> -FILESYSTEMS="$FILESYSTEMS fuse"
> -# The Ubuntu kernel udebs put a number of filesystem modules in
> -# fs-{core,secondary}-modules. It's fairly cheap to check for these too.
> -FILESYSTEMS="$FILESYSTEMS fs-core fs-secondary"
> -
> -if [ ! -e /var/lib/os-prober/modules ]; then
> -	# Check for anna-install to make it easier to use os-prober outside
> -	# d-i.
> -	if type anna-install >/dev/null 2>&1 && [ -d /lib/debian-installer ]; then
> -		for fs in $FILESYSTEMS; do
> -			ANNA_QUIET=1 DEBIAN_FRONTEND=none \
> -			log-output -t os-prober \
> -				anna-install "$fs-modules" || true
> -		done
> -		depmod -a >/dev/null 2>&1 || true
> -	fi
> -
> -	for fs in $FILESYSTEMS; do
> -		case "$fs" in
> -			fs-*)
> -				;;
> -			*)
> -				modprobe "$fs" 2>/dev/null | logger -t os-prober
> -				;;
> -		esac
> -	done
> -
> -	# We only want to keep this state inside d-i, so this is as good a
> -	# check as any.
> -	if type anna-install >/dev/null 2>&1 && [ -d /lib/debian-installer ]; then
> -		touch /var/lib/os-prober/modules
> -	fi
> -fi
> +set -e                                                                        
> +                                                                               
> +# Make sure fuse is available for grub2-mount                                 
> +# As long as we use grub2-mount, we use grub2's own file system modules       
> +# to mount the partitiion and the operation don't require kernel support      
> +# other than fuse.                                                            
> +if ! cat /proc/filesystems | grep nodev | cut -f2 | grep -qw fuse; then       
> +       modprobe fuse 2>&1 | logger -t os-prober                               
> +fi                                                                            
> +# Regarding file systems not supported by grub2, or systems simply don't      
> +# have grub2-mount, will use linux 'mount' utility. This will require         
> +# kernel file system module to work, but still we don't need to modprobe      
> +# all of them before mount, because mount() syscall will take care of it      
> +# by __request_module the needed kernel module and we should leave it do      
> +# that for us in order to have only needed modules get loaded.                
> +#                                                                             
> +# Still if you want any kernel module loaded, add them here.

> Index: os-prober-1.76/os-probes/common/50mounted-tests
> ===================================================================
> --- os-prober-1.76.orig/os-probes/common/50mounted-tests
> +++ os-prober-1.76/os-probes/common/50mounted-tests
> @@ -65,10 +65,40 @@ fi
>  
>  mounted=
>  
> +if [ "$types" = btrfs ]; then
> +	partition="$BTRFSDEV"
> +fi
> +
> +if type grub2-mount >/dev/null 2>&1 && \
> +   type grub2-probe >/dev/null 2>&1 && \
> +   grub2-mount "$partition" "$tmpmnt" 2>/dev/null; then
> +	mounted=1
> +	type="$(grub2-probe -d "$partition" -t fs)" || true
> +	if [ "$type" ]; then
> +		debug "mounted using GRUB $type filesystem driver"
> +	else
> +		debug "mounted using GRUB, but unknown filesystem?"
> +		type=fuseblk
> +	fi
> +fi
> +
> +if [ "$mounted" ]; then
> +	for test in /usr/lib/os-probes/mounted/*; do
> +		debug "running subtest $test"
> +		if [ -f "$test" ] && [ -x "$test" ]; then
> +			if "$test" "$partition" "$tmpmnt" "$type"; then
> +				debug "os found by subtest $test"
> +				do_unmount
> +				exit 0
> +			fi
> +		fi
> +	done
> +fi
> +do_unmount
> +
>  # all btrfs processing here.  Handle both unmounted and
>  # mounted subvolumes.
>  if [ "$types" = btrfs ]; then
> -	partition="$BTRFSDEV"
>  	debug "begin btrfs processing for $UUID"
>  	# note that the btrfs volume must not be mounted ro
>  	if mount -t btrfs -U "$UUID" "$tmpmnt"  2>/dev/null; then
> @@ -129,37 +159,8 @@ if [ "$types" = btrfs ]; then
>  	rmdir "$tmpmnt" || true
>  	if [ "$found" ]; then
>  		exit 0
> -	else
> -		exit 1
> -	fi
> -fi
> -
> -if type grub-mount >/dev/null 2>&1 && \
> -   type grub-probe >/dev/null 2>&1 && \
> -   grub-mount "$partition" "$tmpmnt" 2>/dev/null; then
> -	mounted=1
> -	type="$(grub-probe -d "$partition" -t fs)" || true
> -	if [ "$type" ]; then
> -		debug "mounted using GRUB $type filesystem driver"
> -	else
> -		debug "mounted using GRUB, but unknown filesystem?"
> -		type=fuseblk
>  	fi
>  fi
>  
> -if [ "$mounted" ]; then
> -	for test in /usr/lib/os-probes/mounted/*; do
> -		debug "running subtest $test"
> -		if [ -f "$test" ] && [ -x "$test" ]; then
> -			if "$test" "$partition" "$tmpmnt" "$type"; then
> -				debug "os found by subtest $test"
> -				do_unmount
> -				exit 0
> -			fi
> -		fi
> -	done
> -fi
> -do_unmount
> -
>  # No tests found anything.
>  exit 1

> Index: os-prober-1.61/os-prober
> ===================================================================
> --- os-prober-1.61.orig/os-prober
> +++ os-prober-1.61/os-prober
> @@ -23,6 +23,28 @@
>  	fi
>  	return 1
>  }
> +mp_disks="UNDEF"
> +on_multipath () {
> +	type multipath >/dev/null 2>&1 || return 1
> +	local parent="${1%/*}"
> +	local device="${parent##*/}"
> +
> +	if [ "$mp_disks" = "UNDEF" ]; then
> +		mp_disks=`multipath -d -l | sed -n -e 's/^.\+[0-9]\+:[0-9]\+:[0-9]\+:[0-9]\+ \([^ ]\+\) .*/\1/p'`
> +	fi
> +
> +	if [ -z "$mp_disks" ]; then
> +		return 1
> +	fi
> +
> +	for i in $mp_disks; do
> +		if [ "$device" = "$i" ]; then
> +			debug "$1: part of multipath disk $i"
> +			return 0
> +		fi
> +	done
> +	return 1
> +}
>  
>  partitions () {
>  	os_name="$(uname -s)"
> @@ -31,7 +54,7 @@ partitions () {
>  		# Serial ATA RAID disk.
>  		for part in /sys/block/*/*[0-9]; do
>  			if [ -f "$part/start" ] && \
> -			   [ ! -f "$part/whole_disk" ] && ! on_sataraid $part; then
> +			   [ ! -f "$part/whole_disk" ] && ! on_sataraid $part && ! on_multipath $part; then
>  				name="$(echo "${part##*/}" | sed 's,[!.],/,g')"
>  				if [ -e "/dev/$name" ]; then
>  					echo "/dev/$name"

> From: Egbert Eich <eich@suse.de>
> Date: Fri May 29 08:55:21 2015 +0200
> Subject: Improve btrfs handling on os-probing for grub2
> Patch-mainline: never
> 
> References: bsc#892364
> Signed-off-by: Egbert Eich <eich@suse.com>
> 
> Currently probing of a grub2 config file is broken if
> the root/boot fs is btrfs. This is due to a patch picked
> from Fedora which attempts to determine the location of
> the kernel and probe for it.
> This code has meanwhile changed on Fedora, however the
> new version works no better than the old one.
> It is possible that this code works under very special
> circumstances of the Fedora system, however it is by no
> means valid.
> Our goal is to
> a. determine the location of the kernel in the mounted fs
>    regardless whether the grub2 config specifies an absolute
>    or relative path to the kernel file.
> b. Prepend the correct prefix if grub2_btrfs expects an
>    absolute path (either because the current grub2 fs isn't
>    btrfs or absolute path addressing is explicitely requested).
> c. Attempt to handle the location of the kernel file correctly
>    if this lives on a separate btrfs subvolume.
>    (Currently this only works if the path to this subvolume is
>    identical to the fs path).
> 
> Signed-off-by: Egbert Eich <eich@suse.de>
> 
> v2:
> a. Fix missing linux16/initrd16 parsing in entry result
> b. Fix kernelfile path if separate boot partition on btrfs 
> 
> Signed-off-by: Michael Chang <mchang@suse.com>
> ---
>  linux-boot-probes/mounted/common/40grub2 | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> Index: os-prober-1.61/linux-boot-probes/mounted/common/40grub2
> ===================================================================
> --- os-prober-1.61.orig/linux-boot-probes/mounted/common/40grub2
> +++ os-prober-1.61/linux-boot-probes/mounted/common/40grub2
> @@ -14,9 +14,19 @@ bootsv="$6"
>  found_item=0
>  
>  entry_result () {
> -	if [ "x$type" = "xbtrfs" -a "$rootsv" = "$bootsv" ]; then
> -		# trim off the leading subvol
> -		kernelfile=$(echo "$kernel" | cut -d '/' -f 2- | cut -d '/' -f 2-)
> +	if [ "x$type" = "xbtrfs" ]; then
> +		bsv=${bootsv:+/}${bootsv}
> +		# if path is not relative to subvolume make it relative
> +		kernel=${kernel#${bsv}}
> +		kernelfile=$kernel
> +		initrd=${initrd#${bsv}}
> +		if [ "x$GRUB_FS" != "xbtrfs" -o "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" != "xtrue" ]; then
> +		    # absolute path needed: prepend subvolume if $kernel isn't empty
> +		    kernel=${kernel:+${bsv}}${kernel}
> +		    initrd=${initrd:+${bsv}}${initrd}
> +		fi
> +		# assumed: rootsv != bootsv if rootsv isn't ancestor of bootsv
> +		[ "$partition" != "$bootpart" -o "$rootsv" != "$bootsv" ] && kernelfile="/boot${kernelfile}"
>  	else
>  		kernelfile=$kernel
>  	fi
> @@ -81,7 +91,7 @@ parse_grub_menu () {
>  					ignore_item=1
>  				fi
>  			;;
> -			linux|linuxefi)
> +			linux|linuxefi|linux16)
>  				# Hack alert: sed off any (hdn,n) but
>  				# assume the kernel is on the same
>  				# partition.
> @@ -90,14 +100,14 @@ parse_grub_menu () {
>  				parameters="$@"
>  				# Systems with a separate /boot will not have
>  				# the path to the kernel in grub.cfg.
> -				if [ "$partition" != "$bootpart" ]; then
> +				if [ "$partition" != "$bootpart" -a "$type" != "btrfs" ]; then
>  					kernel="/boot$kernel"
>  				fi
>  			;;
> -			initrd|initrdefi)
> +			initrd|initrdefi|initrd16)
>  				initrd="$(echo "$2" | sed 's/(.*)//')"
>  				# Initrd same.
> -				if [ "$partition" != "$bootpart" ]; then
> +				if [ "$partition" != "$bootpart" -a "$type" != "btrfs" ]; then
>  					initrd="/boot$initrd"
>  				fi
>  			;;

> Index: os-prober/os-probes/common/50mounted-tests
> ===================================================================
> --- os-prober.orig/os-probes/common/50mounted-tests
> +++ os-prober/os-probes/common/50mounted-tests
> @@ -72,9 +72,7 @@ mounted=
>  
>  if [ "$types" = btrfs ]; then
>  	partition="$BTRFSDEV"
> -fi
> -
> -if type grub2-mount >/dev/null 2>&1 && \
> +elif type grub2-mount >/dev/null 2>&1 && \
>     type grub2-probe >/dev/null 2>&1 && \
>     grub2-mount "$partition" "$tmpmnt" 2>/dev/null; then
>  	mounted=1
> @@ -110,7 +108,11 @@ if [ "$mounted" ]; then
>  		fi
>  	done
>  fi
> -do_unmount
> +
> +if [ "$types" != "btrfs" ]; then
> +	do_unmount
> +	exit 1
> +fi
>  
>  # all btrfs processing here.  Handle both unmounted and
>  # mounted subvolumes.
> @@ -125,9 +127,9 @@ if [ "$types" = btrfs ]; then
>  		exit 1
>  	fi
>  	# besides regular subvols, get ro and snapshot so thet can be excluded
> -        subvols=$(btrfs subvolume list "$tmpmnt" | cut -d ' ' -f 9)
> -        rosubvols=$(btrfs subvolume list -r "$tmpmnt" | cut -d ' ' -f 9)
> -        sssubvols=$(btrfs subvolume list -s "$tmpmnt" | cut -d ' ' -f 14)
> +        subvols=$(btrfs subvolume list -a "$tmpmnt" | cut -d ' ' -f 9 | sed -e s!^\<FS_TREE\>/!!)
> +        rosubvols=$(btrfs subvolume list -r -a "$tmpmnt" | cut -d ' ' -f 9 | sed -e s!^\<FS_TREE\>/!!)
> +        sssubvols=$(btrfs subvolume list -s -a "$tmpmnt" | cut -d ' ' -f 14 | sed -e s!^\<FS_TREE\>/!!)
>          if ! umount "$tmpmnt"; then
>              warn "failed to umount btrfs volume on $tmpmnt"
>              rmdir "$tmpmnt" || true

> From: Andrei Borzenkov <arvidjaar@gmail.com>
> Subject: Also skip legacy grub if grub2 is found
> 
> Check for grub.cfg also in /boot/grub2, not only in /boot/grub.
> Index: os-prober/linux-boot-probes/mounted/x86/40grub
> ===================================================================
> --- os-prober.orig/linux-boot-probes/mounted/x86/40grub
> +++ os-prober/linux-boot-probes/mounted/x86/40grub
> @@ -95,7 +95,9 @@ fi
>  
>  if [ "$grubconf" ] && \
>     ([ ! -e "$mpoint/boot/grub/grub.cfg" ] || \
> -    [ "$mpoint/boot/grub/$grubconf" -nt "$mpoint/boot/grub/grub.cfg" ]); then
> +    [ "$mpoint/boot/grub/$grubconf" -nt "$mpoint/boot/grub/grub.cfg" ]) && \
> +   ([ ! -e "$mpoint/boot/grub2/grub.cfg" ] || \
> +    [ "$mpoint/boot/grub/$grubconf" -nt "$mpoint/boot/grub2/grub.cfg" ]); then
>  	debug "parsing $grubconf"
>  	parse_grub_menu "$mpoint" "$partition" "$bootpart" < "$mpoint/boot/grub/$grubconf"
>  fi

> Index: os-prober/os-probes/common/50mounted-tests
> ===================================================================
> --- os-prober.orig/os-probes/common/50mounted-tests
> +++ os-prober/os-probes/common/50mounted-tests
> @@ -115,6 +115,7 @@ if [ "$types" = btrfs ]; then
>          subvols=$(btrfs subvolume list -a "$tmpmnt" | cut -d ' ' -f 9 | sed -e s!^\<FS_TREE\>/!!)
>          rosubvols=$(btrfs subvolume list -r -a "$tmpmnt" | cut -d ' ' -f 9 | sed -e s!^\<FS_TREE\>/!!)
>          sssubvols=$(btrfs subvolume list -s -a "$tmpmnt" | cut -d ' ' -f 14 | sed -e s!^\<FS_TREE\>/!!)
> +        defaultvol=$(btrfs subvolume get-default "$tmpmnt" | cut -d ' ' -f 9)
>          if ! umount "$tmpmnt"; then
>              warn "failed to umount btrfs volume on $tmpmnt"
>              rmdir "$tmpmnt" || true
> @@ -127,11 +128,13 @@ if [ "$types" = btrfs ]; then
>  	found=
>          for subvol in $subvols; do
>  		debug "begin btrfs processing for $UUID subvol=$subvol"
> -		if echo "$rosubvols" | grep -q -x "$subvol"; then
> -			continue
> -		fi
> -		if echo "$sssubvols" | grep -q -x "$subvol"; then
> -			continue
> +                if [ "$subvol" != "$defaultvol" ]; then
> +			if echo "$rosubvols" | grep -q -x "$subvol"; then
> +				continue
> +			fi
> +			if echo "$sssubvols" | grep -q -x "$subvol"; then
> +				continue
> +			fi
>  		fi
>  		mounted=
>  		mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)"

> Index: os-prober/linux-boot-prober
> ===================================================================
> --- os-prober.orig/linux-boot-prober
> +++ os-prober/linux-boot-prober
> @@ -67,7 +67,12 @@ if [ "$type" = btrfs ]; then
>  	fi
>  	if [ -z "$mpoint" ]; then
>  		# mount the btrfs root
> -		if ! mount -o subvol=$subvol -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then
> +
> +		if [ -n "$subvol" ]; then
> +			opts="-o subvol=$subvol"
> +		fi
> +
> +		if ! mount $opts -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then
>  			warn "error mounting btrfs subvol=$subvol UUID=$UUID"
>  			umount "$tmpmnt/boot" 2>/dev/null
>  			umount "$tmpmnt" 2>/dev/null
> Index: os-prober/os-probes/common/50mounted-tests
> ===================================================================
> --- os-prober.orig/os-probes/common/50mounted-tests
> +++ os-prober/os-probes/common/50mounted-tests
> @@ -114,6 +114,47 @@ if [ "$types" != "btrfs" ]; then
>  	exit 1
>  fi
>  
> +probe_subvol ()
> +{
> +	local subvol=$1
> +	local partition=$2
> +	local UUID=$3
> +	local tmpmnt=$4
> +
> +	mounted=
> +	mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)"
> +	ret=1
> +
> +	if [ -n "$subvol" ]; then
> +		opts="-o subvol=$subvol"
> +	fi
> +
> +	if [ -n "$mpoint" ]; then
> +		if [ "x$mpoint" = "x/" ]; then
> +			continue # this is the root for the running system
> +  		fi
> +		mounted=1
> +	else
> +		# again, do not mount btrfs ro
> +		mount -t btrfs $opts -U "$UUID" "$tmpmnt"
> +		mpoint="$tmpmnt"
> +	fi
> +	test="/usr/lib/os-probes/mounted/90linux-distro"
> +	if [ -f "$test" ] && [ -x "$test" ]; then
> +		debug "running subtest $test"
> +		if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID" "subvol=$subvol"; then
> +			debug "os found by subtest $test on subvol $subvol"
> +			ret=0
> +		fi
> +	fi
> +	if [ -z "$mounted" ]; then
> +		if ! umount "$tmpmnt"; then
> +			warn "failed to umount $tmpmnt"
> +		fi
> +	fi
> +	return $ret
> +}
> +
>  # all btrfs processing here.  Handle both unmounted and
>  # mounted subvolumes.
>  if [ "$types" = btrfs ]; then
> @@ -136,45 +177,23 @@ if [ "$types" = btrfs ]; then
>              rmdir "$tmpmnt" || true
>              exit 1
>          fi
> -	if [ -z "$subvols" ]; then
> -		debug "no subvols found on btrfs volume $UUID"
> -		exit 1
> -	fi
> +
>  	found=
> -        for subvol in $subvols; do
> -		debug "begin btrfs processing for $UUID subvol=$subvol"
> -                if [ "$subvol" != "$defaultvol" ]; then
> -			if echo "$rosubvols" | grep -q -x "$subvol"; then
> -				continue
> -			fi
> -			if echo "$sssubvols" | grep -q -x "$subvol"; then
> -				continue
> -			fi
> -		fi
> -		mounted=
> -		mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)"
> -		if [ -n "$mpoint" ]; then
> -			if [ "x$mpoint" = "x/" ]; then
> -				continue # this is the root for the running system
> -			fi
> -			mounted=1
> -		else
> -			# again, do not mount btrfs ro
> -			mount -t btrfs -o subvol="$subvol" -U "$UUID" "$tmpmnt"
> -			mpoint="$tmpmnt"
> -		fi
> -		test="/usr/lib/os-probes/mounted/90linux-distro"
> -		if [ -f "$test" ] && [ -x "$test" ]; then
> -			debug "running subtest $test"
> -			if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID" "subvol=$subvol"; then
> -				debug "os found by subtest $test on subvol $subvol"
> -				found=1
> -			fi
> +	# Always probe subvol or root set as default
> +	if probe_subvol "$defaultvol" "$partition" "$UUID" "$tmpmnt"; then
> +		found=1
> +	fi
> +
> +	# Probe any other OS on subvol
> +	for subvol in $subvols; do
> +		if echo "$rosubvols" | grep -q -x "$subvol" ||
> +		   echo "$sssubvols" | grep -q -x "$subvol" ||
> +		   echo "$defaultvol" | grep -q -x "$subvol"; then
> +			continue
>  		fi
> -		if [ -z "$mounted" ]; then
> -			if ! umount "$tmpmnt"; then
> -			    warn "failed to umount $tmpmnt"
> -			fi
> +		debug "begin btrfs processing for $UUID subvol=$subvol"
> +		if probe_subvol "$subvol" "$partition" "$UUID" "$tmpmnt"; then
> +			found=1
>  		fi
>  	done
>  	rmdir "$tmpmnt" || true

> 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
> @@ -10,147 +10,133 @@ type="$3"
>  uuid="$4"
>  subvol="$5"
>  
> -# This test is inaccurate, but given separate / and /boot partitions and the
> -# fact that only some architectures have ld-linux.so, I can't see anything
> -# better. Make sure this test has a high number so that more accurate tests
> -# can come first.
> -# Unless volumes to checked are already mounted, they will be mounted using
> -# GRUB's own filesystems through FUSE. Since these ATM doesn't support
> -# symlinks we need to also check in $dir/usr/lib* for distributions that
> -# moved /lib* to /usr and only left symlinks behind.
> -# TODO: look for ld-linux.so on arches that have it
> -if (ls "$dir"/lib*/ld*.so* && [ -d "$dir/boot" ] || ls "$dir"/usr/lib*/ld*.so*) >/dev/null 2>/dev/null; then
> -	if [ -e "$dir/etc/os-release" ]; then
> -		short="$(grep ^NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g; s/[[:space:]].*//')"
> -		long="$(grep ^PRETTY_NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g')"
> -	elif [ -e "$dir/etc/debian_version" ]; then
> -		short="Debian"
> -		long="$(printf "Debian GNU/Linux (%s)\n" "$(cat "$dir/etc/debian_version")")"
> -	# RPM derived distributions may also have a redhat-release or
> -	# mandrake-release, so check their files first.
> -	elif [ -e "$dir/etc/altlinux-release" ]; then
> -		short="ALTLinux"
> -		long="$(cat "$dir/etc/altlinux-release")"
> -	elif [ -e "$dir/etc/magic-release" ]; then
> -		short="Magic"
> -		long="$(cat "$dir/etc/magic-release")"
> -	elif [ -e "$dir/etc/blackPanther-release" ]; then
> -		short="blackPanther"
> -		long="$(cat "$dir/etc/blackPanther-release")"
> -	elif [ -e "$dir/etc/ark-release" ]; then
> -		short="Ark"
> -		long="$(cat "$dir/etc/ark-release")"
> -	elif [ -e "$dir/etc/arch-release" ]; then
> -		short="Arch"
> -		long="$(cat "$dir/etc/arch-release")"
> -	elif [ -e "$dir/etc/asplinux-release" ]; then
> -		short="ASPLinux"
> -		long="$(cat "$dir/etc/asplinux-release")"
> -	elif [ -e "$dir/etc/lvr-release" ]; then
> -		short="LvR"
> -		long="$(cat "$dir/etc/lvr-release")"
> -	elif [ -e "$dir/etc/caos-release" ]; then
> -		short="cAos"
> -		long="$(cat "$dir/etc/caos-release")"
> -	elif [ -e "$dir/etc/aurox-release" ]; then
> -		short="Aurox"
> -		long="$(cat "$dir/etc/aurox-release")"
> -	elif [ -e "$dir/etc/engarde-release" ]; then
> -		short="EnGarde"
> -		long="$(cat "$dir/etc/engarde-release")"
> -	elif [ -e "$dir/etc/vine-release" ]; then
> -		short="Vine"
> -		long="$(cat "$dir/etc/vine-release")"
> -	elif [ -e "$dir/etc/whitebox-release" ]; then
> -		short="WhiteBox"
> -		long="$(cat "$dir/etc/whitebox-release")"
> -	elif [ -e "$dir/etc/pld-release" ]; then
> -		short="PLD"
> -		long="$(cat "$dir/etc/pld-release")"
> -	elif [ -e "$dir/etc/startcom-release" ]; then
> -		short="StartCom"
> -		long="$(cat "$dir/etc/startcom-release")"
> -	elif [ -e "$dir/etc/trustix-release" ]; then
> -		short="Trustix"
> -		long="$(cat "$dir/etc/trustix-release")"
> -	elif [ -e "$dir/etc/openna-release" ]; then
> -		short="OpenNA"
> -		long="$(cat "$dir/etc/openna-release")"
> -	elif [ -e "$dir/etc/mageia-release" ]; then
> -		short="Mageia"
> -		long="$(cat "$dir/etc/mageia-release")"
> -	elif [ -e "$dir/etc/conectiva-release" ]; then
> -		short="Conectiva"
> -		long="$(cat "$dir/etc/conectiva-release")"
> -	elif [ -e "$dir/etc/mandrake-release" ]; then
> -		short="Mandrake"
> -		long="$(cat "$dir/etc/mandrake-release")"
> -	elif [ -e "$dir/etc/fedora-release" ]; then
> -		short="Fedora"
> -		long="$(cat "$dir/etc/fedora-release")"
> -	elif [ -e "$dir/etc/redhat-release" ]; then
> -		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")"
> -	elif [ -e "$dir/etc/gentoo-release" ]; then
> -		short="Gentoo"
> -		long="$(cat "$dir/etc/gentoo-release")"
> -	elif [ -e "$dir/etc/cobalt-release" ]; then
> -		short="Cobalt"
> -		long="$(cat "$dir/etc/cobalt-release")"
> -	elif [ -e "$dir/etc/yellowdog-release" ]; then
> -		short="YellowDog"
> -		long="$(cat "$dir/etc/yellowdog-release")"
> -	elif [ -e "$dir/etc/turbolinux-release" ]; then
> -		short="Turbolinux"
> -		long="$(cat "$dir/etc/turbolinux-release")"
> -	elif [ -e "$dir/etc/pardus-release" ]; then
> -		short="Pardus"
> -		long="$(cat "$dir/etc/pardus-release")"
> -	elif [ -e "$dir/etc/kanotix-version" ]; then
> -		short="Kanotix"
> -		long="$(cat "$dir/etc/kanotix-version")"
> -	elif [ -e "$dir/etc/slackware-version" ]; then
> -		short="Slackware"
> -		long="$(printf "Slackware Linux (%s)\n" "$(cat "$dir/etc/slackware-version")")"
> -	elif [ -e "$dir/sbin/pkgtool" ]; then
> -		short="Slackware"
> -		long="Slackware Linux"
> -	elif grep -qs OpenLinux "$dir/etc/issue"; then
> -		short="Caldera"
> -		long="Caldera OpenLinux"
> -	elif [ -e "$dir/etc/frugalware-release" ]; then
> -		short="Frugalware Linux"
> -		long="$(cat "$dir/etc/frugalware-release")"
> -	elif [ -e "$dir/etc/kdemar-release" ]; then
> -		short="K-DEMar"
> -		long="$(printf "K-DEMar GNU/Linux (%s)\n" "$(cat "$dir/etc/kdemar-release")")"
> -	elif [ -e "$dir/etc/lfs-release" ]; then
> -		short="LFS"
> -		long="$(printf "Linux From Scratch (%s)\n" "$(cat "$dir/etc/lfs-release")")"
> -	elif [ -e "$dir/etc/meego-release" ]; then
> -		short="MeeGo"
> -		long="$(head -1 "$dir/etc/meego-release")"
> -	elif [ -e "$dir/etc/4MLinux-version" ]; then
> -		short="4MLinux"
> -		long="4MLinux $(head -1 "$dir/etc/4MLinux-version")"
> -	elif [ -e "$dir/etc/devuan_version" ]; then
> -		short="Devuan"
> -		long="$(printf "Devuan GNU/Linux (%s)\n" "$(cat "$dir/etc/devuan_version")")"
> -	else
> -		short="Linux"
> -		long="unknown Linux distribution"
> -	fi
> -	
> -        label="$(count_next_label "$short")"
> -	if [ "x$type" = "xbtrfs" -a "x$uuid" != "x" -a "x$subvol" != "x" ]; then
> -		result "$partition:$long:$label:linux:$type:$uuid:$subvol"
> -	else
> -		result "$partition:$long:$label:linux"
> -	fi
> -	exit 0
> +if [ -e "$dir/etc/os-release" ]; then
> +	short="$(grep ^NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g; s/[[:space:]].*//')"
> +	long="$(grep ^PRETTY_NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g')"
> +elif [ -e "$dir/etc/debian_version" ]; then
> +	short="Debian"
> +	long="$(printf "Debian GNU/Linux (%s)\n" "$(cat "$dir/etc/debian_version")")"
> +# RPM derived distributions may also have a redhat-release or
> +# mandrake-release, so check their files first.
> +elif [ -e "$dir/etc/altlinux-release" ]; then
> +	short="ALTLinux"
> +	long="$(cat "$dir/etc/altlinux-release")"
> +elif [ -e "$dir/etc/magic-release" ]; then
> +	short="Magic"
> +	long="$(cat "$dir/etc/magic-release")"
> +elif [ -e "$dir/etc/blackPanther-release" ]; then
> +	short="blackPanther"
> +	long="$(cat "$dir/etc/blackPanther-release")"
> +elif [ -e "$dir/etc/ark-release" ]; then
> +	short="Ark"
> +	long="$(cat "$dir/etc/ark-release")"
> +elif [ -e "$dir/etc/arch-release" ]; then
> +	short="Arch"
> +	long="$(cat "$dir/etc/arch-release")"
> +elif [ -e "$dir/etc/asplinux-release" ]; then
> +	short="ASPLinux"
> +	long="$(cat "$dir/etc/asplinux-release")"
> +elif [ -e "$dir/etc/lvr-release" ]; then
> +	short="LvR"
> +	long="$(cat "$dir/etc/lvr-release")"
> +elif [ -e "$dir/etc/caos-release" ]; then
> +	short="cAos"
> +	long="$(cat "$dir/etc/caos-release")"
> +elif [ -e "$dir/etc/aurox-release" ]; then
> +	short="Aurox"
> +	long="$(cat "$dir/etc/aurox-release")"
> +elif [ -e "$dir/etc/engarde-release" ]; then
> +	short="EnGarde"
> +	long="$(cat "$dir/etc/engarde-release")"
> +elif [ -e "$dir/etc/vine-release" ]; then
> +	short="Vine"
> +	long="$(cat "$dir/etc/vine-release")"
> +elif [ -e "$dir/etc/whitebox-release" ]; then
> +	short="WhiteBox"
> +	long="$(cat "$dir/etc/whitebox-release")"
> +elif [ -e "$dir/etc/pld-release" ]; then
> +	short="PLD"
> +	long="$(cat "$dir/etc/pld-release")"
> +elif [ -e "$dir/etc/startcom-release" ]; then
> +	short="StartCom"
> +	long="$(cat "$dir/etc/startcom-release")"
> +elif [ -e "$dir/etc/trustix-release" ]; then
> +	short="Trustix"
> +	long="$(cat "$dir/etc/trustix-release")"
> +elif [ -e "$dir/etc/openna-release" ]; then
> +	short="OpenNA"
> +	long="$(cat "$dir/etc/openna-release")"
> +elif [ -e "$dir/etc/mageia-release" ]; then
> +	short="Mageia"
> +	long="$(cat "$dir/etc/mageia-release")"
> +elif [ -e "$dir/etc/conectiva-release" ]; then
> +	short="Conectiva"
> +	long="$(cat "$dir/etc/conectiva-release")"
> +elif [ -e "$dir/etc/mandrake-release" ]; then
> +	short="Mandrake"
> +	long="$(cat "$dir/etc/mandrake-release")"
> +elif [ -e "$dir/etc/fedora-release" ]; then
> +	short="Fedora"
> +	long="$(cat "$dir/etc/fedora-release")"
> +elif [ -e "$dir/etc/redhat-release" ]; then
> +	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")"
> +elif [ -e "$dir/etc/gentoo-release" ]; then
> +	short="Gentoo"
> +	long="$(cat "$dir/etc/gentoo-release")"
> +elif [ -e "$dir/etc/cobalt-release" ]; then
> +	short="Cobalt"
> +	long="$(cat "$dir/etc/cobalt-release")"
> +elif [ -e "$dir/etc/yellowdog-release" ]; then
> +	short="YellowDog"
> +	long="$(cat "$dir/etc/yellowdog-release")"
> +elif [ -e "$dir/etc/turbolinux-release" ]; then
> +	short="Turbolinux"
> +	long="$(cat "$dir/etc/turbolinux-release")"
> +elif [ -e "$dir/etc/pardus-release" ]; then
> +	short="Pardus"
> +	long="$(cat "$dir/etc/pardus-release")"
> +elif [ -e "$dir/etc/kanotix-version" ]; then
> +	short="Kanotix"
> +	long="$(cat "$dir/etc/kanotix-version")"
> +elif [ -e "$dir/etc/slackware-version" ]; then
> +	short="Slackware"
> +	long="$(printf "Slackware Linux (%s)\n" "$(cat "$dir/etc/slackware-version")")"
> +elif [ -e "$dir/sbin/pkgtool" ]; then
> +	short="Slackware"
> +	long="Slackware Linux"
> +elif grep -qs OpenLinux "$dir/etc/issue"; then
> +	short="Caldera"
> +	long="Caldera OpenLinux"
> +elif [ -e "$dir/etc/frugalware-release" ]; then
> +	short="Frugalware Linux"
> +	long="$(cat "$dir/etc/frugalware-release")"
> +elif [ -e "$dir/etc/kdemar-release" ]; then
> +	short="K-DEMar"
> +	long="$(printf "K-DEMar GNU/Linux (%s)\n" "$(cat "$dir/etc/kdemar-release")")"
> +elif [ -e "$dir/etc/lfs-release" ]; then
> +	short="LFS"
> +	long="$(printf "Linux From Scratch (%s)\n" "$(cat "$dir/etc/lfs-release")")"
> +elif [ -e "$dir/etc/meego-release" ]; then
> +	short="MeeGo"
> +	long="$(head -1 "$dir/etc/meego-release")"
> +elif [ -e "$dir/etc/4MLinux-version" ]; then
> +	short="4MLinux"
> +	long="4MLinux $(head -1 "$dir/etc/4MLinux-version")"
> +elif [ -e "$dir/etc/devuan_version" ]; then
> +	short="Devuan"
> +	long="$(printf "Devuan GNU/Linux (%s)\n" "$(cat "$dir/etc/devuan_version")")"
>  else
>  	exit 1
>  fi
> +
> +label="$(count_next_label "$short")"
> +if [ "x$type" = "xbtrfs" -a "x$uuid" != "x" -a "x$subvol" != "x" ]; then
> +	result "$partition:$long:$label:linux:$type:$uuid:$subvol"
> +else
> +	result "$partition:$long:$label:linux"
> +fi
> +exit 0
> Index: os-prober/os-prober
> ===================================================================
> --- os-prober.orig/os-prober
> +++ os-prober/os-prober
> @@ -186,6 +186,11 @@ for partition in $(partitions); do
>  	# be handled by 50mounted-tests so we can do a subvol only once.
>  	type=$(blkid -o value -s TYPE $mapped || true)
>  	if [ "$type" = btrfs ]; then
> +		mpoint=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2)
> +		mpoint="$(unescape_mount "$mpoint")"
> +		if [ "$mpoint" = "/target/boot" ] || [ "$mpoint" = "/target" ] || [ "$mpoint" = "/" ]; then
> +			continue
> +		fi
>  		uuid=$(blkid -o value -s UUID $mapped)
>  		if grep -q "^$uuid" "$OS_PROBER_TMP/btrfs-vols" ; then
>  			continue

> 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
> @@ -10,7 +10,18 @@ type="$3"
>  uuid="$4"
>  subvol="$5"
>  
> -if [ -e "$dir/etc/os-release" ]; then
> +if [ -L "$dir/etc/os-release" ]; then
> +	RELPATH=$(readlink -f "$dir/etc/os-release")
> +	if readlink "$dir/etc/os-release" | grep -q '^/'; then
> +		RELPATH="$dir$RELPATH"
> +	fi
> +	if [ -f "$RELPATH" ]; then
> +		short="$(grep ^NAME= "$RELPATH" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g; s/[[:space:]].*//')"
> +		long="$(grep ^PRETTY_NAME= "$RELPATH" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g')"
> +	else
> +		exit 1
> +	fi
> +elif [ -e "$dir/etc/os-release" ]; then
>  	short="$(grep ^NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g; s/[[:space:]].*//')"
>  	long="$(grep ^PRETTY_NAME= "$dir/etc/os-release" | sed 's/^[^=]*=//; s/^['\''"]\(.*\)['\''"]$/\1/; s/\\\(.\)/\1/g')"
>  elif [ -e "$dir/etc/debian_version" ]; then

> Index: os-prober/os-probes/mounted/x86/05efi
> ===================================================================
> --- os-prober.orig/os-probes/mounted/x86/05efi
> +++ os-prober/os-probes/mounted/x86/05efi
> @@ -59,7 +59,11 @@ ret=1
>  for test in /usr/lib/os-probes/mounted/efi/*; do
>  	debug "running subtest $test"
>  	if [ -f "$test" ] && [ -x "$test" ]; then
> +		# we need results of subtest in stdout
> +		orig_fd_res=$fd_result
> +		export fd_result=1
>  		entry=$("$test" "$mpoint/$efi")
> +		export fd_result=$orig_fd_res
>  		if [ -n "$entry" ]; then
>  			debug "bootloader $entry found by subtest $test"
>  			ret=0

> Index: os-prober/common.sh
> ===================================================================
> --- os-prober.orig/common.sh
> +++ os-prober/common.sh
> @@ -62,10 +62,14 @@ cache_progname() {
>    esac
>  }
>  
> -log() {
> -  cache_progname
> -  logger -t "$progname" "$@"
> -}
> +# fd_logger: bind value now, possibly after assigning default. 
> +eval '
> +  log() {
> +    cache_progname
> +    echo "$progname: $@"  1>&'${fd_logger:=9}'
> +  }
> +'
> +export fd_logger  # so subshells inherit current value by default
>  
>  error() {
>    log "error: $@"
> @@ -81,10 +85,14 @@ debug() {
>    fi
>  }
>  
> -result () {
> -  log "result:" "$@"
> -  echo "$@"
> -}
> +# fd_result: bind value now, possibly after assigning default.
> +eval '
> +  result() {
> +    log "result:" "$@"
> +    echo "$@"  1>&'${fd_result:=1}'
> +  }
> +'
> +export fd_result  # so subshells inherit current value by default
>  
>  # shim to make it easier to use os-prober outside d-i
>  if ! type mapdevfs >/dev/null 2>&1; then
> Index: os-prober/linux-boot-prober
> ===================================================================
> --- os-prober.orig/linux-boot-prober
> +++ os-prober/linux-boot-prober
> @@ -1,4 +1,12 @@
>  #!/bin/sh
> +
> +# dash shell does not have "{varname}>&1" feature that bash shell has
> +# for auto-assignment of new filedescriptors.
> +# It is cumbersome to write the 'eval' to use our own variables in redirections.
> +# Therefore use fixed numbers.
> +export fd_result=3  # file descriptor for external results
> +export fd_logger=9  # file descriptor for input to logger
> +
>  . /usr/share/os-prober/common.sh
>  
>  set -e
> @@ -19,6 +27,7 @@ bootuuid=
>  
>  grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true
>  
> +( (
>  if [ -z "$1" ]; then
>  	ERR=y
>  elif [ "$1" = btrfs -a -z "$2" ]; then
> @@ -186,3 +195,5 @@ else
>  		fi
>  	fi
>  fi
> +) 9>&1 | logger 1>&-  # fd_logger
> +) 3>&1  # fd_result
> Index: os-prober/os-prober
> ===================================================================
> --- os-prober.orig/os-prober
> +++ os-prober/os-prober
> @@ -1,7 +1,14 @@
>  #!/bin/sh
>  set -e
>  
> -. /usr/share/os-prober/common.sh
> +# dash shell does not have "{varname}>&1" feature that bash shell has
> +# for auto-assignment of new filedescriptors.
> +# It is cumbersome to write the 'eval' to use our own variables in redirections.
> +# Therefore use fixed numbers.
> +export fd_result=3  # file descriptor for external results
> +export fd_logger=9  # file descriptor for input to logger
> +
> + . /usr/share/os-prober/common.sh
>  
>  newns "$@"
>  require_tmpdir
> @@ -136,6 +143,7 @@ fi
>  
>  : >"$OS_PROBER_TMP/btrfs-vols"
>  
> +( (
>  for partition in $(partitions); do
>  	if ! mapped="$(mapdevfs "$partition")"; then
>  		log "Device '$partition' does not exist; skipping"
> @@ -200,3 +208,5 @@ for partition in $(partitions); do
>  		fi
>  	fi
>  done
> +) 9>&1 | logger 1>&-  # fd_logger
> +) 3>&1  # fd_result

> Index: os-prober/common.sh
> ===================================================================
> --- os-prober.orig/common.sh
> +++ os-prober/common.sh
> @@ -336,3 +336,13 @@ linux_mount_boot () {
>  
>  	mountboot="$bootpart $mounted"
>  }
> +
> +umount_exec=$(which umount)
> +umount() {
> +	if ! $umount_exec $@ 2> /dev/null; then
> +		error "umount error, retrying after 1 sec"
> +		sleep 1
> +		$umount_exec $@
> +	fi
> +}
> +

> Index: os-prober/os-probes/mounted/x86/83haiku
> ===================================================================
> --- os-prober.orig/os-probes/mounted/x86/83haiku
> +++ os-prober/os-probes/mounted/x86/83haiku
> @@ -13,7 +13,7 @@ case "$type" in
>  	*) debug "$partition is not a BeFS partition: exiting"; exit 1 ;;
>  esac
>  
> -if head -c 512 "$partition" | grep -qs "system.haiku_loader"; then
> +if head -c 512 "$partition" | grep -aqs "system.haiku_loader"; then
>  	debug "Stage 1 bootloader found"
>  else
>  	debug "Stage 1 bootloader not found: exiting"

> Index: os-prober/linux-boot-probes/mounted/common/90fallback
> ===================================================================
> --- os-prober.orig/linux-boot-probes/mounted/common/90fallback
> +++ os-prober/linux-boot-probes/mounted/common/90fallback
> @@ -33,7 +33,7 @@ for kernpat in /vmlinuz /vmlinux /boot/v
>  			# Dracut initramfses are named differently again.
>  			initrdname3=$(echo "$kernfile" | sed "s/vmlinu[zx]/initramfs\*/" | sed 's/$/.img/')
>  			# And Gentoo's also
> -			initrdname4=$(echo "$kernfile" | sed "s/kernel/initramfs\*/")
> +			initrdname4=$(echo "$kernfile" | sed "s/kernel\|vmlinu[zx]/initramfs\*/")
>  			foundinitrd=0
>  			for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null); do
>  				if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then

> Index: os-prober/common.sh
> ===================================================================
> --- os-prober.orig/common.sh
> +++ os-prober/common.sh
> @@ -146,7 +146,7 @@ parse_proc_mounts () {
>  		set -f
>  		set -- $line
>  		set +f
> -		printf '%s %s %s\n' "$(mapdevfs "$1")" "$2" "$3"
> +		printf '%s %s %s %s\n' "$(mapdevfs "$1")" "$2" "$3" "$1"
>  	done
>  }
>  
> Index: os-prober/linux-boot-prober
> ===================================================================
> --- os-prober.orig/linux-boot-prober
> +++ os-prober/linux-boot-prober
> @@ -167,7 +167,7 @@ else
>  			bootpart="${mountboot%% *}"
>  			bootmounted="${mountboot#* }"
>  		else
> -			bootpart="$partition"
> +			bootpart="$(grep " $mpoint/boot " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 4)"
>  			bootmounted=0
>  		fi
>  		for test in /usr/lib/linux-boot-probes/mounted/*; do

> Index: os-prober/common.sh
> ===================================================================
> --- os-prober.orig/common.sh
> +++ os-prober/common.sh
> @@ -269,7 +269,7 @@ linux_mount_boot () {
>  				if [ "$bindfrom" != "$tmpmnt/boot" ]; then
>  					if mount --bind "$bindfrom" "$tmpmnt/boot"; then
>  						mounted=1
> -						bootpart="$1"
> +						bootpart="$tmppart"
>  					else
>  						debug "failed to bind-mount $bindfrom onto $tmpmnt/boot"
>  					fi
> @@ -277,6 +277,15 @@ linux_mount_boot () {
>  			fi
>  			if [ "$mounted" ]; then
>  				:
> +			elif [ -e "$tmppart" ]; then
> +				bootpart="$tmppart"
> +				boottomnt="$tmppart"
> +			elif [ -e "$tmpmnt/$tmppart" ]; then
> +				bootpart="$tmppart"
> +				boottomnt="$tmpmnt/$tmppart"
> +			elif [ -e "/target/$tmppart" ]; then
> +				bootpart="$tmppart"
> +				boottomnt="/target/$tmppart"
>  			elif [ -e "$1" ]; then
>  				bootpart="$1"
>  				boottomnt="$1"

> Index: os-prober-1.58/linux-boot-probes/mounted/common/40grub2
> ===================================================================
> --- os-prober-1.58.orig/linux-boot-probes/mounted/common/40grub2
> +++ os-prober-1.58/linux-boot-probes/mounted/common/40grub2
> @@ -77,7 +77,7 @@ parse_grub_menu () {
>  					ignore_item=1
>  				fi
>  			;;
> -			linux)
> +			linux*)
>  				# Hack alert: sed off any (hdn,n) but
>  				# assume the kernel is on the same
>  				# partition.
> @@ -90,7 +90,7 @@ parse_grub_menu () {
>  					kernel="/boot$kernel"
>  				fi
>  			;;
> -			initrd)
> +			initrd*)
>  				initrd="$(echo "$2" | sed 's/(.*)//')"
>  				# Initrd same.
>  				if [ "$partition" != "$bootpart" ]; then

> From f71f7eb5c492720c24033901ef8c6c420e188ff2 Mon Sep 17 00:00:00 2001
> From: Peter Jones <pjones@redhat.com>
> Date: Thu, 10 May 2012 14:47:35 -0400
> Subject: [PATCH] Don't count our dummy mach_kernel as real MacOS X.
> 
> ---
>  os-probes/mounted/powerpc/20macosx |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> Index: b/os-probes/mounted/powerpc/20macosx
> ===================================================================
> --- a/os-probes/mounted/powerpc/20macosx
> +++ b/os-probes/mounted/powerpc/20macosx
> @@ -21,7 +21,7 @@ esac
>  # but I don't think it exists on Mac OS <= 9, and it's XML so parsing in
>  # shell will be nasty.
>  
> -if [ -e "$2/mach_kernel" ]; then
> +if [ -e "$2/mach_kernel" ] && ! dd if="$2/mach_kernel" count=1 bs=5 2>/dev/null | grep -aq Dummy ; then
>    label="$(count_next_label MacOSX)"
>    result "$1:Mac OS X:$label:macosx"
>    exit 0

> Index: os-prober/os-prober
> ===================================================================
> --- os-prober.orig/os-prober
> +++ os-prober/os-prober
> @@ -64,6 +64,11 @@ partitions () {
>  		exit 0
>  	fi
>  
> +	# Add MD RAID devices
> +	if [ -f /proc/mdstat ] ; then
> +		awk '/^md/ {printf "/dev/"$1"\n"}' /proc/mdstat
> +	fi
> +
>  	# Also detect OSes on LVM volumes (assumes LVM is active)
>  	if type lvs >/dev/null 2>&1; then
>  		echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name |
> @@ -123,7 +128,7 @@ if [ -f /proc/swaps ]; then
>  fi
>  : >"$OS_PROBER_TMP/raided-map"
>  if [ -f /proc/mdstat ] ; then
> -	grep "^md" /proc/mdstat | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true
> +	grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true
>  fi
>  
>  for partition in $(partitions); do

Attachment: signature.asc
Description: PGP signature


Reply to: