检测打开的文件/设备是不是已被替换/删除
Posted
技术标签:
【中文标题】检测打开的文件/设备是不是已被替换/删除【英文标题】:Detect if an open file/device has been replaced/deleted检测打开的文件/设备是否已被替换/删除 【发布时间】:2011-09-26 05:18:17 【问题描述】:假设Linux下的情况如下:
一个进程不断地从 USB 串行转换器设备 (/dev/ttyUSB0
) 中读取数据。该设备突然拔下并再次插入(或出于某种原因正在重置自身)。进程继续拥有/dev/ttyUSB0
的有效文件句柄,但不会从设备接收任何数据,除非进程重新打开设备(因为 udev 已删除并重新创建设备节点)。
是否有一种直接方法来检测这种情况(即不是间接通过检测数据流超时),以便进程知道它必须重新打开设备?使用stat()
监控/dev/ttyUSB0
的修改时间可靠吗?
其他细节:
进程使用标准open()
函数打开设备文件。
/dev
是由udev
控制的tmpfs
。
注意:我确实不想为此使用任何 udev 规则,并且更喜欢直接在流程中实施的解决方案。
【问题讨论】:
inotify 【参考方案1】:如果 USB 设备是热拔出的,设备上的操作将开始失败并显示-EIO
;您可以检测到这一点并采取适当的措施。
【讨论】:
谢谢,是的,拔掉电源后出现这个错误。我是否可以安全地假设在获取 EIO 时文件描述符已变得无用,或者是否存在导致 临时 EIO 以及文件描述符稍后可以正常工作的情况?目前我已经实现了一个逻辑,它在使用 EIO 进行 read() 之后完全关闭、重新打开和重新初始化设备(调制解调器)。 @Udo: 可能 - 例如,如果您的硬盘出现某种暂时的机械错误,您可能会在一次读取时得到 -EIO,即硬盘恢复,下一次读取成功。但是这不太可能,如果您看到 -EIO,重新初始化设备可能是正确的做法。【参考方案2】:如果设备节点实际上正在被删除并重新创建(如果您有 udev,我相信是这样),那么您应该能够使用 inode 编号来判断这种情况何时发生。
只需在打开的文件描述符上调用fstat()
,在/dev/ttyUSB0
上调用stat()
,然后比较两个struct stat
s 的st_ino
字段。
如果它真的有效,请告诉我。 :-)
【讨论】:
这个策略对我有用。我在 python 中实现了它:github.com/hrchu/python-scsi/blob/… 更新:对于某些设备类型,设备文件的 inode 不会改变。在我的盒子里,USB大容量存储设备的设备文件即使在重新插入后总是具有相同的inode。【参考方案3】:我认为FAM
或gamin
会检测到这些事件。
【讨论】:
以上是关于检测打开的文件/设备是不是已被替换/删除的主要内容,如果未能解决你的问题,请参考以下文章