由于 "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 中挂载了共享文件夹,我想在卸载后删除目录,我只想分享我的解决方案。
卸载路径
sudo umount /your_path
删除 /etc/fstab
中的 mout 路径
sudo nano /etc/fstab
重启
sudo reboot
删除目录
sudo rm -rf /your_path
检查
df -h
然后
sudo umount /path
按照以下步骤操作:
打开资源监视器
单击 "associated handles" 下拉框
搜索创建问题的文件夹
右键单击每个进程并"End process"。
现在您可以删除文件夹
类似的问题还有很多"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()
可能 returnEBUSY
执行异步释放。请参阅此处的讨论: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. Thereboot(8)
andhalt(8)
commands take this into account by sleeping for a few seconds after callingsync(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 中挂载了共享文件夹,我想在卸载后删除目录,我只想分享我的解决方案。
卸载路径
sudo umount /your_path
删除 /etc/fstab
中的 mout 路径sudo nano /etc/fstab
重启
sudo reboot
删除目录
sudo rm -rf /your_path
检查
df -h
然后
sudo umount /path
按照以下步骤操作:
打开资源监视器
单击 "associated handles" 下拉框
搜索创建问题的文件夹
右键单击每个进程并"End process"。
现在您可以删除文件夹