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_...@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_...@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_...@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_...@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