generic/081: fix lvm config not being cleaned up properly
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 15 Aug 2019 15:18:59 +0000 (08:18 -0700)
committerEryu Guan <guaneryu@gmail.com>
Sun, 18 Aug 2019 15:13:16 +0000 (23:13 +0800)
Fix a race between _cleanup and dmeventd that causes the lvm
configuration not to be cleaned up and subsequent tests to fail.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Eryu Guan <guaneryu@gmail.com>
Signed-off-by: Eryu Guan <guaneryu@gmail.com>
tests/generic/081

index 10f4a1861b510e5c70075a50f20dcb6684740751..e8f4f5b5ce70d5693e48163292e6d7de66146ab0 100755 (executable)
@@ -19,12 +19,29 @@ _cleanup()
 {
        cd /
        rm -f $tmp.*
 {
        cd /
        rm -f $tmp.*
-       # lvm may have umounted it on I/O error, but in case it does not
-       # wait a bit for lvm to settle, sigh..
-       sleep 2
-       $UMOUNT_PROG $mnt >/dev/null 2>&1
-       $LVM_PROG vgremove -f $vgname >>$seqres.full 2>&1
-       $LVM_PROG pvremove -f $SCRATCH_DEV >>$seqres.full 2>&1
+
+       # Tear down the lvm vg and snapshot.
+       #
+       # NOTE: We do the unmount and {vg,pv}remove in a loop here because
+       # dmeventd could be configured to unmount the filesystem automatically
+       # after the IO errors.  That is racy with the umount we're trying to do
+       # here because there's a window in which the directory tree has been
+       # removed from the mount namespaces (so the umount call here sees no
+       # mount and exits) but the filesystem hasn't yet released the block
+       # device, which causes the vgremove here to fail.
+       #
+       # We "solve" the race by repeating the umount/lvm teardown until the
+       # block device goes away, because we cannot exit this test without
+       # removing the lvm devices from the scratch device -- this will cause
+       # other tests to fail.
+       while test -e /dev/mapper/$vgname-$snapname || \
+             test -e /dev/mapper/$vgname-$lvname; do
+               $UMOUNT_PROG $mnt >> $seqres.full 2>&1
+               $LVM_PROG vgremove -f $vgname >>$seqres.full 2>&1
+               $LVM_PROG pvremove -f $SCRATCH_DEV >>$seqres.full 2>&1
+               test $? -eq 0 && break
+               sleep 2
+       done
 }
 
 # get standard environment, filters and checks
 }
 
 # get standard environment, filters and checks