我有一些代码,可以在设备上汇总文件系统,然后使用DM_DEV_REMOVE ioctl命令从设备映射程序中立即删除该设备。
有时,作为压力测试的一部分,我在以下代码的紧密循环中运行这段代码:
通常,当我在数千次迭代中运行这个测试时,当我试图删除设备的EBUSY时,最终会得到errno 。这个国家总是成功的。
我已经尝试过搜索这个问题,但我发现大多数人在获取EBUSY时遇到了问题,这不是我遇到的问题。
我能找到的最有帮助的地方是,在dmsetup中,它谈到了在尝试删除设备时使用--retry选项作为udev规则的解决方法。不幸的是,对我来说,我已经能够确认,udev没有打开我的设备时,我试图删除它。
我使用DM_DEV_STATUS命令检查我的设备的open_count,我看到的是,open_count总是在umount之前,当测试成功时,umount之后是0,失败时是umount之后的1。
现在,我试图找出根本原因,因为我的问题是,“我的资源繁忙的失败是否是由umount异步释放我的设备而导致的,从而创建了一个竞争条件?”我知道,在实际卸载时,umount应该是同步的,但是我找不到任何文档来说明是否可以异步释放/关闭底层设备。
而且,如果不是umount持有我的设备的打开句柄,还有其他可能的人选吗?
我的测试正在3.10内核上运行。
发布于 2017-05-03 06:20:45
从历史上看,系统调用会阻塞所涉及的进程,直到所有任务都完成为止(由于明显的原因,write(2)是块设备的第一个主要例外),原因是您需要一个进程来完成工作,而syscall所涉及的进程就是因为这个原因(您可以将cpu处理收费到该用户的帐户)。
现在,解决与进程无关的问题涉及到大量的内核线程,而umount(2) syscall可能是需要一些背景的系统之一(我认为并不是因为不经常发布umount(2)来证明代码的更改是合理的)。
但是linux不是unix的后代,所以umount(2)可以用这种方式实现。反正我也不相信。
umount(2)系统通常会成功,除非文件系统上的inode正在使用。事实并非如此。但是内核可能涉及到一些繁重的进程,这使得内核分配了一些内核内存(不可交换),并在请求中失败。这可能导致错误(请注意,这只是猜测,我还没有在代码中检查过,最好还是看看umount(2) syscall实现)。
还有另一个问题,可能会阻止您的umount进程(或失败),以防您以某种方式接触到文件系统。有些引用依赖代码使文件系统能够在一致状态下抵抗电源故障(在linux中,这是按调用顺序的数据,在BSD系统中称为软件更新,这使得擦除的文件不能在unlink(2)之后立即释放。如果在进行实际的umount(2)调用之前,必须在文件系统上更新某些数据,这可能会阻止umount(2) (或使其失败)。但是,这不应该是您的情况,正如您所说的,您不修改已安装的文件系统。
https://stackoverflow.com/questions/43742559
复制相似问题