4

I have a folder in /tmp that is mounted as ramfs. After some action that my script does, I delete everything inside said folder with the command:

rm -R -f "$tmp_dir"/{*,.*}

Then, I try to unmount the directory, but on the first try it doesn't work because the device is busy. After sleeping for a 0.5sec, the unmount succeeds.

I've verified that no process is using the folder or anything inside that folder with any of the following commands:

fuser -m "$tmp_dir"
fuser "$tmp_dir"
lsof +d "$tmp_dir"
lsof "$tmp_dir"

Why would the device be busy in the 1st try?


Edit #1 (30 Sep, 18:32 UTC):
When I execute find "$tmp_dir" -delete, the unmount succeeds on the 1st time!
But then the find command complains about $tmp_dir being busy.


Edit #2 (30 Sep, 18:45 UTC):
With stat I noticed a change in the size of the folder, before an after the success in the unmount:

$ stat '/tmp/tmp.nbljlVcmix'
  File: `/tmp/tmp.nbljlVcmix'
  Size: 0           Blocks: 0          IO Block: 4096   directory
Device: 17h/23d Inode: 121188      Links: 2
Access: (0700/drwx------)  Uid: ( 1000/     dor)   Gid: (    0/    root)
Access: 2013-09-30 20:37:51.430769893 +0300
Modify: 2013-09-30 20:37:51.430769893 +0300
Change: 2013-09-30 20:37:51.430769893 +0300
$ umount '/tmp/tmp.nbljlVcmix'
umount: /tmp/tmp.nbljlVcmix: device is busy.
        (In some cases useful info about processes that use
         the device is found by lsof(8) or fuser(1))
$ sleep 0.5
$ umount '/tmp/tmp.nbljlVcmix'
$ stat '/tmp/tmp.nbljlVcmix'
  File: `/tmp/tmp.nbljlVcmix'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: 806h/2054d  Inode: 2401825     Links: 2
Access: (0700/drwx------)  Uid: ( 1000/     dor)   Gid: (    0/    root)
Access: 2013-09-30 20:37:47.600513531 +0300
Modify: 2013-09-30 20:37:47.600513531 +0300
Change: 2013-09-30 20:37:47.610513892 +0300

Edit #3 (1 Oct, 11:04 UTC):
I've copied all the code (single file) to: http://pastebin.com/RJP6eQiy (Valid for 1 Month)

The relevant umount is in the cleanup procedure, line #346, that is umount "$DEST_DIR".

Dor
  • 2,535
  • 1
    Does your script close any filehandles it opens in tmp? I am not sure but I think this might happen if your script leaves the fh open. – terdon Sep 30 '13 at 18:06
  • "With stat I noticed a change in the size of the folder, before an after the success in the unmount" Mount points are normal directories. If you mount something on a directory that has contents, the contents are inaccessible until you unmount whatever. Then they'll still be there, untouched. – goldilocks Sep 30 '13 at 18:11
  • 2
    @terdon Open files in the toplevel should show up with lsof +d, but the man page notes: "+d does NOT descend the directory tree, rooted at s. The +D D option may be used to request a full-descent directory tree search, rooted at directory D." – goldilocks Sep 30 '13 at 18:17
  • Can you run the lsof via sudo? This will show us for sure if something is using tmp that you're username isn't privy to. – slm Sep 30 '13 at 18:24
  • @sim: I forgot to mention that all of the commands were run by root (including fuser and lsof) – Dor Sep 30 '13 at 20:52
  • @terdon: I've added the code, see my edit. My script doesn't leave any opened file handle as far as I understand. Perhaps Open Office leaves them? It's not possible because that I delete the folder's content before trying to unmount. – Dor Oct 01 '13 at 10:08
  • My guess would be that some process has a file open and reacts to the removal of that file by closing it. An audit rule (see http://security.blogoverflow.com/2013/09/stump-the-chump-with-auditd-01/ for an example) might let you track it down. – Gilles 'SO- stop being evil' Oct 01 '13 at 15:16

1 Answers1

2

I believe the disk needs a 'sync' first (to flush/write disk cache) before the umount. Add sync after your 'rm' command (some OS require two sync commands) and then umount. Your 'busy' message should go away.

Andrew
  • 1,205
  • You were right, I used sync before the umount and it works properly! Thank you! – Dor Sep 30 '13 at 20:39
  • No, you never need to call sync before umount. Calling sync just happens to delay the unmounting enough; calling sleep would do the same. – Gilles 'SO- stop being evil' Sep 30 '13 at 21:46
  • @Gilles: How can I test this..? I executed time on the sync and got the output: real 0m0.261s user 0m0.000s sys 0m0.020s – Dor Oct 01 '13 at 10:01
  • 1
    @Dor You could test it by suspending all writes (noflushd does that, but I'm not sure if it would be suitable here, as it's fairly tied to the disk layer and to the way certain filesystems operate). If sleep works as a delay even when no syncing happens, this would demonstrate that sync is not needed. Alternatively, you can use logic: syncing is one of the first things that happens during the unmounting process. – Gilles 'SO- stop being evil' Oct 01 '13 at 10:08
  • @Gilles: Please see the answer of the user 'jeberle' here. What is your opinion? – Dor Oct 01 '13 at 13:12
  • @Dor - sync command runs as quickly as the disk can write, usually a few milliseconds or less. It has nothing to do with 'creating a delay'. Since it kills Gilles (rhyming intended) to manually invoke sync, use "umount -l" which is a lazy umount and you can probably skip the sync command. From the man page "Lazy unmount. Detach the filesystem from the filesystem hierarchy now, and cleanup all references to the filesystem as soon as it is not busy anymore". No guarantee a lazy umount will work as well as sync, and/or not corrupt your /tmp filesystem, but you can try it. – Andrew Oct 01 '13 at 14:56
  • @Andrew Running sync to make umount work is as efficient as waving a dead chicken to prevent rain: it doesn't, but it might prevent your head from getting wet. A lazy unmount does something different: it leaves the filesystem mounted, but at a different, unreachable location. So files can no longer be opened, but processes with open files are not affected. The filesystem is later unmounted when the last open descriptor is closed. For a ramfs, it frees the mount point, but does not free the memory until later. This is probably good enough. P.S. It doesn't rhyme, Gilles is pronounced like Gil. – Gilles 'SO- stop being evil' Oct 01 '13 at 15:12
  • @Dor That answer is wrong, mpez0 has it right. See our question on the topic. – Gilles 'SO- stop being evil' Oct 01 '13 at 15:14
  • So, I would only have suggested on waving the dead chicken to keep my head dry, not to stop the rain. Don't put words in my mouth, lol. Similarly, I said sync will get the filesystem unmount faster because that is what the 'busy' is awaiting. I got the filesystem unmounted, and my head remained dry. Both worked, as advertised. – Andrew Oct 01 '13 at 15:30