Blame SOURCES/0008-Improve-btrfs-detection-support-888341.patch

2e96e6
From 916d8338b56b514b8f0ef72530a627fa28463140 Mon Sep 17 00:00:00 2001
2e96e6
From: Gene Czarcinski <gczarcinski@gmail.com>
2e96e6
Date: Thu, 31 Jan 2013 23:58:53 +0330
2e96e6
Subject: [PATCH 08/18] Improve btrfs detection support (#888341)
2e96e6
2e96e6
Enables os-prober to detect multiple installations that live in separate
2e96e6
btrfs storage pools.
2e96e6
2e96e6
Resolves: rhbz#888341
2e96e6
---
2e96e6
 README.btrfs                             |  15 ++++
2e96e6
 common.sh                                |  13 ++-
2e96e6
 linux-boot-prober                        | 133 ++++++++++++++++++++++++++++++-
2e96e6
 linux-boot-probes/mounted/common/40grub2 |  12 ++-
2e96e6
 os-prober                                |  28 ++++++-
2e96e6
 os-probes/common/50mounted-tests         |  98 +++++++++++++++++++++--
2e96e6
 os-probes/mounted/common/90linux-distro  |   8 +-
2e96e6
 7 files changed, 293 insertions(+), 14 deletions(-)
2e96e6
 create mode 100644 README.btrfs
2e96e6
2e96e6
diff --git a/README.btrfs b/README.btrfs
2e96e6
new file mode 100644
2e96e6
index 0000000..f9b4d45
2e96e6
--- /dev/null
2e96e6
+++ b/README.btrfs
2e96e6
@@ -0,0 +1,15 @@
2e96e6
+BTRFS is a new filesystem which combines the filesystem with logical volume
2e96e6
+management (subvolumes).  For further information, see:
2e96e6
+      https://btrfs.wiki.kernel.org/index.php/Main_Page
2e96e6
+      https://btrfs.wiki.kernel.org/index.php/FAQ
2e96e6
+
2e96e6
+In order to support BTRFS, a number of changes were necessary to os-prober,
2e96e6
+os-probes/common/50mounted-tests, os-probes/mounted/common/90linux-distro,
2e96e6
+linux-boot-prober, and linux-boot-probes/common/50mounted-tests.
2e96e6
+
2e96e6
+The biggest impact will be to grub2 where there is additional information
2e96e6
+output by os-prober and where, if a BTRFS subvolume is being used for root,
2e96e6
+the parameters for linux-boot-prober have changed.
2e96e6
+
2e96e6
+Sun 30 Dec 2012 11:49:52 AM EST Gene Czarcinski <gene@czarc.net>
2e96e6
+
2e96e6
diff --git a/common.sh b/common.sh
2e96e6
index 19ef90a..85d13f0 100644
2e96e6
--- a/common.sh
2e96e6
+++ b/common.sh
2e96e6
@@ -127,6 +127,7 @@ parse_proc_mounts () {
2e96e6
 	done
2e96e6
 }
2e96e6
 
2e96e6
+# add forth parameter to pickup btrfs subvol info
2e96e6
 parsefstab () {
2e96e6
 	while read -r line; do
2e96e6
 		case "$line" in
2e96e6
@@ -137,12 +138,22 @@ parsefstab () {
2e96e6
 				set -f
2e96e6
 				set -- $line
2e96e6
 				set +f
2e96e6
-				printf '%s %s %s\n' "$1" "$2" "$3"
2e96e6
+				printf '%s %s %s %s\n' "$1" "$2" "$3" "$4"
2e96e6
 			;;
2e96e6
 		esac
2e96e6
 	done
2e96e6
 }
2e96e6
 
2e96e6
+#check_btrfs_mounted $bootsv $bootuuid)
2e96e6
+check_btrfs_mounted () {
2e96e6
+	bootsv="$1"
2e96e6
+	bootuuid="$2"
2e96e6
+	bootdev=$(blkid | grep "$bootuuid" | cut -d ':' -f  1)
2e96e6
+	bindfrom=$(grep " btrfs " /proc/self/mountinfo | 
2e96e6
+		   grep " $bootdev " | grep " /$bootsv " | cut -d ' ' -f 5)
2e96e6
+	printf "%s" "$bindfrom"
2e96e6
+}
2e96e6
+
2e96e6
 unescape_mount () {
2e96e6
 	printf %s "$1" | \
2e96e6
 		sed 's/\\011/	/g; s/\\012/\n/g; s/\\040/ /g; s/\\134/\\/g'
2e96e6
diff --git a/linux-boot-prober b/linux-boot-prober
2e96e6
index e32dc84..505c2fd 100755
2e96e6
--- a/linux-boot-prober
2e96e6
+++ b/linux-boot-prober
2e96e6
@@ -5,16 +5,143 @@ set -e
2e96e6
 
2e96e6
 newns "$@"
2e96e6
 require_tmpdir
2e96e6
+ERR="n"
2e96e6
+
2e96e6
+tmpmnt=/var/lib/os-prober/mount
2e96e6
+if [ ! -d "$tmpmnt" ]; then
2e96e6
+	mkdir "$tmpmnt"
2e96e6
+fi
2e96e6
+
2e96e6
+mounted=
2e96e6
+bootmnt=
2e96e6
+bootsv=
2e96e6
+bootuuid=
2e96e6
 
2e96e6
 grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true
2e96e6
 
2e96e6
-partition="$1"
2e96e6
+if [ -z "$1" ]; then
2e96e6
+	ERR=y
2e96e6
+elif [ "$1" = btrfs -a -z "$2" ]; then
2e96e6
+	ERR=y
2e96e6
+elif [ "$1" = btrfs -a -z "$3" ]; then
2e96e6
+	ERR=y
2e96e6
+elif [ "$1" = btrfs ]; then
2e96e6
+	type=btrfs
2e96e6
+	echo "$2" | grep -q "^UUID=" || ERR=y
2e96e6
+	echo "$3" | grep -q "^subvol=" || ERR=y	
2e96e6
+	export "$2"
2e96e6
+	export "$3"
2e96e6
+	partition=$(blkid | grep "$UUID" | cut -d ':' -f 1 | tr '\n' ' ' | cut -d ' ' -f 1)
2e96e6
+	debug "btrfs: partition=$partition, UUID=$UUID, subvol=$subvol"
2e96e6
+else
2e96e6
+	partition="$1"
2e96e6
+	type=other
2e96e6
+fi
2e96e6
 
2e96e6
-if [ -z "$partition" ]; then
2e96e6
+if [ "x$ERR" != xn ]; then
2e96e6
 	echo "usage: linux-boot-prober partition" >&2
2e96e6
+	echo "       linux-boot-prober btrfs UUID=<> subvol=<>" >&2
2e96e6
 	exit 1
2e96e6
 fi
2e96e6
 
2e96e6
+if [ "$type" = btrfs ]; then
2e96e6
+	# handle all of the btrfs stuff here
2e96e6
+	if [ ! -e "/proc/self/mountinfo" ]; then
2e96e6
+		warn "/proc/self/mountinfo does not exist, exiting"
2e96e6
+		umount "$tmpmnt" 2>/dev/null
2e96e6
+		rmdir "$tmpmnt" 2>/dev/null
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	mpoint=$(grep "btrfs" /proc/self/mountinfo | grep " /$subvol " | grep " $partition " | cut -d ' ' -f 5)
2e96e6
+	if [ "$mpoint" = "/" ]; then
2e96e6
+		warn "specifying active root not valid, exiting"
2e96e6
+		umount "$tmpmnt" 2>/dev/null
2e96e6
+		rmdir "$tmpmnt" 2>/dev/null
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	if [ "$mpoint" = "$tmpmnt" ]; then
2e96e6
+		warn "btrfs subvol=$subvool, UUID=$UUID, already mounted on $tmpmnt **ERROR**"
2e96e6
+		umount "$tmpmnt" 2>/dev/null
2e96e6
+		rmdir "$tmpmnt" 2>/dev/null
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	if [ -z "$mpoint" ]; then
2e96e6
+		# mount the btrfs root
2e96e6
+		if ! mount -o subvol=$subvol -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then
2e96e6
+			warn "error mounting btrfs subvol=$subvol UUID=$UUID"
2e96e6
+			umount "$tmpmnt/boot" 2>/dev/null
2e96e6
+			umount "$tmpmnt" 2>/dev/null
2e96e6
+			rmdir "$tmpmnt" 2>/dev/null
2e96e6
+			exit 1
2e96e6
+		fi
2e96e6
+	else
2e96e6
+		# bind-mount
2e96e6
+		if ! mount -o bind "$mpoint" "$tmpmnt" 2>/dev/null; then
2e96e6
+			warn "error mounting btrfs bindfrom=$mpoint subvol=$subvol UUID=$UUID"
2e96e6
+			umount "$tmpmnt/boot" 2>/dev/null
2e96e6
+			umount "$tmpmnt" 2>/dev/null
2e96e6
+			rmdir "$tmpmnt" 2>/dev/null
2e96e6
+			exit 1
2e96e6
+		fi
2e96e6
+	fi
2e96e6
+	debug "mounted btrfs $partition, subvol=$subvol on $tmpmnt"
2e96e6
+	if [ ! -e "$tmpmnt/etc/fstab" ]; then
2e96e6
+		warn "btrfs subvol=$subvol not root"
2e96e6
+		umount "$tmpmnt" 2>/dev/null
2e96e6
+		rmdir "$tmpmnt" 2>/dev/null
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	bootmnt=$(parsefstab < "$tmpmnt/etc/fstab" | grep " /boot ") || true
2e96e6
+	if [ -z "$bootmnt" ]; then
2e96e6
+		# /boot is part of the root
2e96e6
+		bootpart="$partition"
2e96e6
+		bootsv="$subvol"
2e96e6
+	elif echo "$bootmnt" | cut -d ' ' -f 3 | grep -q "btrfs"; then
2e96e6
+		# separate btrfs /boot subvolume
2e96e6
+		bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | grep "^subvol=" | sed "s/subvol=//" )
2e96e6
+		bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | grep "^UUID=" | sed "s/UUID=//" )
2e96e6
+		debug "mounting btrfs $tmpmnt/boot UUID=$bootuuid subvol=$bootsv"
2e96e6
+		bindfrom=$(check_btrfs_mounted $bootsv $bootuuid)
2e96e6
+		if [ -n "$bindfrom" ]; then
2e96e6
+			# already mounted some place
2e96e6
+			if ! mount -o bind $bindfrom "$tmpmnt/boot" 2>/dev/null; then
2e96e6
+				warn "error bind mounting btrfs boot subvol=$bootsv, from=$bindfrom"
2e96e6
+				umount "$tmpmnt/boot" 2>/dev/null
2e96e6
+				umount "$tmpmnt" 2>/dev/null
2e96e6
+				rmdir "$tmpmnt" 2>/dev/null
2e96e6
+				exit 1
2e96e6
+			fi
2e96e6
+		elif ! mount -o subvol=$bootsv -t btrfs -U $bootuuid "$tmpmnt/boot" 2>/dev/null; then
2e96e6
+			warn "error mounting btrfs boot partition subvol=$bootsv, UUID=$bootuuid"
2e96e6
+			umount "$tmpmnt/boot" 2>/dev/null
2e96e6
+			umount "$tmpmnt" 2>/dev/null
2e96e6
+			rmdir "$tmpmnt" 2>/dev/null
2e96e6
+			exit 1
2e96e6
+		fi
2e96e6
+		bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " /$bootsv " | cut -d ' ' -f 10)
2e96e6
+	else
2e96e6
+		# non-btrfs partition or logical volume
2e96e6
+		linux_mount_boot $partition $tmpmnt
2e96e6
+		bootpart="${mountboot%% *}"
2e96e6
+		bootsv=
2e96e6
+	fi
2e96e6
+	
2e96e6
+	test="/usr/lib/linux-boot-probes/mounted/40grub2"
2e96e6
+	if [ -f $test ] && [ -x $test ]; then
2e96e6
+		debug "running $test $partition $bootpart $tmpmnt $type $subvol $bootsv"
2e96e6
+		if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvol" "$bootsv"; then
2e96e6
+			debug "$test succeeded"
2e96e6
+		fi
2e96e6
+	fi
2e96e6
+	umount "$tmpmnt/boot" 2>/dev/null || true
2e96e6
+	if ! umount "$tmpmnt" 2>/dev/null; then
2e96e6
+		warn "problem umount $tmpmnt"
2e96e6
+	fi
2e96e6
+	rmdir "$tmpmnt" 2>/dev/null || true
2e96e6
+
2e96e6
+	exit 0
2e96e6
+fi
2e96e6
+
2e96e6
 if ! mapped="$(mapdevfs "$partition")"; then
2e96e6
 	log "Device '$partition' does not exist; skipping"
2e96e6
 	continue
2e96e6
@@ -22,8 +149,8 @@ fi
2e96e6
 
2e96e6
 if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map"; then
2e96e6
 	for test in /usr/lib/linux-boot-probes/*; do
2e96e6
-		debug "running $test"
2e96e6
 		if [ -x $test ] && [ -f $test ]; then
2e96e6
+			debug "running $test"
2e96e6
 			if $test "$partition"; then
2e96e6
 				debug "linux detected by $test"
2e96e6
 				break
2e96e6
diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
2e96e6
index 885614e..11ffa1b 100755
2e96e6
--- a/linux-boot-probes/mounted/common/40grub2
2e96e6
+++ b/linux-boot-probes/mounted/common/40grub2
2e96e6
@@ -2,17 +2,27 @@
2e96e6
 . /usr/share/os-prober/common.sh
2e96e6
 set -e
2e96e6
 
2e96e6
+# add support for btrfs with no separate /boot
2e96e6
+# that is, rootsv = bootsv
2e96e6
 partition="$1"
2e96e6
 bootpart="$2"
2e96e6
 mpoint="$3"
2e96e6
 type="$4"
2e96e6
+rootsv="$5"
2e96e6
+bootsv="$6"
2e96e6
 
2e96e6
 found_item=0
2e96e6
 
2e96e6
 entry_result () {
2e96e6
+	if [ "x$type" = "xbtrfs" -a "$rootsv" = "$bootsv" ]; then
2e96e6
+		# trim off the leading subvol
2e96e6
+		kernelfile=$(echo "$kernel" | cut -d '/' -f 2- | cut -d '/' -f 2-)
2e96e6
+	else
2e96e6
+		kernelfile=$kernel
2e96e6
+	fi
2e96e6
 	if [ "$ignore_item" = 0 ] && \
2e96e6
 	   [ -n "$kernel" ] && \
2e96e6
-	   [ -e "$mpoint/$kernel" ]; then
2e96e6
+	   [ -e "$mpoint/$kernelfile" ]; then
2e96e6
 		result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
2e96e6
 		found_item=1
2e96e6
 	fi
2e96e6
diff --git a/os-prober b/os-prober
2e96e6
index 99ede8e..ca8f5ab 100755
2e96e6
--- a/os-prober
2e96e6
+++ b/os-prober
2e96e6
@@ -64,9 +64,12 @@ partitions () {
2e96e6
 
2e96e6
 	# Also detect OSes on LVM volumes (assumes LVM is active)
2e96e6
 	if type lvs >/dev/null 2>&1; then
2e96e6
-		echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name |
2e96e6
+		echo "$(LVM_SUPPRESS_FD_WARNINGS=1 log_output lvs --noheadings --separator : -o vg_name,lv_name 2>/dev/null |
2e96e6
 			sed "s|-|--|g;s|^[[:space:]]*\(.*\):\(.*\)$|/dev/mapper/\1-\2|")"
2e96e6
 	fi
2e96e6
+
2e96e6
+	# now lets make sure we got all of the btrfs partitions and disks
2e96e6
+	blkid | grep btrfs | cut -d ':' -f 1
2e96e6
 }
2e96e6
 
2e96e6
 parse_proc_swaps () {
2e96e6
@@ -124,6 +127,8 @@ if [ -f /proc/mdstat ] ; then
2e96e6
 	grep "^md" /proc/mdstat | cut -d: -f2- | parse_proc_mdstat >"$OS_PROBER_TMP/raided-map" || true
2e96e6
 fi
2e96e6
 
2e96e6
+: >"$OS_PROBER_TMP/btrfs-vols"
2e96e6
+
2e96e6
 for partition in $(partitions); do
2e96e6
 	if ! mapped="$(mapdevfs "$partition")"; then
2e96e6
 		log "Device '$partition' does not exist; skipping"
2e96e6
@@ -142,7 +147,26 @@ for partition in $(partitions); do
2e96e6
 		continue
2e96e6
 	fi
2e96e6
 
2e96e6
-	if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
2e96e6
+	# do btrfs processing here; both mounted and unmounted will
2e96e6
+	# be handled by 50mounted-tests so we can do a subvol only once.
2e96e6
+	type=$(blkid -o value -s TYPE $mapped)
2e96e6
+	if [ "$type" = btrfs ]; then
2e96e6
+		uuid=$(blkid -o value -s UUID $mapped)
2e96e6
+		if grep -q "^$uuid" "$OS_PROBER_TMP/btrfs-vols" ; then
2e96e6
+			continue
2e96e6
+		fi
2e96e6
+		debug "btrfs volume uuid=$uuid partition=$partition"
2e96e6
+		echo "$uuid" >>"$OS_PROBER_TMP/btrfs-vols"
2e96e6
+		test="/usr/lib/os-probes/50mounted-tests"
2e96e6
+		if [ -f "$test" ] && [ -x "$test" ]; then
2e96e6
+			debug "running $test on btrfs $partition"
2e96e6
+			if "$test" btrfs "$uuid" "$partition"; then
2e96e6
+				debug "os detected by $test"
2e96e6
+		   		continue
2e96e6
+			fi
2e96e6
+		fi
2e96e6
+
2e96e6
+	elif ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
2e96e6
 		for test in /usr/lib/os-probes/*; do
2e96e6
 			if [ -f "$test" ] && [ -x "$test" ]; then
2e96e6
 				debug "running $test on $partition"
2e96e6
diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests
2e96e6
index 561163b..751999a 100755
2e96e6
--- a/os-probes/common/50mounted-tests
2e96e6
+++ b/os-probes/common/50mounted-tests
2e96e6
@@ -1,20 +1,36 @@
2e96e6
 #!/bin/sh
2e96e6
 # Sub-tests that require a mounted partition.
2e96e6
 set -e
2e96e6
-partition="$1"
2e96e6
 
2e96e6
 . /usr/share/os-prober/common.sh
2e96e6
 
2e96e6
-types="$(fs_type "$partition")" || types=NOT-DETECTED
2e96e6
+if [ "x$1" = xbtrfs ]; then
2e96e6
+	types=btrfs
2e96e6
+	if [ -z "$2" -o -z "$3" ]; then
2e96e6
+		debug "missing btrfs parameters, exiting"
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	UUID="$2"
2e96e6
+	BTRFSDEV="$3"
2e96e6
+else
2e96e6
+	partition="$1"
2e96e6
+	types="$(fs_type "$partition")" || types=NOT-DETECTED
2e96e6
+fi
2e96e6
+
2e96e6
 if [ "$types" = NOT-DETECTED ]; then
2e96e6
 	debug "$1 type not recognised; skipping"
2e96e6
-	exit 0
2e96e6
+	exit 1
2e96e6
+elif [ "x$types" = "x" ]; then
2e96e6
+	exit 1
2e96e6
+elif [ "$types" = LVM2_member ]; then
2e96e6
+	debug "skipping LVM2 Volume Group on $partition"
2e96e6
+	exit 1
2e96e6
 elif [ "$types" = swap ]; then
2e96e6
 	debug "$1 is a swap partition; skipping"
2e96e6
-	exit 0
2e96e6
+	exit 1
2e96e6
 elif [ "$types" = crypto_LUKS ]; then
2e96e6
 	debug "$1 is a LUKS partition; skipping"
2e96e6
-	exit 0
2e96e6
+	exit 1
2e96e6
 elif [ "$types" = ntfs ]; then
2e96e6
 	if type ntfs-3g >/dev/null 2>&1; then
2e96e6
 		types='ntfs-3g ntfs'
2e96e6
@@ -23,7 +39,7 @@ elif [ -z "$types" ]; then
2e96e6
 	if type cryptsetup >/dev/null 2>&1 && \
2e96e6
 	   cryptsetup luksDump "$partition" >/dev/null 2>&1; then
2e96e6
 		debug "$1 is a LUKS partition; skipping"
2e96e6
-		exit 0
2e96e6
+		exit 1
2e96e6
 	fi
2e96e6
 	for type in $(grep -v nodev /proc/filesystems); do
2e96e6
 		# hfsplus filesystems are mountable as hfs. Try hfs last so
2e96e6
@@ -46,6 +62,76 @@ if [ ! -d "$tmpmnt" ]; then
2e96e6
 fi
2e96e6
 
2e96e6
 mounted=
2e96e6
+
2e96e6
+# all btrfs processing here.  Handle both unmounted and
2e96e6
+# mounted subvolumes.
2e96e6
+if [ "$types" = btrfs ]; then
2e96e6
+	partition="$BTRFSDEV"
2e96e6
+	debug "begin btrfs processing for $UUID"
2e96e6
+	# note that the btrfs volume must not be mounted ro
2e96e6
+	if mount -t btrfs -U "$UUID" "$tmpmnt"  2>/dev/null; then
2e96e6
+		debug "btrfs volume $UUID mounted"
2e96e6
+	else
2e96e6
+		warn "cannot mount btrfs volume $UUID, exiting"
2e96e6
+		rmdir "$tmpmnt" || true
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	# besides regular subvols, get ro and snapshot so thet can be excluded
2e96e6
+        subvols=$(btrfs subvolume list "$tmpmnt" | cut -d ' ' -f 9)
2e96e6
+        rosubvols=$(btrfs subvolume list -r "$tmpmnt" | cut -d ' ' -f 9)
2e96e6
+        sssubvols=$(btrfs subvolume list -s "$tmpmnt" | cut -d ' ' -f 9)
2e96e6
+        if ! umount "$tmpmnt"; then
2e96e6
+            warn "failed to umount btrfs volume on $tmpmnt"
2e96e6
+            rmdir "$tmpmnt" || true
2e96e6
+            exit 1
2e96e6
+        fi
2e96e6
+	if [ -z "$subvols" ]; then
2e96e6
+		debug "no subvols found on btrfs volume $UUID"
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+	found=
2e96e6
+        for subvol in $subvols; do
2e96e6
+		debug "begin btrfs processing for $UUID subvol=$subvol"
2e96e6
+		if echo "$rosubvols" | grep -q -x "$subvol"; then
2e96e6
+			continue
2e96e6
+		fi
2e96e6
+		if echo "$sssubvols" | grep -q -x "$subvol"; then
2e96e6
+			continue
2e96e6
+		fi
2e96e6
+		mounted=
2e96e6
+		mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)"
2e96e6
+		if [ -n "$mpoint" ]; then
2e96e6
+			if [ "x$mpoint" = "x/" ]; then
2e96e6
+				continue # this is the root for the running system
2e96e6
+			fi
2e96e6
+			mounted=1
2e96e6
+		else
2e96e6
+			# again, do not mount btrfs ro
2e96e6
+			mount -t btrfs -o subvol="$subvol" -U "$UUID" "$tmpmnt"
2e96e6
+			mpoint="$tmpmnt"
2e96e6
+		fi
2e96e6
+		test="/usr/lib/os-probes/mounted/90linux-distro"
2e96e6
+		if [ -f "$test" ] && [ -x "$test" ]; then
2e96e6
+			debug "running subtest $test"
2e96e6
+			if "$test" "$partition" "$mpoint" btrfs "UUID=$UUID" "subvol=$subvol"; then
2e96e6
+				debug "os found by subtest $test on subvol $subvol"
2e96e6
+				found=1
2e96e6
+			fi
2e96e6
+		fi
2e96e6
+		if [ -z "$mounted" ]; then
2e96e6
+			if ! umount "$tmpmnt"; then
2e96e6
+			    warn "failed to umount $tmpmnt"
2e96e6
+			fi
2e96e6
+		fi
2e96e6
+	done
2e96e6
+	rmdir "$tmpmnt" || true
2e96e6
+	if [ "$found" ]; then
2e96e6
+		exit 0
2e96e6
+	else
2e96e6
+		exit 1
2e96e6
+	fi
2e96e6
+fi
2e96e6
+
2e96e6
 if type grub-mount >/dev/null 2>&1 && \
2e96e6
    type grub-probe >/dev/null 2>&1 && \
2e96e6
    grub-mount "$partition" "$tmpmnt" 2>/dev/null; then
2e96e6
diff --git a/os-probes/mounted/common/90linux-distro b/os-probes/mounted/common/90linux-distro
2e96e6
index 583a9ec..6b03c7a 100755
2e96e6
--- a/os-probes/mounted/common/90linux-distro
2e96e6
+++ b/os-probes/mounted/common/90linux-distro
2e96e6
@@ -7,6 +7,8 @@ set -e
2e96e6
 partition="$1"
2e96e6
 dir="$2"
2e96e6
 type="$3"
2e96e6
+uuid="$4"
2e96e6
+subvol="$5"
2e96e6
 
2e96e6
 # This test is inaccurate, but given separate / and /boot partitions and the
2e96e6
 # fact that only some architectures have ld-linux.so, I can't see anything
2e96e6
@@ -131,7 +133,11 @@ if (ls "$dir"/lib*/ld*.so*  && [ -d "$dir/boot" ] || ls "$dir"/usr/lib*/ld*.so*)
2e96e6
 	fi
2e96e6
 	
2e96e6
         label="$(count_next_label "$short")"
2e96e6
-	result "$partition:$long:$label:linux"
2e96e6
+	if [ "x$type" = "xbtrfs" -a "x$uuid" != "x" -a "x$subvol" != "x" ]; then
2e96e6
+		result "$partition:$long:$label:linux:$type:$uuid:$subvol"
2e96e6
+	else
2e96e6
+		result "$partition:$long:$label:linux"
2e96e6
+	fi
2e96e6
 	exit 0
2e96e6
 else
2e96e6
 	exit 1
2e96e6
-- 
2e96e6
2.5.5
2e96e6