rmdir因"设备或资源忙"而失败

hao*_*ent 5 linux filesystems

有很多类似的问题,如"设备或资源忙".但我认为我的问题与他们不同.

我使用mount --bind来绑定目录

mount --bind /tmp/origin /tmp/mount
Run Code Online (Sandbox Code Playgroud)

然后可以成功卸载

umount /tmp/mount
Run Code Online (Sandbox Code Playgroud)

然后,如果我立刻打电话给rm

rm -rf /tmp/mount
Run Code Online (Sandbox Code Playgroud)

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

所以这种行为在这里很奇怪.我试着用

lsof +D /tmp/mount
Run Code Online (Sandbox Code Playgroud)

看不到任何东西.

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

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

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

即使我打电话sync && echo 2 > /proc/sys/vm/drop_caches并尝试删除文件缓存,它仍然无法正常工作.

我在Ubuntu 14.04和CentOS 6.6中尝试了这个.他们有相同的结果.

小智 8

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

  1. 卸载路径

    sudo umount /your_path
    
    Run Code Online (Sandbox Code Playgroud)
  2. 删除/ etc/fstab中的mout路径

    sudo nano /etc/fstab
    
    Run Code Online (Sandbox Code Playgroud)
  3. 重启

    sudo reboot
    
    Run Code Online (Sandbox Code Playgroud)
  4. 删除目录

    sudo rm -rf /your_path
    
    Run Code Online (Sandbox Code Playgroud)

  • `umount /path -l` 强制卸载 (2认同)

gav*_*avv 5

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

  • 关闭文件。close()返回后立即umount()返回,EBUSY同时执行异步释放。请参阅此处的讨论:第 1 页第 2 页
  • 正在卸载文件系统。在所有数据写入磁盘之前,安装的设备可能会很忙。

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

sync(8)

在Linux上,sync仅保证调度脏块进行写入;实际上可能需要很短的时间才能最终写入所有块。和命令考虑到了这一点reboot(8)halt(8)在调用 后休眠几秒钟sync(2)

至于/proc/sys/vm/drop_caches,看这里

这是一个非破坏性操作,不会释放任何脏对象。

因此,在您执行命令之后,数据可能仍在排队等待写入,并且卸载尚未完成。


更新

但是,当异步卸载正在进行时,内核将返回已安装设备EBUSY上的操作,但不会返回安装点

所以上述情况不可能是您问题的原因:P


附言。

实际上我不明白为什么手册页指出sync(8)Linux 中不同步。它调用sync(2)其中声明:

根据标准规范(例如,POSIX.1-2001),sync()安排写入,但可能在实际写入完成之前返回。然而,从 1.3.20 版本开始,Linux 实际上会等待。(这仍然不能保证数据完整性:现代磁盘具有大量缓存。)


hao*_*ent 2

谢谢@gv 的回答。但我发现结果又是一个问题。当 fork 一个进程时,我们使用 CLONE_NEWNS 标志。更多详细信息可以在CLONE_NEWNS 标志MESOS-3349 设备繁忙错误中找到

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

为了避免上述问题,我们可以使用共享挂载或从属挂载。更多详情请参阅LWN 159092