我有一些代码可以在设备上安装文件系统,然后使用DM_DEV_REMOVE
ioctl命令立即从设备映射器中删除设备。
有时,作为压力测试的一部分,我在紧密循环中运行此代码:
通常,在数千次迭代中运行此测试时,我最终会在尝试删除设备时获得错误EBUSY
。 umount总是成功的。
我尝试过搜索这个问题,但我发现大多数情况下人们在卸载时遇到问题EBUSY
,这不是我遇到的问题。
我能找到的最接近帮助的是,在man page for dmsetup
中它讨论了使用--retry
选项作为udev规则在您尝试删除设备时打开设备的解决方法。不幸的是,我可以确认udev在我试图删除它时没有打开我的设备。
我已使用DM_DEV_STATUS
命令检查设备的open_count
,我看到open_count
在umount
之前始终为1 {测试成功在umount
之后它为0,当它失败时它在umount
之后为1。
现在,我试图找到根本原因 - 我的问题是,"我的资源忙碌失败是由umount
异步释放我的设备引起的,从而造成竞争条件?&# 34 ;.我知道umount
在实际卸载时应该是同步的,但我找不到任何关于是否可以异步发布/关闭底层设备的文档。
而且,如果它不是umount
对我的设备持开放式句柄,是否有其他可能的候选人?
我的测试是在3.10内核上运行的。
答案 0 :(得分:0)
从历史上看,系统调用阻止了所涉及的进程,直到完成所有任务(由于显而易见的原因,write(2)
对块设备是第一个主要异常)原因是您需要一个进程来完成工作并且由于这个原因,系统调用涉及进程(并且您可以对该用户的帐户收取cpu处理)
如今,解决与非流程相关的问题涉及大量内核线程,而umount(2)
系统调用可能是需要一些背景的系统调用之一(我认为它不是{{1}不经常发布以证明代码更改的合理性)
但是linux不是unix后代,所以umount(2)
可以通过这种方式实现。无论如何,我不相信。
umount(2)
syscall通常会成功,除非文件系统上的inode正在使用中。事实并非如此。但内核可能涉及一些重负载进程,这使得它在请求中分配一些内核内存(不可交换)并失败。这可能会导致错误(请注意,这只是一个猜测,我还没有在代码中检查过这个,你最好还是看看你得到的umount(2)
系统调用实现)。
还有另一个问题,如果你碰到了某些文件系统,可能会阻止你的umount进程(或失败)。有一些参考依赖代码使得文件系统能够在一致状态下抵御电源故障(在linux中,这是calles 有序数据,在BSD系统中它被称为软件更新< / em>,这使得在umount(2)
之后不会立即释放已删除的文件。如果必须在文件系统上更新某些数据,可能会阻止unlink(2)
(或使其失败) umount(2)
致电。但是,再次,这不应该是您的情况,正如您所说,您不会修改已挂载的文件系统。