Bug#688336: os-probe: subvol: patches to provide bootloaders with all the subvolume info.
Here are corrected versions of these patches. Filesystem raid is
almost certainly a separate bug.
From 3d4b580dea4592793af3411fc0543af36de0e958 Mon Sep 17 00:00:00 2001
From: Michael Mestnik <cheako+github_com@mikemestnik.net>
Date: Fri, 9 Jun 2017 13:04:05 -0500
Subject: [PATCH 2/6] Process filesystem raid entries
---
common.sh | 14 ++++++++++++--
os-prober | 5 +++++
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/common.sh b/common.sh
index e1646d4..d6fee58 100644
--- a/common.sh
+++ b/common.sh
@@ -146,12 +146,22 @@ is_dos_extended_partition() {
return 1
}
+canonical_dev () {
+ local dev="${1#/dev/}"
+ local sys="$(find /sys/fs/btrfs -path \*/devices/"$dev")"
+ if [ -e "$sys" ]; then
+ echo /dev/"$(ls "${sys%/$dev}" | head -n1)"
+ else
+ echo "$1"
+ fi
+}
+
parse_proc_mounts () {
while read -r line; do
set -f
set -- $line
set +f
- printf '%s %s %s\n' "$(mapdevfs "$1")" "$2" "$3"
+ printf '%s %s %s\n' "$(canonical_dev "$(mapdevfs "$1")")" "$2" "$3"
done
}
@@ -245,7 +255,7 @@ linux_mount_boot () {
fi
fi
shift
- set -- "$(mapdevfs "$tmppart")" "$@"
+ set -- "$(canonical_dev "$(mapdevfs "$tmppart")")" "$@"
if grep -q "^$1 " "$OS_PROBER_TMP/mounted-map"; then
bindfrom="$(grep "^$1 " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2)"
diff --git a/os-prober b/os-prober
index a48863e..e4439a7 100755
--- a/os-prober
+++ b/os-prober
@@ -137,6 +137,11 @@ for partition in $(partitions); do
continue
fi
+ if ! [ "$mapped" = "$(canonical_dev "$mapped")" ]; then
+ log "Device '$mapped' is part of filesystem raid; skipping"
+ continue
+ fi
+
# Skip partitions used in software RAID arrays
if grep -q "^$mapped" "$OS_PROBER_TMP/raided-map" ; then
debug "$partition: part of software raid array"
--
2.11.0
From bd6d7a78e88eba3a03940e84f6e1222268ab5c8d Mon Sep 17 00:00:00 2001
From: Michael Mestnik <cheako+github_com@mikemestnik.net>
Date: Mon, 5 Jun 2017 11:08:42 -0500
Subject: [PATCH 5/6] Pass subvol data for /boot to bootloadter(s)
---
common.sh | 36 +++++++++++++++++++++++++++++
linux-boot-prober | 6 +++--
linux-boot-probes/common/50mounted-tests | 3 ++-
linux-boot-probes/mounted/common/40grub2 | 3 ++-
linux-boot-probes/mounted/common/90fallback | 5 ++--
linux-boot-probes/mounted/powerpc/40yaboot | 3 ++-
linux-boot-probes/mounted/sparc/50silo | 3 ++-
linux-boot-probes/mounted/x86/40grub | 3 ++-
linux-boot-probes/mounted/x86/50lilo | 3 ++-
9 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/common.sh b/common.sh
index 1001c74..ff278c3 100644
--- a/common.sh
+++ b/common.sh
@@ -253,6 +253,42 @@ linux_mount_boot () {
shift
set -- "$(mapdevfs "$tmppart")" "$@"
+ if bootsubvolid="$(echo "$4" | grep -o 'subvolid=[0-9][0-9]*')"; then
+ bootsubvolid="$(echo "$bootsubvolid" | cut -d= -f2-)"
+ if mount -o "subvolid=$bootsubvolid" "$1" "$tmpmnt/boot"; then
+ if [ "$bootsubvolid" = "$(get_default_subvolid "$tmpmnt/boot")" ]; then
+ mountboot="$1 1"
+ return
+ else
+ mountboot="$1 1 $bootsubvolid"
+ return
+ fi
+ else
+ debug "failed to subvolid-mount $1 onto $tmpmnt/boot"
+ mountboot="$1 0 $bootsubvolid"
+ return
+ fi
+ else
+ if bootsubvol="$(echo "$4" | grep -o 'subvol=[^,]*')"; then
+ bootsubvol="$(echo "$bootsubvol" | cut -d= -f2-)"
+ bootsubvol="${bootsubvol#/}"
+ if mount -o "subvol=${bootsubvol:=/}" "$1" "$tmpmnt/boot"; then
+ bootsubvolid="$(grep "^/dev/" /proc/mounts | parse_proc_mounts | grep " $tmpmnt/boot " | cut -d ' ' -f 4)"
+ if [ "$bootsubvolid" = "$(get_default_subvolid "$tmpmnt/boot")" ]; then
+ mountboot="$1 1"
+ return
+ else
+ mountboot="$1 1 ${bootsubvolid:-@$bootsubvol}"
+ return
+ fi
+ else
+ debug "failed to subvol-mount $1 onto $tmpmnt/boot"
+ mountboot="$1 0 @$bootsubvol"
+ return
+ fi
+ fi
+ fi
+
if grep -q "^$1 " "$OS_PROBER_TMP/mounted-map"; then
bindfrom="$(grep "^$1 " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2)"
bindfrom="$(unescape_mount "$bindfrom")"
diff --git a/linux-boot-prober b/linux-boot-prober
index 4a86119..ae34670 100755
--- a/linux-boot-prober
+++ b/linux-boot-prober
@@ -36,19 +36,21 @@ else
mpoint="$(unescape_mount "$mpoint")"
if [ "$mpoint" != "/target/boot" ] && [ "$mpoint" != "/target" ] && [ "$mpoint" != "/" ]; then
type="$(echo "$mrecord" | head -n1 | cut -d ' ' -f 3)"
- if ! grep -q " $mpoint/boot " "$OS_PROBER_TMP/mounted-map"; then
+ if ! bootrecord="$(grep -q " $mpoint/boot " "$OS_PROBER_TMP/mounted-map")"; then
linux_mount_boot "$partition" "$mpoint" "$subvolid"
set -- $mountboot
bootpart="$1"
bootmounted="$2"
+ bootsubvolid="$3"
else
bootpart="$partition"
bootmounted=0
+ bootsubvolid="$(echo "$bootrecord" | head -n1 | cut -d ' ' -f 4)"
fi
for test in /usr/lib/linux-boot-probes/mounted/*; do
if [ -f $test ] && [ -x $test ]; then
debug "running $test on mounted $partition"
- if $test "$partition" "$bootpart" "$mpoint" "$type" "$subvolid"; then
+ if $test "$partition" "$bootpart" "$mpoint" "$type" "$subvolid" "$bootsubvolid"; then
debug "$test succeeded"
break
fi
diff --git a/linux-boot-probes/common/50mounted-tests b/linux-boot-probes/common/50mounted-tests
index 65264f5..d150d23 100755
--- a/linux-boot-probes/common/50mounted-tests
+++ b/linux-boot-probes/common/50mounted-tests
@@ -67,11 +67,12 @@ if [ "$mounted" ]; then
set -- $mountboot
bootpart="$1"
bootmounted="$2"
+ bootsubvolid="$3"
for test in /usr/lib/linux-boot-probes/mounted/*; do
if [ -f "$test" ] && [ -x "$test" ]; then
debug "running $test $partition $bootpart $tmpmnt $type"
- if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvolid"; then
+ if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvolid" "$bootsubvolid"; then
debug "$test succeeded"
do_unmount
exit 0
diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
index 9d0b48c..06b8744 100755
--- a/linux-boot-probes/mounted/common/40grub2
+++ b/linux-boot-probes/mounted/common/40grub2
@@ -7,6 +7,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
found_item=0
@@ -14,7 +15,7 @@ entry_result () {
if [ "$ignore_item" = 0 ] && \
[ -n "$kernel" ] && \
[ -e "$mpoint/$kernel" ]; then
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$rootpart:$bootpart${bootsubvolid:+@$bootsubvolid}:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
fi
kernel=""
diff --git a/linux-boot-probes/mounted/common/90fallback b/linux-boot-probes/mounted/common/90fallback
index da0d22d..7a5b001 100755
--- a/linux-boot-probes/mounted/common/90fallback
+++ b/linux-boot-probes/mounted/common/90fallback
@@ -9,6 +9,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
mappedpartition=$(mapdevfs "$partition" 2>/dev/null) || mappedpartition="$partition"
@@ -39,13 +40,13 @@ for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \
for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null); do
if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then
initrd=$(echo "$initrd" | sed "s!^$mpoint!!")
- result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$partition:$kernbootpart${bootsubvolid:+@$bootsubvolid}::$kernbasefile:$initrd:root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
exitcode=0
foundinitrd=1
fi
done
if [ "$foundinitrd" = 0 ]; then
- result "$partition:$kernbootpart::$kernbasefile::root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$partition:$kernbootpart${bootsubvolid:+@$bootsubvolid}::$kernbasefile::root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
exitcode=0
fi
fi
diff --git a/linux-boot-probes/mounted/powerpc/40yaboot b/linux-boot-probes/mounted/powerpc/40yaboot
index 44ca0bc..05f4c82 100755
--- a/linux-boot-probes/mounted/powerpc/40yaboot
+++ b/linux-boot-probes/mounted/powerpc/40yaboot
@@ -7,6 +7,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
found_item=0
@@ -37,7 +38,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$rootpart:$bootpart${bootsubvolid:+@$bootsubvolid}:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
title=
diff --git a/linux-boot-probes/mounted/sparc/50silo b/linux-boot-probes/mounted/sparc/50silo
index da6579b..71098e1 100755
--- a/linux-boot-probes/mounted/sparc/50silo
+++ b/linux-boot-probes/mounted/sparc/50silo
@@ -7,6 +7,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
found_item=0
@@ -38,7 +39,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$rootpart:$bootpart${bootsubvolid:+@$bootsubvolid}:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
else
debug "cannot find $initrd, not recording"
diff --git a/linux-boot-probes/mounted/x86/40grub b/linux-boot-probes/mounted/x86/40grub
index 4e2eaf1..3cd2839 100755
--- a/linux-boot-probes/mounted/x86/40grub
+++ b/linux-boot-probes/mounted/x86/40grub
@@ -7,6 +7,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
found_item=0
@@ -14,7 +15,7 @@ entry_result () {
if [ "$ignore_item" = 0 ] && \
[ -n "$kernel" ] && \
[ -e "$mpoint/$kernel" ]; then
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$rootpart:$bootpart${bootsubvolid:+@$bootsubvolid}:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
fi
kernel=""
diff --git a/linux-boot-probes/mounted/x86/50lilo b/linux-boot-probes/mounted/x86/50lilo
index d0f3c1d..6918a1b 100755
--- a/linux-boot-probes/mounted/x86/50lilo
+++ b/linux-boot-probes/mounted/x86/50lilo
@@ -7,6 +7,7 @@ bootpart="$2"
mpoint="$3"
type="$4"
subvolid="$5"
+bootsubvolid="$6"
found_item=0
@@ -49,7 +50,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
+ result "$rootpart:$bootpart${bootsubvolid:+@$bootsubvolid}:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
else
debug "cannot find $kernel or $initrd, not recording"
--
2.11.0
From f1898d06ac877f013ba9f02b2ccc72e18a8b5d48 Mon Sep 17 00:00:00 2001
From: Michael Mestnik <cheako+github_com@mikemestnik.net>
Date: Tue, 6 Jun 2017 21:42:19 -0500
Subject: [PATCH 4/6] Handle subvol during boot probe
---
common.sh | 2 +-
linux-boot-prober | 18 ++++++++++--------
linux-boot-probes/common/50mounted-tests | 15 +++++++++++----
linux-boot-probes/mounted/common/40grub2 | 3 ++-
linux-boot-probes/mounted/common/90fallback | 5 +++--
linux-boot-probes/mounted/powerpc/40yaboot | 3 ++-
linux-boot-probes/mounted/sparc/50silo | 3 ++-
linux-boot-probes/mounted/x86/40grub | 3 ++-
linux-boot-probes/mounted/x86/50lilo | 3 ++-
9 files changed, 35 insertions(+), 20 deletions(-)
diff --git a/common.sh b/common.sh
index 8942a91..1001c74 100644
--- a/common.sh
+++ b/common.sh
@@ -166,7 +166,7 @@ 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
diff --git a/linux-boot-prober b/linux-boot-prober
index e32dc84..4a86119 100755
--- a/linux-boot-prober
+++ b/linux-boot-prober
@@ -9,6 +9,7 @@ require_tmpdir
grep "^/dev/" /proc/mounts | parse_proc_mounts >"$OS_PROBER_TMP/mounted-map" || true
partition="$1"
+subvolid="$2"
if [ -z "$partition" ]; then
echo "usage: linux-boot-prober partition" >&2
@@ -20,25 +21,26 @@ if ! mapped="$(mapdevfs "$partition")"; then
continue
fi
-if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map"; then
+if ! mrecord="$(grep "^$mapped [^ ]* [^ ]* $subvolid" "$OS_PROBER_TMP/mounted-map")"; then
for test in /usr/lib/linux-boot-probes/*; do
debug "running $test"
if [ -x $test ] && [ -f $test ]; then
- if $test "$partition"; then
+ if $test "$partition" "$subvolid"; then
debug "linux detected by $test"
break
fi
fi
done
else
- mpoint=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 2)
+ mpoint="$(echo "$mrecord" | head -n1 | cut -d ' ' -f 2)"
mpoint="$(unescape_mount "$mpoint")"
if [ "$mpoint" != "/target/boot" ] && [ "$mpoint" != "/target" ] && [ "$mpoint" != "/" ]; then
- type=$(grep "^$mapped " "$OS_PROBER_TMP/mounted-map" | head -n1 | cut -d " " -f 3)
+ type="$(echo "$mrecord" | head -n1 | cut -d ' ' -f 3)"
if ! grep -q " $mpoint/boot " "$OS_PROBER_TMP/mounted-map"; then
- linux_mount_boot "$partition" "$mpoint"
- bootpart="${mountboot%% *}"
- bootmounted="${mountboot#* }"
+ linux_mount_boot "$partition" "$mpoint" "$subvolid"
+ set -- $mountboot
+ bootpart="$1"
+ bootmounted="$2"
else
bootpart="$partition"
bootmounted=0
@@ -46,7 +48,7 @@ else
for test in /usr/lib/linux-boot-probes/mounted/*; do
if [ -f $test ] && [ -x $test ]; then
debug "running $test on mounted $partition"
- if $test "$partition" "$bootpart" "$mpoint" "$type"; then
+ if $test "$partition" "$bootpart" "$mpoint" "$type" "$subvolid"; then
debug "$test succeeded"
break
fi
diff --git a/linux-boot-probes/common/50mounted-tests b/linux-boot-probes/common/50mounted-tests
index ad68874..65264f5 100755
--- a/linux-boot-probes/common/50mounted-tests
+++ b/linux-boot-probes/common/50mounted-tests
@@ -14,6 +14,7 @@ do_unmount() {
}
partition="$1"
+subvolid="$2"
types="$(fs_type "$partition")"
if [ "$types" = NOT-DETECTED ]; then
@@ -48,6 +49,10 @@ if [ ! -d "$tmpmnt" ]; then
fi
mounted=
+if [ "$subvolid" ]; then
+ mount "$partition" "$tmpmnt" -o subvolid="$subvolid" &&
+ mounted=1
+else
if type grub-mount >/dev/null 2>&1 && \
type grub-probe >/dev/null 2>&1 && \
grub-mount "$partition" "$tmpmnt" 2>/dev/null; then
@@ -55,16 +60,18 @@ if type grub-mount >/dev/null 2>&1 && \
type="$(grub-probe -d "$partition" -t fs)"
[ "$type" ] || type=fuseblk
fi
+fi
if [ "$mounted" ]; then
- linux_mount_boot "$partition" "$tmpmnt"
- bootpart="${mountboot%% *}"
- mounted="${mountboot#* }"
+ linux_mount_boot "$partition" "$tmpmnt" "$subvolid"
+ set -- $mountboot
+ bootpart="$1"
+ bootmounted="$2"
for test in /usr/lib/linux-boot-probes/mounted/*; do
if [ -f "$test" ] && [ -x "$test" ]; then
debug "running $test $partition $bootpart $tmpmnt $type"
- if $test "$partition" "$bootpart" "$tmpmnt" "$type"; then
+ if $test "$partition" "$bootpart" "$tmpmnt" "$type" "$subvolid"; then
debug "$test succeeded"
do_unmount
exit 0
diff --git a/linux-boot-probes/mounted/common/40grub2 b/linux-boot-probes/mounted/common/40grub2
index 885614e..9d0b48c 100755
--- a/linux-boot-probes/mounted/common/40grub2
+++ b/linux-boot-probes/mounted/common/40grub2
@@ -6,6 +6,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
found_item=0
@@ -13,7 +14,7 @@ entry_result () {
if [ "$ignore_item" = 0 ] && \
[ -n "$kernel" ] && \
[ -e "$mpoint/$kernel" ]; then
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
fi
kernel=""
diff --git a/linux-boot-probes/mounted/common/90fallback b/linux-boot-probes/mounted/common/90fallback
index 9ff78e1..da0d22d 100755
--- a/linux-boot-probes/mounted/common/90fallback
+++ b/linux-boot-probes/mounted/common/90fallback
@@ -8,6 +8,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
mappedpartition=$(mapdevfs "$partition" 2>/dev/null) || mappedpartition="$partition"
@@ -38,13 +39,13 @@ for kernpat in /vmlinuz /vmlinux /boot/vmlinuz /boot/vmlinux "/boot/vmlinuz*" \
for initrd in $(eval ls "$initrdname" "$initrdname1" "$initrdname2" "$initrdname3" "$initrdname4" 2>/dev/null); do
if [ "$initrd" != "$kernfile" ] && [ -f "$initrd" ] && [ ! -L "$initrd" ]; then
initrd=$(echo "$initrd" | sed "s!^$mpoint!!")
- result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition"
+ result "$partition:$kernbootpart::$kernbasefile:$initrd:root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
exitcode=0
foundinitrd=1
fi
done
if [ "$foundinitrd" = 0 ]; then
- result "$partition:$kernbootpart::$kernbasefile::root=$mappedpartition"
+ result "$partition:$kernbootpart::$kernbasefile::root=$mappedpartition${subvolid:+ rootflags=subvolid=$subvolid}"
exitcode=0
fi
fi
diff --git a/linux-boot-probes/mounted/powerpc/40yaboot b/linux-boot-probes/mounted/powerpc/40yaboot
index 764621c..44ca0bc 100755
--- a/linux-boot-probes/mounted/powerpc/40yaboot
+++ b/linux-boot-probes/mounted/powerpc/40yaboot
@@ -6,6 +6,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
found_item=0
@@ -36,7 +37,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
title=
diff --git a/linux-boot-probes/mounted/sparc/50silo b/linux-boot-probes/mounted/sparc/50silo
index bb5c41c..da6579b 100755
--- a/linux-boot-probes/mounted/sparc/50silo
+++ b/linux-boot-probes/mounted/sparc/50silo
@@ -6,6 +6,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
found_item=0
@@ -37,7 +38,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
else
debug "cannot find $initrd, not recording"
diff --git a/linux-boot-probes/mounted/x86/40grub b/linux-boot-probes/mounted/x86/40grub
index 08f6605..4e2eaf1 100755
--- a/linux-boot-probes/mounted/x86/40grub
+++ b/linux-boot-probes/mounted/x86/40grub
@@ -6,6 +6,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
found_item=0
@@ -13,7 +14,7 @@ entry_result () {
if [ "$ignore_item" = 0 ] && \
[ -n "$kernel" ] && \
[ -e "$mpoint/$kernel" ]; then
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
fi
kernel=""
diff --git a/linux-boot-probes/mounted/x86/50lilo b/linux-boot-probes/mounted/x86/50lilo
index a011b56..d0f3c1d 100755
--- a/linux-boot-probes/mounted/x86/50lilo
+++ b/linux-boot-probes/mounted/x86/50lilo
@@ -6,6 +6,7 @@ partition="$1"
bootpart="$2"
mpoint="$3"
type="$4"
+subvolid="$5"
found_item=0
@@ -48,7 +49,7 @@ recordstanza () {
parameters="root=$rootdev $parameters"
fi
parameters="${parameters% }"
- result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters"
+ result "$rootpart:$bootpart:$title:$kernel:$initrd:$parameters${subvolid:+ rootflags=subvolid=$subvolid}"
found_item=1
else
debug "cannot find $kernel or $initrd, not recording"
--
2.11.0
From ce34b0a3ea289bb712a0841c2ad4bbd67df47754 Mon Sep 17 00:00:00 2001
From: Michael Mestnik <cheako+github_com@mikemestnik.net>
Date: Sun, 4 Jun 2017 20:42:11 -0500
Subject: [PATCH 3/6] Iterate over and insert, subvol, into output
---
common.sh | 8 ++++-
debian/os-prober.prerm | 34 +++++++++++++++++++++
os-prober | 52 +++++++++++++++++++++++++++++++++
os-probes/common/50mounted-tests | 8 ++++-
os-probes/mounted/common/40lsb | 3 +-
os-probes/mounted/common/90linux-distro | 3 +-
6 files changed, 104 insertions(+), 4 deletions(-)
create mode 100644 debian/os-prober.prerm
diff --git a/common.sh b/common.sh
index e1646d4..8942a91 100644
--- a/common.sh
+++ b/common.sh
@@ -151,7 +151,8 @@ 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" "$(
+ echo "$4" | grep -o 'subvolid=[0-9][0-9]*' | cut -d= -f2)"
done
}
@@ -204,6 +205,11 @@ find_uuid () {
fi
}
+get_default_subvolid () {
+ btrfs subvolume get-default "$1" 2>/dev/null |
+ cut -d ' ' -f 2 | head -n1
+}
+
# Sets $mountboot as output variables. This is very messy, but POSIX shell
# isn't really up to the task of doing it more cleanly.
linux_mount_boot () {
diff --git a/debian/os-prober.prerm b/debian/os-prober.prerm
new file mode 100644
index 0000000..957d6ef
--- /dev/null
+++ b/debian/os-prober.prerm
@@ -0,0 +1,34 @@
+#!/bin/sh
+# prerm script for os-prober
+#
+# see: dh_installdeb(1)
+
+set -e
+
+case "$1" in
+ remove)
+ # Cleanup script temp files/folders
+ # in case of crash and user uninstalls.
+ # The last thing we want is for our pkg
+ # to generate even more errors on it's
+ # way out.
+ tmpmnt=/var/lib/os-prober/mnt
+ umount "$tmpmnt" 2>/dev/null || true
+ rmdir "$tmpmnt" 2>/dev/null || true
+ ;;
+
+ upgrade|deconfigure|failed-upgrade)
+ ;;
+
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/os-prober b/os-prober
index a48863e..955020d 100755
--- a/os-prober
+++ b/os-prober
@@ -149,6 +149,58 @@ for partition in $(partitions); do
continue
fi
+ # Scan btrfs subvol(s)
+ type="$(fs_type "$mapped")"
+ if [ "$type" = "btrfs" ] && type btrfs >/dev/null 2>&1; then
+ tmpmnt=/var/lib/os-prober/mnt
+ if [ ! -d "$tmpmnt" ]; then
+ mkdir "$tmpmnt"
+ fi
+ # any fs supporting subvol has no fear of multi-mount
+ mount "$mapped" "$tmpmnt"
+ # 5 is special for btrfs and not listed as a subvol
+ subvols="$(echo 5; btrfs subvolume list "$tmpmnt" | cut -d ' ' -f 2)"
+ rosubvols="$(btrfs subvolume list -r "$tmpmnt" | cut -d ' ' -f 2)"
+ sssubvols="$(btrfs subvolume list -s "$tmpmnt" | cut -d ' ' -f 2)"
+ defaultsv="$(get_default_subvolid "$tmpmnt")"
+ umount "$tmpmnt"
+ for subvol in $subvols; do
+ if echo "$rosubvols" | grep -q -x "$subvol"; then
+ continue
+ fi
+ if echo "$sssubvols" | grep -q -x "$subvol"; then
+ continue
+ fi
+ if [ "$defaultsv" = "$subvol" ]; then
+ mount "$mapped" "$tmpmnt"
+ for test in /usr/lib/os-probes/mounted/*; do
+ if [ -f "$test" ] && [ -x "$test" ]; then
+ debug "running $test on $mapped default subvol "
+ if "$test" "$mapped" "$tmpmnt" "$type"; then
+ debug "os detected by $test"
+ break
+ fi
+ fi
+ done
+ umount "$tmpmnt"
+ continue
+ fi
+ mount -o "subvolid=$subvol" "$mapped" "$tmpmnt"
+ for test in /usr/lib/os-probes/mounted/*; do
+ if [ -f "$test" ] && [ -x "$test" ]; then
+ debug "running $test on $mapped subvolid $subvol"
+ if "$test" "$mapped" "$tmpmnt" "$type" "$subvol"; then
+ debug "os detected by $test"
+ break
+ fi
+ fi
+ done
+ umount "$tmpmnt"
+ done
+ rmdir "$tmpmnt"
+ continue
+ fi
+
if ! grep -q "^$mapped " "$OS_PROBER_TMP/mounted-map" ; then
for test in /usr/lib/os-probes/*; do
if [ -f "$test" ] && [ -x "$test" ]; then
diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests
index fca15cb..389f8d9 100755
--- a/os-probes/common/50mounted-tests
+++ b/os-probes/common/50mounted-tests
@@ -2,6 +2,7 @@
# Sub-tests that require a mounted partition.
set -e
partition="$1"
+subvolid="$2"
. /usr/share/os-prober/common.sh
@@ -58,6 +59,10 @@ if [ ! -d "$tmpmnt" ]; then
fi
mounted=
+if [ "$subvolid" ]; then
+ mount "$partition" "$tmpmnt" -o subvolid="$subvolid" &&
+ mounted=1
+else
if type grub-mount >/dev/null 2>&1 && \
type grub-probe >/dev/null 2>&1 && \
grub-mount "$partition" "$tmpmnt" 2>/dev/null; then
@@ -70,12 +75,13 @@ if type grub-mount >/dev/null 2>&1 && \
type=fuseblk
fi
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
+ if "$test" "$partition" "$tmpmnt" "$type" "$subvolid"; then
debug "os found by subtest $test"
do_unmount
exit 0
diff --git a/os-probes/mounted/common/40lsb b/os-probes/mounted/common/40lsb
index ce8d4e1..da58b8f 100755
--- a/os-probes/mounted/common/40lsb
+++ b/os-probes/mounted/common/40lsb
@@ -7,6 +7,7 @@ set -e
partition="$1"
dir="$2"
type="$3"
+subvolid="$4"
lsb_field () {
file="$1"
@@ -44,5 +45,5 @@ if [ -z "$short" ]; then
fi
label="$(count_next_label "$short")"
-result "$partition:$long:$label:linux"
+result "$partition${subvolid:+@$subvolid}:$long:$label:linux${subvolid:+-subvolid}"
exit 0
diff --git a/os-probes/mounted/common/90linux-distro b/os-probes/mounted/common/90linux-distro
index badfbb1..adba52d 100755
--- a/os-probes/mounted/common/90linux-distro
+++ b/os-probes/mounted/common/90linux-distro
@@ -7,6 +7,7 @@ set -e
partition="$1"
dir="$2"
type="$3"
+subvolid="$4"
# 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 +144,7 @@ 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"
+ result "$partition${subvolid:+@$subvolid}:$long:$label:linux${subvolid:+-subvolid}"
exit 0
else
exit 1
--
2.11.0
Reply to: