mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
blkdeactivate: fix handling of nested mountpoints and mangled mount paths.
If there was a nested mountpoint inside an existing mount path, blkdeactivate could fail to unmount such a mountpoint as it needs to deactivate the deepest path first and continue upwards. For example the simplest reproducer: [root@rhel6-a ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 4G 0 disk |-vg-lvol0 (dm-2) 253:2 0 32M 0 lvm /mnt/a `-vg-lvol1 (dm-3) 253:3 0 32M 0 lvm /mnt/a/b Before this patch: [root@rhel6-a ~]# blkdeactivate -u Deactivating block devices: UMOUNT: unmounting vg-lvol0 (dm-2) mounted on /mnt/a umount: /mnt/a: device is busy. (In some cases useful info about processes that use the device is found by lsof(8) or fuser(1)) UMOUNT: unmounting vg-lvol1 (dm-3) mounted on /mnt/a/b LVM: deactivating Logical Volume vg/lvol1 (deactivation of vg/lvol0 is skipped as /mnt/a that is on lvol0 can't be unmounted - it still has /mnt/a/b as nested mountpoint!) With this patch applied: [root@rhel6-a ~]# blkdeactivate -u Deactivating block devices: UMOUNT: unmounting vg-lvol1 (dm-3) mounted on /mnt/a/b UMOUNT: unmounting vg-lvol0 (dm-2) mounted on /mnt/a LVM: deactivating Logical Volume vg/lvol0 LVM: deactivating Logical Volume vg/lvol1 === Also, this patch contains a fix for processing mangled mount paths: [root@rhel6-a ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 4G 0 disk `-vg-lvol0 (dm-2) 253:2 0 32M 0 lvm /mnt/x y z [root@rhel6-a ~]# lsblk -r vg-lvol0 253:2 0 32M 0 lvm /mnt/x\x20y\x20z (the mount path is mangled with \xNN that is visible in raw lsblk output only and which is used in blkdeactive as well) Before this patch: [root@rhel6-a ~]# blkdeactivate -u Deactivating block devices: umount: /mnt/x\x20y\x20z: not found After this patch applied: [root@rhel6-a ~]# blkdeactivate -u Deactivating block devices: UMOUNT: unmounting vg-lvol0 (dm-2) mounted on /mnt/x\x20y\x20z LVM: deactivating Logical Volume vg/lvol0
This commit is contained in:
parent
8bcc1da2f3
commit
f7da1caf8d
@ -1,5 +1,6 @@
|
||||
Version 2.02.99 -
|
||||
===================================
|
||||
Fix blkdeactivate to handle nested mountpoints and mangled mount paths.
|
||||
Set locales with LC_ALL instead of lower priority LANG variable.
|
||||
Fix a crash-inducing race condition in lvmetad.
|
||||
Add log/debug_classes to lvm.conf to control debug log messages.
|
||||
|
@ -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 -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`"
|
||||
|
Loading…
Reference in New Issue
Block a user