Commit fca491a9 authored by Philip Müller's avatar Philip Müller
Browse files

[pkg-upd] 1.77-1

parents
Loading
Loading
Loading
Loading

PKGBUILD

0 → 100644
+102 −0
Original line number Diff line number Diff line
# Maintainer: Bernhard Landauer <oberon@manjaro.org>
# Maintainer: Timothy Redaelli <timothy.redaelli@gmail.com>
# Contributor: darkcoder <mario_vazq@hotmail.com>

pkgname=os-prober
pkgver=1.77
pkgrel=1
pkgdesc="Utility to detect other OSes on a set of drives"
url="http://joey.kitenet.net/code/os-prober/"
arch=('i686' 'x86_64')
license=('GPL3')
depends=('sh')
source=(http://http.debian.net/debian/pool/main/o/${pkgname}/${pkgname}_${pkgver}.tar.xz
	os-prober-frugalware.diff
	os-prober-mdraidfix.patch
	os-prober-btrfsfix.patch
	os-prober-bootpart-name-fix.patch
	os-prober-mounted-partitions-fix.patch
	os-prober-factor-out-logger.patch
	os-prober-factored-logger-efi-fix.patch
	os-prober-umount-fix.patch
	os-prober-grub2-parsefix.patch
        os-prober-grub2-multiple-images.patch
	os-prober-grepfix.patch
	os-prober-gentoo-fix.patch
	fix-blkid-path.patch)
md5sums=('cfe55c2414868fb1478a4565887b9de3'
         '2ae284a2fc6cafb6ec4af0f44d3c3e48'
         'fa2c878cbb8af6b6dc57b6cd966520ec'
         'b71e32f69569f8ad693a19c7129cadf2'
         '672f301022bdb4a2962e9c7f8af05f21'
         '3c15707f9abbf2867d44886a77dbf74a'
         '7e4c8f98ff7763472bc46adb4f9119c2'
         '1a09f769d1e966c773b8885a9b0be44e'
         '69e5e23a35a2756fcb9d649d0ae2eea5'
         'b81bdf05173269ccce91c9a81ce4bfe8'
         '2ac73c1c9f3ff32c4c5670f5fbda9f0d'
         'ed3242f992b525a4af0a9df9af51e334'
         'ec05aaa35c83ab669291e8895c252cc8'
         '20dc42ef9b69f79b920380cd95191ed3')
sha256sums=('8d8ea4afbe1aeef3c8b73f74a0fb37b06185e21a6abc78f80fc2160009cf705f'
            '9a6c22c91ea5955d665bc20d85d899f6721875a6216862d59a1b7f3f4241fd02'
            '092b0caef6fff45560531c0735e9449cb05a677e2296d72b5a0b4fb568fa4476'
            '0ebfd75cfc82cfba2d239986ad68213dc8ee92943a1c68111b34e3fefc360232'
            'c3d094f02b8a00026af10fdfe2ea9286cd1af6a1e25afcc82f3b234bdb64b86f'
            '7a9c4a0f5bba4053b1bbf1640c854aee83f526fd086c94bc7691e1d3cb28afb7'
            'b5c41ac1bc1a4544dd2d9efdcf190d6e5c2f0822b6d0e5fc8f7e6e5222da1d8d'
            '08bf632e4716a3a63bd8f20e729c540754b676b23f4f82ff9156c448910c6f94'
            '81a5ce0c5e784480dff7520bdfada8f80dfe96b101e14e41bca2d0992e863e68'
            'afc201d4d71525b73ffa365f7c667148e007836567be4c8ec25ea661d43b43f8'
            '07b919c7559ce6c5a8d8907d752366fc97ccf40b7ad54cbb2de904a9dd373efd'
            'a9331117892dd9876b346d941969f70da96d54ce122d7a5ff40d9efe36aded42'
            '02741e0edbc46327501be5d74977ff2bffa5ddaffe6a55a689e38ce4b8372444'
            '87bbb0f69ebb47f5136291d6851967fba791db4f27d8883b35fc5be1653ff7a6')

prepare() {
  cd "$pkgname-$pkgver"

  patch -p1 -i "$srcdir"/os-prober-frugalware.diff
  patch -p1 -i "$srcdir"/os-prober-mdraidfix.patch
  patch -p1 -i "$srcdir"/os-prober-btrfsfix.patch
  patch -p1 -i "$srcdir"/os-prober-bootpart-name-fix.patch
  patch -p1 -i "$srcdir"/os-prober-mounted-partitions-fix.patch
  patch -p1 -i "$srcdir"/os-prober-factor-out-logger.patch
  patch -p1 -i "$srcdir"/os-prober-factored-logger-efi-fix.patch
  patch -p1 -i "$srcdir"/os-prober-umount-fix.patch
  patch -p1 -i "$srcdir"/os-prober-grub2-parsefix.patch
  patch -p1 -i "$srcdir"/os-prober-grub2-multiple-images.patch
  patch -p1 -i "$srcdir"/os-prober-grepfix.patch
  patch -p1 -i "$srcdir"/os-prober-gentoo-fix.patch
  patch -p1 -i "$srcdir"/fix-blkid-path.patch

  # adjust lib dir to allow detection of 64-bit distros
  sed -i -e "s:/lib/ld\*\.so\*:/lib*/ld*.so*:g" os-probes/mounted/common/90linux-distro

  rm -f Makefile
}

build() {
  cd "$pkgname-$pkgver"

  make newns
}

package() {
  cd "$pkgname-$pkgver"

  install -Dm755 linux-boot-prober "$pkgdir"/usr/bin/linux-boot-prober
  install -Dm755 os-prober "$pkgdir"/usr/bin/os-prober
  install -Dm755 newns "$pkgdir"/usr/lib/os-prober/newns
  install -Dm755 common.sh $pkgdir/usr/share/os-prober/common.sh  

  for dir in os-probes os-probes/mounted os-probes/init linux-boot-probes linux-boot-probes/mounted; do
    install -dm755 "$pkgdir/usr/lib/$dir"
    install -m755 -t "$pkgdir/usr/lib/$dir" "$dir"/common/*
    [[ -d "$dir"/x86 ]] && cp -r "$dir"/x86/* "$pkgdir/usr/lib/$dir"
  done

  install -Dm755 os-probes/mounted/powerpc/20macosx "$pkgdir"/usr/lib/os-probes/mounted/20macosx

  install -dm755 "$pkgdir"/var/lib/os-prober
}

fix-blkid-path.patch

0 → 100644
+49 −0
Original line number Diff line number Diff line
--- os-prober-1.77/common.sh	2018-08-10 21:23:18.000000000 +0200
+++ os-prober-1.77.new/common.sh	2019-05-13 11:35:39.198711136 +0200
@@ -116,18 +116,18 @@
 		fstype=$(lsblk --nodeps --noheading --output FSTYPE -- "$1" || true)
 		[ -z "$fstype" ] || { echo "$fstype"; return; }
 	fi
-	if type blkid >/dev/null 2>&1; then
-		fstype=$(blkid -o value -s TYPE "$1" 2>/dev/null || true)
+	if type /sbin/blkid >/dev/null 2>&1; then
+		fstype=$(/sbin/blkid -o value -s TYPE "$1" 2>/dev/null || true)
 		[ -z "$fstype" ] || { echo "$fstype"; return; }
 	fi
 	echo "NOT-DETECTED"
 }
 
 is_dos_extended_partition() {
-	if type blkid >/dev/null 2>&1; then
+	if type /sbin/blkid >/dev/null 2>&1; then
 		local output
 
-		output="$(blkid -o export $1)"
+		output="$(/sbin/blkid -o export $1)"
 
 		# old blkid (util-linux << 2.24) errors out on extended p.
 		if [ "$?" = "2" ]; then
@@ -178,9 +178,9 @@
 
 find_label () {
 	local output
-	if type blkid >/dev/null 2>&1; then
+	if type /sbin/blkid >/dev/null 2>&1; then
 		# Hopefully everyone has blkid by now
-		output="$(blkid -o device -t LABEL="$1")" || return 1
+		output="$(/sbin/blkid -o device -t LABEL="$1")" || return 1
 		echo "$output" | head -n1
 	elif [ -h "/dev/disk/by-label/$1" ]; then
 		# Last-ditch fallback
@@ -192,9 +192,9 @@
 
 find_uuid () {
 	local output
-	if type blkid >/dev/null 2>&1; then
+	if type /sbin/blkid >/dev/null 2>&1; then
 		# Hopefully everyone has blkid by now
-		output="$(blkid -o device -t UUID="$1")" || return 1
+		output="$(/sbin/blkid -o device -t UUID="$1")" || return 1
 		echo "$output" | head -n1
 	elif [ -h "/dev/disk/by-uuid/$1" ]; then
 		# Last-ditch fallback
+29 −0
Original line number Diff line number Diff line
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"
+472 −0
Original line number Diff line number Diff line
diff --git a/common.sh b/common.sh
index c2c5f46..8fb3c5f 100644
--- a/common.sh
+++ b/common.sh
@@ -155,6 +155,7 @@ parse_proc_mounts () {
 	done
 }
 
+# add forth parameter to pickup btrfs subvol info
 parsefstab () {
 	while read -r line; do
 		case "$line" in
@@ -165,12 +166,22 @@ parsefstab () {
 				set -f
 				set -- $line
 				set +f
-				printf '%s %s %s\n' "$1" "$2" "$3"
+				printf '%s %s %s %s\n' "$1" "$2" "$3" "$4"
 			;;
 		esac
 	done
 }
 
+#check_btrfs_mounted $bootsv $bootuuid)
+check_btrfs_mounted () {
+	bootsv="$1"
+	bootuuid="$2"
+	bootdev=$(blkid | grep "$bootuuid" | cut -d ':' -f  1)
+	bindfrom=$(grep " btrfs " /proc/self/mountinfo |
+		   grep " $bootdev " | grep " /$bootsv " | cut -d ' ' -f 5)
+	printf "%s" "$bindfrom"
+}
+
 unescape_mount () {
 	printf %s "$1" | \
 		sed 's/\\011/	/g; s/\\012/\n/g; s/\\040/ /g; s/\\134/\\/g'
diff --git a/linux-boot-prober b/linux-boot-prober
index e32dc84..2a60fa2 100755
--- a/linux-boot-prober
+++ b/linux-boot-prober
@@ -5,16 +5,143 @@ set -e
 
 newns "$@"
 require_tmpdir
+ERR="n"
+
+tmpmnt=/var/lib/os-prober/mount
+if [ ! -d "$tmpmnt" ]; then
+	mkdir "$tmpmnt"
+fi
+
+mounted=
+bootmnt=
+bootsv=
+bootuuid=
 
 grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true
 
-partition="$1"
+if [ -z "$1" ]; then
+	ERR=y
+elif [ "$1" = btrfs -a -z "$2" ]; then
+	ERR=y
+elif [ "$1" = btrfs -a -z "$3" ]; then
+	ERR=y
+elif [ "$1" = btrfs ]; then
+	type=btrfs
+	echo "$2" | grep -q "^UUID=" || ERR=y
+	echo "$3" | grep -q "^subvol=" || ERR=y
+	export "$2"
+	export "$3"
+	partition=$(blkid | grep "$UUID" | cut -d ':' -f 1 | tr '\n' ' ' | cut -d ' ' -f 1)
+	debug "btrfs: partition=$partition, UUID=$UUID, subvol=$subvol"
+else
+	partition="$1"
+	type=other
+fi
 
-if [ -z "$partition" ]; then
+if [ "x$ERR" != xn ]; then
 	echo "usage: linux-boot-prober partition" >&2
+	echo "       linux-boot-prober btrfs UUID=<> subvol=<>" >&2
 	exit 1
 fi
 
+if [ "$type" = btrfs ]; then
+	# handle all of the btrfs stuff here
+	if [ ! -e "/proc/self/mountinfo" ]; then
+		warn "/proc/self/mountinfo does not exist, exiting"
+		umount "$tmpmnt" 2>/dev/null
+		rmdir "$tmpmnt" 2>/dev/null
+		exit 1
+	fi
+	mpoint=$(grep "btrfs" /proc/self/mountinfo | grep " /$subvol " | grep " $partition " | cut -d ' ' -f 5)
+	if [ "$mpoint" = "/" ]; then
+		warn "specifying active root not valid, exiting"
+		umount "$tmpmnt" 2>/dev/null
+		rmdir "$tmpmnt" 2>/dev/null
+		exit 1
+	fi
+	if [ "$mpoint" = "$tmpmnt" ]; then
+		warn "btrfs subvol=$subvool, UUID=$UUID, already mounted on $tmpmnt **ERROR**"
+		umount "$tmpmnt" 2>/dev/null
+		rmdir "$tmpmnt" 2>/dev/null
+		exit 1
+	fi
+	if [ -z "$mpoint" ]; then
+		# mount the btrfs root
+		if ! mount -o subvol=$subvol -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
+			rmdir "$tmpmnt" 2>/dev/null
+			exit 1
+		fi
+	else
+		# bind-mount
+		if ! mount -o bind "$mpoint" "$tmpmnt" 2>/dev/null; then
+			warn "error mounting btrfs bindfrom=$mpoint subvol=$subvol UUID=$UUID"
+			umount "$tmpmnt/boot" 2>/dev/null
+			umount "$tmpmnt" 2>/dev/null
+			rmdir "$tmpmnt" 2>/dev/null
+			exit 1
+		fi
+	fi
+	debug "mounted btrfs $partition, subvol=$subvol on $tmpmnt"
+	if [ ! -e "$tmpmnt/etc/fstab" ]; then
+		warn "btrfs subvol=$subvol not root"
+		umount "$tmpmnt" 2>/dev/null
+		rmdir "$tmpmnt" 2>/dev/null
+		exit 1
+	fi
+	bootmnt=$(parsefstab < "$tmpmnt/etc/fstab" | grep " /boot ") || true
+	if [ -z "$bootmnt" ]; then
+		# /boot is part of the root
+		bootpart="$partition"
+		bootsv="$subvol"
+	elif echo "$bootmnt" | cut -d ' ' -f 3 | grep -q "btrfs"; then
+		# separate btrfs /boot subvolume
+		bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | grep "^subvol=" | sed "s/subvol=//" )
+		bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | grep "^UUID=" | sed "s/UUID=//" )
+		debug "mounting btrfs $tmpmnt/boot UUID=$bootuuid subvol=$bootsv"
+		bindfrom=$(check_btrfs_mounted $bootsv $bootuuid)
+		if [ -n "$bindfrom" ]; then
+			# already mounted some place
+			if ! mount -o bind $bindfrom "$tmpmnt/boot" 2>/dev/null; then
+				warn "error bind mounting btrfs boot subvol=$bootsv, from=$bindfrom"
+				umount "$tmpmnt/boot" 2>/dev/null
+				umount "$tmpmnt" 2>/dev/null
+				rmdir "$tmpmnt" 2>/dev/null
+				exit 1
+			fi
+		elif ! mount -o subvol=$bootsv -t btrfs -U $bootuuid "$tmpmnt/boot" 2>/dev/null; then
+			warn "error mounting btrfs boot partition subvol=$bootsv, UUID=$bootuuid"
+			umount "$tmpmnt/boot" 2>/dev/null
+			umount "$tmpmnt" 2>/dev/null
+			rmdir "$tmpmnt" 2>/dev/null
+			exit 1
+		fi
+		bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " /$bootsv " | cut -d ' ' -f 10)
+	else
+		# non-btrfs partition or logical volume
+		linux_mount_boot $partition $tmpmnt
+		bootpart="${mountboot%% *}"
+		bootsv=
+	fi
+
+	test="/usr/lib/linux-boot-probes/mounted/40grub2"
+	if [ -f $test ] && [ -x $test ]; then
+		debug "running $test $partition $bootpart $tmpmnt $type $subvol $bootsv"
+		if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvol" "$bootsv"; then
+			debug "$test succeeded"
+		fi
+	fi
+	umount "$tmpmnt/boot" 2>/dev/null || true
+	if ! umount "$tmpmnt" 2>/dev/null; then
+		warn "problem umount $tmpmnt"
+	fi
+	rmdir "$tmpmnt" 2>/dev/null || true
+
+	exit 0
+fi
+
 if ! mapped="$(mapdevfs "$partition")"; then
 	log "Device '$partition' does not exist; skipping"
 	continue
@@ -22,8 +149,8 @@ fi
 
 if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map"; then
 	for test in /usr/lib/linux-boot-probes/*; do
-		debug "running $test"
 		if [ -x $test ] && [ -f $test ]; then
+			debug "running $test"
 			if $test "$partition"; then
 				debug "linux detected by $test"
 				break
diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
index 885614e..db5cbfd 100755
--- a/linux-boot-probes/mounted/common/40grub2
+++ b/linux-boot-probes/mounted/common/40grub2
@@ -2,17 +2,30 @@
 . /usr/share/os-prober/common.sh
 set -e
 
+# add support for btrfs with no separate /boot
+# that is, rootsv = bootsv
 partition="$1"
 bootpart="$2"
 mpoint="$3"
 type="$4"
+rootsv="$5"
+bootsv="$6"
 
 found_item=0
 
 entry_result () {
+	if [ "x$type" = "xbtrfs" -a "$partition" = "$bootpart" ]; then
+		# trim off the leading subvol
+		kernelfile=$(echo "$kernel" | cut -d '/' -f 2- | cut -d '/' -f 2-)
+		if [ "x$rootsv" != "x$bootsv" ]; then
+		   kernelfile="/boot/$kernelfile"
+		fi
+	else
+		kernelfile=$kernel
+	fi
 	if [ "$ignore_item" = 0 ] && \
 	   [ -n "$kernel" ] && \
-	   [ -e "$mpoint/$kernel" ]; then
+	   [ -e "$mpoint/$kernelfile" ]; then
 		result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
 		found_item=1
 	fi
diff --git a/os-prober b/os-prober
index 8852887..482c3c2 100755
--- a/os-prober
+++ b/os-prober
@@ -76,9 +76,12 @@ partitions () {
 
 	# 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 |
+		echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name 2>/dev/null |
 			sed "s|-|--|g;s|^[[:space:]]*\(.*\):\(.*\)$|/dev/mapper/\1-\2|")"
 	fi
+
+	# now lets make sure we got all of the btrfs partitions and disks
+	blkid | grep 'TYPE="btrfs"' | cut -d ':' -f 1
 }
 
 parse_proc_swaps () {
@@ -136,6 +139,8 @@ if [ -f /proc/mdstat ] ; then
 	grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true
 fi
 
+: >"$OS_PROBER_TMP/btrfs-vols"
+
 for partition in $(partitions); do
 	if ! mapped="$(mapdevfs "$partition")"; then
 		log "Device '$partition' does not exist; skipping"
@@ -154,7 +159,26 @@ for partition in $(partitions); do
 		continue
 	fi
 
-	if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
+	# do btrfs processing here; both mounted and unmounted will
+	# 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
+		uuid=$(blkid -o value -s UUID $mapped)
+		if grep -q "^$uuid" "$OS_PROBER_TMP/btrfs-vols" ; then
+			continue
+		fi
+		debug "btrfs volume uuid=$uuid partition=$partition"
+		echo "$uuid" >>"$OS_PROBER_TMP/btrfs-vols"
+		test="/usr/lib/os-probes/50mounted-tests"
+		if [ -f "$test" ] && [ -x "$test" ]; then
+			debug "running $test on btrfs $partition"
+			if "$test" btrfs "$uuid" "$partition"; then
+				debug "os detected by $test"
+				continue
+			fi
+		fi
+
+	elif ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
 		for test in /usr/lib/os-probes/*; do
 			if [ -f "$test" ] && [ -x "$test" ]; then
 				debug "running $test on $partition"
diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests
index 2951ef9..e33eb82 100755
--- a/os-probes/common/50mounted-tests
+++ b/os-probes/common/50mounted-tests
@@ -19,19 +19,31 @@ do_unmount() {
 	rmdir "$tmpmnt" || true
 }
 
-types="$(fs_type "$partition")"
+if [ "x$1" = xbtrfs ]; then
+	types=btrfs
+	if [ -z "$2" -o -z "$3" ]; then
+		debug "missing btrfs parameters, exiting"
+		exit 1
+	fi
+	UUID="$2"
+	BTRFSDEV="$3"
+else
+	partition="$1"
+	types="$(fs_type "$partition")" || types=NOT-DETECTED
+fi
+
 if [ "$types" = NOT-DETECTED ]; then
 	debug "$1 type not recognised; skipping"
-	exit 0
+	exit 1
 elif [ "$types" = swap ]; then
 	debug "$1 is a swap partition; skipping"
-	exit 0
+	exit 1
 elif [ "$types" = crypto_LUKS ]; then
 	debug "$1 is a LUKS partition; skipping"
-	exit 0
+	exit 1
 elif [ "$types" = LVM2_member ]; then
 	debug "$1 is an LVM member; skipping"
-	exit 0
+	exit 1
 elif [ "$types" = ntfs ]; then
 	if type ntfs-3g >/dev/null 2>&1; then
 		types='ntfs-3g ntfs'
@@ -40,7 +52,7 @@ elif [ -z "$types" ]; then
 	if type cryptsetup >/dev/null 2>&1 && \
 	   cryptsetup luksDump "$partition" >/dev/null 2>&1; then
 		debug "$1 is a LUKS partition; skipping"
-		exit 0
+		exit 1
 	fi
 	for type in $(grep -v nodev /proc/filesystems); do
 		# hfsplus filesystems are mountable as hfs. Try hfs last so
@@ -63,6 +75,108 @@ if [ ! -d "$tmpmnt" ]; then
 fi
 
 mounted=
+
+# 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
+		debug "btrfs volume $UUID mounted"
+	else
+		warn "cannot mount btrfs volume $UUID, exiting"
+		rmdir "$tmpmnt" || true
+		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)
+        if ! umount "$tmpmnt"; then
+            warn "failed to umount btrfs volume on $tmpmnt"
+            rmdir "$tmpmnt" || true
+            exit 1
+        fi
+
+	found=
+	mounted=
+
+	mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | cut -d ' ' -f 5)"
+	if [ -n "$mpoint" -a "x$mpoint" = "x/" ]; then
+		debug "This is the root for the running system" #running system must be done elsewhere
+	else
+	    #partition was not root of running system, so lets look for bootable subvols
+	    if [ -n "$mpoint" ] ; then
+		mounted=1  #partition was already mounted,so lets not unmount it when done
+	    else
+		# again, do not mount btrfs ro
+		mount -t btrfs -U "$UUID" "$tmpmnt"
+		mpoint="$tmpmnt"
+	    fi
+
+	    test="/usr/libexec/os-probes/mounted/90linux-distro"
+	    if [ -f "$test" ] && [ -x "$test" ]; then
+		debug "running subtest $test"
+		if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID"; then
+		    debug "os found by subtest $test on $partition"
+		    found=1
+		fi
+	    fi
+	    if [ -z "$mounted" ]; then
+		if ! umount "$tmpmnt"; then
+		    warn "failed to umount $tmpmnt"
+		fi
+	    fi
+	fi
+
+	if [ -z "$subvols" ]; then
+	        debug "no subvols found on btrfs volume $UUID"
+	else
+		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
+			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
+			fi
+			if [ -z "$mounted" ]; then
+				if ! umount "$tmpmnt"; then
+				    warn "failed to umount $tmpmnt"
+				fi
+			fi
+		done
+	fi
+	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
diff --git a/os-probes/mounted/common/90linux-distro b/os-probes/mounted/common/90linux-distro
index badfbb1..9bc5154 100755
--- a/os-probes/mounted/common/90linux-distro
+++ b/os-probes/mounted/common/90linux-distro
@@ -7,6 +7,8 @@ set -e
 partition="$1"
 dir="$2"
 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
@@ -143,7 +145,11 @@ if (ls "$dir"/lib*/ld*.so* && [ -d "$dir/boot" ] || ls "$dir"/usr/lib*/ld*.so*)
 	fi
 	
         label="$(count_next_label "$short")"
-	result "$partition:$long:$label:linux"
+	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
 else
 	exit 1
+107 −0
Original line number Diff line number Diff line
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