From c3cca9cfc0eec1addfb285efe9bcba084b79cddacd3a1daa2cbc5a58bf7669d3 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 25 Apr 2019 08:49:57 +0000 Subject: [PATCH] Accepting request 697790 from home:michael-chang:branches:Base:System - Fix accidental deletion of btrfs subvolume (boo#1130669) * os-prober-use-tmp-over-var-lib-for-transient-files.patch OBS-URL: https://build.opensuse.org/request/show/697790 OBS-URL: https://build.opensuse.org/package/show/Base:System/os-prober?expand=0&rev=96 --- ...tmp-over-var-lib-for-transient-files.patch | 223 +++++++++++++++--- os-prober.changes | 6 + os-prober.spec | 1 + 3 files changed, 193 insertions(+), 37 deletions(-) diff --git a/os-prober-use-tmp-over-var-lib-for-transient-files.patch b/os-prober-use-tmp-over-var-lib-for-transient-files.patch index 3375d00..7b1ca57 100644 --- a/os-prober-use-tmp-over-var-lib-for-transient-files.patch +++ b/os-prober-use-tmp-over-var-lib-for-transient-files.patch @@ -9,6 +9,12 @@ count_last_label function for not relying on /var/lib/os-prober/labels file for the caculation. https://en.opensuse.org/openSUSE:Packaging_for_transactional-updates + +v2: +- Fix accidental deletion of btrfs subvolume (boo#1130669). +- Fix detection of btrfs boot subvolume if its /etc/fstab entry contains + leading slash for subvol= mount option. + --- common.sh | 37 ++++++++++++++------------------ linux-boot-prober | 2 +- @@ -17,10 +23,10 @@ https://en.opensuse.org/openSUSE:Packaging_for_transactional-updates os-probes/common/50mounted-tests | 2 +- 5 files changed, 19 insertions(+), 27 deletions(-) -diff --git a/common.sh b/common.sh -index 19d2668..d73718c 100644 ---- a/common.sh -+++ b/common.sh +Index: os-prober-1.76/common.sh +=================================================================== +--- os-prober-1.76.orig/common.sh ++++ os-prober-1.76/common.sh @@ -21,31 +21,26 @@ require_tmpdir() { fi } @@ -69,36 +75,125 @@ index 19d2668..d73718c 100644 } progname= -diff --git a/linux-boot-prober b/linux-boot-prober -index 243fd6c..4d0f5e8 100755 ---- a/linux-boot-prober -+++ b/linux-boot-prober -@@ -7,7 +7,7 @@ newns "$@" +Index: os-prober-1.76/linux-boot-prober +=================================================================== +--- os-prober-1.76.orig/linux-boot-prober ++++ os-prober-1.76/linux-boot-prober +@@ -7,11 +7,6 @@ newns "$@" require_tmpdir ERR="n" -tmpmnt=/var/lib/os-prober/mount -+tmpmnt="$OS_PROBER_TMP/mount" - if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" +-if [ ! -d "$tmpmnt" ]; then +- mkdir "$tmpmnt" +-fi +- + mounted= + bootmnt= + bootsv= +@@ -45,23 +40,21 @@ if [ "x$ERR" != xn ]; then fi -diff --git a/linux-boot-probes/common/50mounted-tests b/linux-boot-probes/common/50mounted-tests -index 84c3ced..7c9c717 100755 ---- a/linux-boot-probes/common/50mounted-tests -+++ b/linux-boot-probes/common/50mounted-tests -@@ -42,7 +42,7 @@ elif [ -z "$types" ]; then + + if [ "$type" = btrfs ]; then ++ tmpmnt="$(mktemp -d /tmp/linux-boot-prober.XXXXXX)" + # 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 +@@ -74,8 +67,6 @@ if [ "$type" = btrfs ]; then + + if ! mount $opts -t btrfs -U $UUID "$tmpmnt" 2>/dev/null; then + warn "error mounting btrfs subvol=$subvol UUID=$UUID" +- umount "$tmpmnt/boot" 2>/dev/null +- umount "$tmpmnt" 2>/dev/null + rmdir "$tmpmnt" 2>/dev/null + exit 1 + fi +@@ -83,8 +74,6 @@ if [ "$type" = btrfs ]; then + # 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 +@@ -103,27 +92,34 @@ if [ "$type" = btrfs ]; then + 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=//" ) ++ bootsv=$(echo "$bootmnt" | cut -d ' ' -f 4 | sed -n 's!\(^subvol=\|.*,subvol=\)\([^,]\+\).*!\2!p') ++ if [ -z "$bootsv" ]; then ++ warn "no subvolume in entry: $bootmnt" ++ umount "$tmpmnt" 2>/dev/null ++ rmdir "$tmpmnt" 2>/dev/null ++ exit 1 ++ fi ++ bootuuid=$(echo "$bootmnt" | cut -d ' ' -f 1 | sed -n 's/UUID=\("\(.*\)"\|\(.*\)\)/\2\3/p') + 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) ++ bootpart=$(grep " btrfs " /proc/self/mountinfo | grep " `echo /$bootsv | tr -s /` " | cut -d ' ' -f 10) ++ if [ -z "$bootpart" ]; then ++ warn "no bootpart for $bootsv in /proc/self/mountinfo" ++ fi + else + # non-btrfs partition or logical volume + linux_mount_boot $partition $tmpmnt +Index: os-prober-1.76/linux-boot-probes/common/50mounted-tests +=================================================================== +--- os-prober-1.76.orig/linux-boot-probes/common/50mounted-tests ++++ os-prober-1.76/linux-boot-probes/common/50mounted-tests +@@ -42,10 +42,7 @@ elif [ -z "$types" ]; then types="$(grep -v nodev /proc/filesystems)" fi -tmpmnt=/var/lib/os-prober/mount -+tmpmnt="$OS_PROBER_TMP/mount" - if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" - fi -diff --git a/os-prober b/os-prober -index fb0f93c..903eddb 100755 ---- a/os-prober -+++ b/os-prober +-if [ ! -d "$tmpmnt" ]; then +- mkdir "$tmpmnt" +-fi ++tmpmnt="$(mktemp -d /tmp/linux-boot-probes-50mounted-tests.XXXXXX)" + + mounted= + if type grub2-mount >/dev/null 2>&1 && \ +Index: os-prober-1.76/os-prober +=================================================================== +--- os-prober-1.76.orig/os-prober ++++ os-prober-1.76/os-prober @@ -141,9 +141,6 @@ parse_proc_mdstat () { done } @@ -109,19 +204,73 @@ index fb0f93c..903eddb 100755 for prog in /usr/lib/os-probes/init/*; do if [ -x "$prog" ] && [ -f "$prog" ]; then "$prog" || true -diff --git a/os-probes/common/50mounted-tests b/os-probes/common/50mounted-tests -index a9c20ef..9555c39 100755 ---- a/os-probes/common/50mounted-tests -+++ b/os-probes/common/50mounted-tests -@@ -58,7 +58,7 @@ elif [ -z "$types" ]; then +Index: os-prober-1.76/os-probes/common/50mounted-tests +=================================================================== +--- os-prober-1.76.orig/os-probes/common/50mounted-tests ++++ os-prober-1.76/os-probes/common/50mounted-tests +@@ -58,10 +58,7 @@ elif [ -z "$types" ]; then exit 0 fi -tmpmnt=/var/lib/os-prober/mount -+tmpmnt="$OS_PROBER_TMP/mount" - if [ ! -d "$tmpmnt" ]; then - mkdir "$tmpmnt" - fi --- -2.16.4 - +-if [ ! -d "$tmpmnt" ]; then +- mkdir "$tmpmnt" +-fi ++tmpmnt="$(mktemp -d /tmp/os-probes-50mounted-tests.XXXXXX)" + + mounted= + +@@ -105,7 +102,7 @@ probe_subvol () + local UUID=$3 + local tmpmnt=$4 + +- mounted= ++ local mounted= + mpoint="$(grep btrfs /proc/self/mountinfo | grep "$partition " | grep "/$subvol " | cut -d ' ' -f 5)" + ret=1 + +@@ -115,13 +112,18 @@ probe_subvol () + + if [ -n "$mpoint" ]; then + if [ "x$mpoint" = "x/" ]; then +- continue # this is the root for the running system ++ return 1 + fi +- mounted=1 + else + # again, do not mount btrfs ro +- mount -t btrfs $opts -U "$UUID" "$tmpmnt" +- mpoint="$tmpmnt" ++ if mount -t btrfs $opts -U "$UUID" "$tmpmnt" 2>/dev/null; then ++ debug "btrfs volume $UUID mounted with $opt" ++ mpoint="$tmpmnt" ++ mounted=1 ++ else ++ warn "cannot mount btrfs volume $UUID with $opt" ++ return 1 ++ fi + fi + test="/usr/lib/os-probes/mounted/90linux-distro" + if [ -f "$test" ] && [ -x "$test" ]; then +@@ -131,7 +133,7 @@ probe_subvol () + ret=0 + fi + fi +- if [ -z "$mounted" ]; then ++ if [ "$mounted" ]; then + if ! umount "$tmpmnt"; then + warn "failed to umount $tmpmnt" + fi +Index: os-prober-1.76/linux-boot-probes/mounted/common/40grub2 +=================================================================== +--- os-prober-1.76.orig/linux-boot-probes/mounted/common/40grub2 ++++ os-prober-1.76/linux-boot-probes/mounted/common/40grub2 +@@ -15,7 +15,7 @@ found_item=0 + + entry_result () { + if [ "x$type" = "xbtrfs" ]; then +- bsv=${bootsv:+/}${bootsv} ++ bsv=`echo ${bootsv:+/}${bootsv} | tr -s /` + # if path is not relative to subvolume make it relative + kernel=${kernel#${bsv}} + kernelfile=$kernel diff --git a/os-prober.changes b/os-prober.changes index 42601bd..2f7e9e8 100644 --- a/os-prober.changes +++ b/os-prober.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Apr 23 07:42:32 UTC 2019 - mchang + +- Fix accidental deletion of btrfs subvolume (boo#1130669) + * os-prober-use-tmp-over-var-lib-for-transient-files.patch + ------------------------------------------------------------------- Tue Mar 12 06:47:59 UTC 2019 - mchang diff --git a/os-prober.spec b/os-prober.spec index 9075c4f..f88c460 100644 --- a/os-prober.spec +++ b/os-prober.spec @@ -71,6 +71,7 @@ Patch26: os-prober-multiple-initrd.patch # PATCH-FIX-OPENSUSE: os-prober unconditionally pulls btrfsprogs (boo#1118279) Patch27: os-prober-make-btrfsprogs-optional.patch # PATCH-FIX-OPENSUSE: os-prober isn't compatible with transactional update (boo#1125729) +# PATCH-FIX-OPENSUSE: os-prober deletes subvolume on btrfs disk (boo#1130669) Patch28: os-prober-use-tmp-over-var-lib-for-transient-files.patch Requires: /bin/grep Requires: /bin/sed