由于 "Device or resource busy",rmdir 失败

rmdir failed because of "Device or resource busy"

类似的问题还有很多"Device or resource busy"。但是我觉得我的问题和他们不一样。

我使用 mount --bind 绑定一个目录

mount --bind /tmp/origin /tmp/mount

然后就可以卸载成功了

umount /tmp/mount

然后如果我立即调用 rm

rm -rf /tmp/mount

我可能会遇到错误 Device or resource busy。如果我等待2~3秒,然后调用rm,它可能会成功。

所以这里的行为很奇怪。我尝试使用

lsof +D /tmp/mount

什么都看不到。

我也用fuser -vm /tmp/mount,看不到任何进程持有这个文件夹。

我比较了umount /tmp/mount之前和umount /tmp/mount之后的/proc/mounts/tmp/mount 已经删除。

我比较了umount /tmp/mount之前和umount /tmp/mount之后的stat /proc/mounts。 inode 也不同,这意味着 /tmp/mount 已经删除完成。

即使我调用 sync && echo 2 > /proc/sys/vm/drop_caches 并尝试删除文件缓存,它仍然不起作用。

我在 Ubuntu 14.04 和 CentOS 6.6 中都试过了。他们有相同的结果。

根据我的经验,以下操作在 Linux 上是异步的:

  • 正在关闭文件。在 close() returns 之后,umount() 可能 return EBUSY 执行异步释放。请参阅此处的讨论:page 1, page 2.
  • 正在卸载文件系统。在所有数据写入磁盘之前,挂载的设备可能很忙。

Even I call sync && echo 2 > /proc/sys/vm/drop_caches and try to drop file caches, it still not work.

参见sync(8)

On Linux, sync is only guaranteed to schedule the dirty blocks for writing; it can actually take a short time before all the blocks are finally written. The reboot(8) and halt(8) commands take this into account by sleeping for a few seconds after calling sync(2).

至于/proc/sys/vm/drop_caches,见here:

This is a non-destructive operation and will not free any dirty objects.

因此,在您发出命令后,数据可能仍在排队等待写入,卸载尚未完成。


更新

然而,当异步卸载正在运行时,内核将 return EBUSY 用于 挂载设备 上的操作,但不会用于 挂载点.

所以上面的案例不可能是你的问题的原因:P


PS.

其实我不明白为什么手册页说 sync(8) 在 Linux 中不是同步的。它调用 sync(2) 表示:

According to the standard specification (e.g., POSIX.1-2001), sync() schedules the writes, but may return before the actual writing is done. However, since version 1.3.20 Linux does actually wait. (This still does not guarantee data integrity: modern disks have large caches.)

感谢@g-v 的回答。但是我发现结果是另一个问题。我们在 fork 进程时使用 CLONE_NEWNS 标志。可以在 CLONE_NEWNS flag and MESOS-3349 Device busy bug

中找到更多详细信息

简而言之,我们在父进程中挂载。然后在子进程中umount,因为CLONE_NEWNS,父进程处理的挂载点仍然存在。所以当调用 rmdir 时会得到 EBUSY 错误代码。

为了避免上述问题,我们可以使用共享挂载或从属挂载。可以在 LWN 159092

中找到更多详细信息

我遇到这样的问题是因为我在 VM 中挂载了共享文件夹,我想在卸载后删除目录,我只想分享我的解决方案。

  1. 卸载路径

    sudo umount /your_path
    
  2. 删除 /etc/fstab

    中的 mout 路径
    sudo nano /etc/fstab
    
  3. 重启

    sudo reboot
    
  4. 删除目录

    sudo rm -rf /your_path
    
  • 检查

    df -h
    
  • 然后

    sudo umount /path
    

按照以下步骤操作:

  1. 打开资源监视器

  2. 单击 "associated handles" 下拉框

  3. 搜索创建问题的文件夹

  4. 右键单击每个进程并"End process"。

现在您可以删除文件夹