umount saying that a mounted directory is not mounted

From: Nikolay Borisov
Date: Mon Dec 14 2015 - 09:59:27 EST


Hello,

I'm using the attached script to perform some tests. However from time
to time I get the following results:

[root@kernighan lvm-race]# bash -x ./init_vg.sh
+ set -e
++ mktemp -u --tmpdir=. vgfile.XXXX
+ file=./vgfile.lCdz
++ mktemp -u testgrp-XXXX
+ group=testgrp-OgAz
++ mktemp -u thingrp-XXXX
+ thingroup=thingrp-h8mw
++ mktemp -d --tmpdir=. mntdir-XXXX
+ mntpath=./mntdir-KpMO
++ mktemp -u testvol-XXXX
+ volume_name=testvol-JvsQ
+ volume_size=200M
+ truncate ./vgfile.lCdz --size 10G
++ losetup -f --show ./vgfile.lCdz
+ loopdev=/dev/loop2
+ pvcreate --metadatasize 1M /dev/loop2
allocation/use_blkid_wiping=1 configuration setting is set while LVM
is not compiled with blkid wiping support.
Falling back to native LVM signature detection.
Physical volume "/dev/loop2" successfully created
+ vgcreate testgrp-OgAz -s 1MiB /dev/loop2
Volume group "testgrp-OgAz" successfully created
++ vgdisplay /dev/testgrp-OgAz
++ grep 'PE Size'
++ awk '{print $3}'
+ pe_size=1.00
++ bc -l
+++ vgdisplay /dev/testgrp-OgAz
+++ grep 'Free PE'
+++ awk '{print $5}'
++ echo '10238*1.00-180'
+ thin_size=10058.00
+ lvcreate --ignoreactivationskip -Z n -L 10058.00M -T
/dev/testgrp-OgAz/thingrp-h8mw
Logical volume "thingrp-h8mw" created.
+ lvcreate --ignoreactivationskip -V200M -T testgrp-OgAz/thingrp-h8mw -n
testvol-JvsQ
allocation/use_blkid_wiping=1 configuration setting is set while LVM
is not compiled with blkid wiping support.
Falling back to native LVM signature detection.
Logical volume "testvol-JvsQ" created.
+ mkfs.ext4 /dev/testgrp-OgAz/testvol-JvsQ
mke2fs 1.42.12 (29-Aug-2014)
Discarding device blocks: done
Creating filesystem with 51200 4k blocks and 12800 inodes
Filesystem UUID: 303208ff-3c52-451e-8cf3-5c5bf2212902
Superblock backups stored on blocks:
32768

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done

+ sync
+ vgchange -Kan testgrp-OgAz
0 logical volume(s) in volume group "testgrp-OgAz" now active
+ losetup -d /dev/loop2
+ echo 'Volume created, doing work'
Volume created, doing work
+ for i in '{1..10}'
+ echo 'Doing iteration 1'
Doing iteration 1
++ losetup -f --show ./vgfile.lCdz
+ loopdev=/dev/loop2
+ vgchange -Kay testgrp-OgAz
2 logical volume(s) in volume group "testgrp-OgAz" now active
+ mount /dev/testgrp-OgAz/testvol-JvsQ ./mntdir-KpMO
+ rm -rf ./mntdir-KpMO/lost+found
++ mktemp -u tmpfile.XXXX
++ get_random
++ local number=0
++ '[' 0 -le 20 ']'
++ number=244
++ let 'number %= 50'
++ '[' 44 -le 20 ']'
++ echo 44
+ dd if=/dev/urandom of=./mntdir-KpMO/tmpfile.eSJR bs=44M count=1
0+1 records in
0+1 records out
33554431 bytes (34 MB) copied, 2.36667 s, 14.2 MB/s
+ umount ./mntdir-KpMO
umount: ./mntdir-KpMO: not mounted


This shows that (based on the way the script works) that a mount call
succeeds, then a subsequent write succeeds as well and when umount is
invoked it says that the location is not mounted, eventhough it is
indeed mounted? What;s more is the fact that if I rerun the script
umount works as expected? Is this some kind of racy behavior? Am I
missing something? This is on kernel 4.2.6

Regards,
Nikolay
#!/bin/bash
set -e

function get_random() {
local number=0
while [ "$number" -le 20 ]
do
number=$RANDOM
let "number %= 50"
done

echo $number
}

file=$(mktemp -u --tmpdir=. vgfile.XXXX)
group=$(mktemp -u testgrp-XXXX)
thingroup=$(mktemp -u thingrp-XXXX)
mntpath=$(mktemp -d --tmpdir=. mntdir-XXXX)
volume_name=$(mktemp -u testvol-XXXX)
volume_size=200M
truncate ${file} --size 10G
loopdev=$(losetup -f --show ${file})
pvcreate --metadatasize 1M ${loopdev}
vgcreate ${group} -s 1MiB ${loopdev}
pe_size=$(vgdisplay "/dev/${group}" | grep 'PE Size' | awk '{print $3}')
thin_size=$(echo "$(vgdisplay "/dev/${group}" | grep 'Free PE' | awk '{print $5}')*${pe_size}-180" | bc -l)
lvcreate --ignoreactivationskip -Z n -L ${thin_size}M -T "/dev/${group}/${thingroup}"
lvcreate --ignoreactivationskip -V${volume_size} -T "${group}/${thingroup}" -n "${volume_name}"
mkfs.ext4 /dev/$group/$volume_name
sync
vgchange -Kan $group
losetup -d $loopdev

echo "Volume created, doing work"
for i in {1..10}; do
echo "Doing iteration $i"
loopdev=$(losetup -f --show ${file})
vgchange -Kay $group
if ! mount /dev/$group/$volume_name $mntpath; then
echo "kor"
exit 1
fi
rm -rf $mntpath/*
dd if=/dev/urandom of=$mntpath/$(mktemp -u tmpfile.XXXX) bs=$(get_random)M count=1
umount $mntpath
vgchange -Kan $group
losetup -d $loopdev

done