My latest confusion with using mount
and its handy --bind
and --rbind
options is with unmounting such mounts. It should have been as simple as:
umount /my/mount/point
But when executing such a command I end up with:
umount: /my/mount/point: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
So the error had me baffled as the mount shouldn't have been in use. I initially thought some process was grabbing a hold of it and causing me some headache. So I used
lsof
and fuser
command to identify who was tying my mount up. It turned out that there were lots of processes tying it up. Here is a more specific example that I was working with:mount --rbind /home /export/home
I used
--rbind
because /home
contains a couple of mount points that I also wanted to export as part of binding /home
to /export/home
. Seemed simple enough. Well, after using the umount
command and getting the aforementioned error I used lsof
and fuser
to see that just about every process from /home
showed up as using both /home
and /export/home
.So, I did a bit more research and found this RFE (although old): https://bugzilla.redhat.com/show_bug.cgi?id=194342
Basically it was talking about recursive binds not being able to be unmounted due to mounts inside the mount having to be unmounted first. So I immediately ran:
umount /export/home/share1
umount /export/home/share2
Yes! No error! So, now:
umount /export/home
No! The error is still there. I couldn't figure this out. I banged my head against the keyboard a few times and then decided to analyse the workaround command provided in the RFE's comments:
mount | awk '{print $3}' | grep ^/dev | sed -e s,/dev,/tmp/dev, | xargs umount
umount /tmp/dev
I plugged
/home
in for /dev
and /export/home
for /tmp/dev
and executed without the xargs
command on the end (I wanted to see what it was going to output):/export/home
/export/home/share1
/export/home/share2
/export/home/user01/.gvfs
Well wouldn't you know it! I forgot about
gvfs
. Anyway, that prompted me to throw a quick script together. It is very raw and might not be 100% correct but it gets the job done for me and makes it so I don't have to go back and figure out where all my child-mounts are.#!/bin/sh
MOUNTS=`mount`
OFS=$IFS
IFS=$'\n'
if [ -d "$1" ]; then
OLDWD="`pwd`"
cd "$1"
rootMount="`pwd`"
cd "$OLDWD"
else
rootMount="${1%/}"
fi
for mount in $MOUNTS; do
umountTgt=`echo $mount | awk '{print $3}'`
if [ "$umountTgt" = "$rootMount" ]; then
mountSrc=`echo $mount | awk '{print $1}'`
umountList=$umountList`mount | awk '{print $3}' | grep ^$mountSrc | sed -e s,$mountSrc,$rootMount, `$'\n'
for umount in $umountList; do
if [ "$umount" != "$rootMount" ]; then
echo "Unmounting $umount..."
/bin/umount "$umount"
fi
done
fi
done
IFS=$OFS
echo "Unmounting $rootMount..."
/bin/umount "$rootMount"