linux inotify 事件的 rename() 覆盖
Posted
技术标签:
【中文标题】linux inotify 事件的 rename() 覆盖【英文标题】:linux inotify events for rename() with overwrite 【发布时间】:2014-11-14 14:40:56 【问题描述】:我有一个小型应用程序,它监视特定类型文件名的目录树 (*.monitored)。它统计匹配文件的数量,使用 inotify 监视添加或删除匹配文件的各种事件,并且可以轮询以报告当前文件数,以及过去几次添加和删除文件的平均速率秒。目录树可以包含数十万个文件,因此我试图避免维护受监控文件的列表。
如果我跑步:
touch foo.monitored
我得到了 IN_CREATE,我设置了 num_files=1
touch foo.ignored
我得到 IN_CREATE,忽略它,并保留 num_files=1
mv foo.ignored foo.monitored
生成:
IN_MOVED_FROM for foo.ignored 我忽略了,所以 num_files=1
IN_MOVED_TO for foo.monitored 我将其作为一个新文件,因此设置 num_files=2,但是旧的 foo.monitored 已被覆盖,所以我的总数是错误的。
我找不到表明旧 foo.monitored 消亡的事件 - 有没有办法在不维护庞大的文件名结构的情况下做我想做的事?
谢谢!
【问题讨论】:
投票结束的人应该发表评论。这看起来是一个非常明确的问题。 【参考方案1】:不,inotify 不会在这里为您提供帮助。在这种情况下,它不会发出删除事件。
也许一种折中的解决方案是记录每个目录中有多少被监控的文件,然后在每次收到模棱两可的信号时简单地重新扫描一个目录?
但是,使用 inotify 监控目录树有更大的问题。您是否考虑过如果将包含数千个受监视文件的目录移入或移出树会发生什么?即使在树中移动目录也是有问题的。
编辑:其他想法:
在每个文件上单独添加一个 inotify 监视。这可能不是一个好计划。
计数器只能在您读取时准确;任何读取计数然后期望与读取的内容匹配的调用者都有一个令人讨厌的竞争条件错误等待发生。因此,可以接受计数器可能有一点错误,并在有机会时纠正它。
每 5 次移动事件后进行一次全面扫描。
在移动事件之后,等待 30 秒查看是否还有其他事件,然后才进行扫描。
将树分成多个部分(“桶”),并记录每个部分的计数。这应该会减少扫描开销。
为每个受监控的文件路径记录一个哈希值。与记录实际文件名相比,这可能会减少内存/麻烦。
【讨论】:
谢谢 - 碰巧,我可以很容易地处理来来往往的目录,因为目录树定义明确(如 squid 缓存、dir/0/0/0/files、dir/0 /0/1/files ...),如果一个目录被移入或移出,我可以进行全面重新扫描,但如果我必须对每个 IN_MOVED_TO 进行全面扫描,我不妨停止使用 inotify。 .. 你能建议一种替代方法吗? 我想您可以在每个单独的文件上设置一个 inotify 监视器,但所做的只是将文件名存储移动到其他地方(我不完全确定它会 无论如何都要这样做)。 TBH,我很想记录下文件计数在某些情况下可能只是大致正确,并在您进行全面重新扫描时更正您的计数。你说统计数据只是几秒钟的活动,这种情况可能很少见,所以这可能就足够了吗?也许每当发生不明确的事情时增加一个计数器,然后在达到某个阈值时触发重新扫描? 我在答案中添加了这些以及其他一些想法。以上是关于linux inotify 事件的 rename() 覆盖的主要内容,如果未能解决你的问题,请参考以下文章