commit 5025178f95b122c6862dc7d925a7c089f5fb61a8 Author: Peter Rajnoha Date: Tue May 14 11:05:50 2013 +0200 lvm2-2_02_99-fix-blkdeactivate-handling-of-nested-mountpoints-and-mangled-mount-paths.patch --- WHATS_NEW | 1 + scripts/blkdeactivate.sh.in | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 35c5e43..1bdfeb0 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.99 - =================================== + Fix blkdeactivate to handle nested mountpoints and mangled mount paths. Fix a crash-inducing race condition in lvmetad while updating metadata. Fix possible race while removing metadata from lvmetad. Fix possible deadlock when querying and updating lvmetad at the same time. diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in index 740bac5..be00c24 100644 --- a/scripts/blkdeactivate.sh.in +++ b/scripts/blkdeactivate.sh.in @@ -39,6 +39,7 @@ LVM="@sbindir@/lvm" LSBLK="/bin/lsblk -r --noheadings -o TYPE,KNAME,NAME,MOUNTPOINT" LSBLK_VARS="local devtype local kname local name local mnt" LSBLK_READ="read -r devtype kname name mnt" +SORT_MNT="/bin/sort -r -u -k 4" # Do not unmount mounted devices by default. DO_UMOUNT=0 @@ -122,9 +123,11 @@ is_top_level_device() { device_umount () { test -z "$mnt" && return 0; + test "$devtype" != "lvm" && test "${kname:0:3}" != "dm-" && return 0 + if test -z "${SKIP_UMOUNT_LIST["$mnt"]}" -a "$DO_UMOUNT" -eq "1"; then echo " UMOUNT: unmounting $name ($kname) mounted on $mnt" - $UMOUNT "$mnt" || add_device_to_skip_list + $UMOUNT "$(printf $mnt)" || add_device_to_skip_list else echo " [SKIP]: unmount of $name ($kname) mounted on $mnt" add_device_to_skip_list @@ -142,9 +145,6 @@ deactivate_holders () { # check if the device not on the skip list already test -z ${SKIP_DEVICE_LIST["$kname"]} || return 1 - # try to unmount it if mounted - device_umount || return 1 - # try to deactivate the holder test $skip -eq 1 && skip=0 && continue deactivate || return 1 @@ -226,7 +226,16 @@ deactivate_all() { echo "Deactivating block devices:" if test $# -eq 0; then - # Deactivate all devices + ####################### + # Process all devices # + ####################### + + # Unmount all relevant mountpoints first + while $LSBLK_READ; do + device_umount + done <<< "`$LSBLK | $SORT_MNT`" + + # Do deactivate while $LSBLK_READ; do # 'disk' is at the bottom already and it's a real device test "$devtype" = "disk" && continue @@ -249,8 +258,17 @@ deactivate_all() { deactivate || skip=1 done <<< "`$LSBLK -s`" else - # Deactivate only specified devices + ################################## + # Process only specified devices # + ################################## + while test $# -ne 0; do + # Unmount all relevant mountpoints first + while $LSBLK_READ; do + device_umount + done <<< "`$LSBLK $1 | $SORT_MNT`" + + # Do deactivate # Single dm device tree deactivation. if test -b "$1"; then $LSBLK_READ <<< "`$LSBLK --nodeps $1`"