我如何判断自己是否用尽了inotify watches?

我使用了一个消耗inotify watches的应用程序。我已经设置好了。
fs.inotify.max_user_watches=32768

/etc/sysctl.conf中,但昨晚应用程序停止索引,除非我手动运行它,这让我怀疑我已经用完了监视器。
由于我不知道增加这个数字时的权衡是什么(是否会消耗更多的RAM?),所以我不知道是否应该只增加这个数字,因此我想知道是否有办法可以告诉我是否正在使用所有这些监视器以及增加它可能带来的权衡。

这个问题又变得相当重要了,因为在18.04版本中,如果inode watches用完了,就无法解锁屏幕。 - kasperd
如果我在这里链接的内核补丁被合并,就有可能看到正在使用的inotify监视器数量: https://github.com/prometheus/node_exporter/issues/866#issuecomment-1136379569 - Albert Vaca Cintora
2个回答

如何知道你的手表用完了?尾巴会告诉你!
  • 在任何旧文件上使用tail命令,并加上-f(跟随)选项,例如:tail -f /var/log/dmesg
    • 如果一切正常,它将显示最后10行并暂停;按Ctrl-C中止
    • 如果你的手表用完了,它将以这种有点神秘的错误失败:
      tail: cannot watch '/var/log/dmsg': No space left on device

好奇的人:为什么tail是个“telltail”?

  • 实际上,任何 写得好的应用程序 都应该有礼貌地告诉你,因为 inotify API/调用清楚地告诉它们发生了什么。
  • 可以尝试使用 strace tail -f ...,当成功时,它会以以下方式结束:
    inotify_add_watch(4, "/var/log/dmesg", IN_MODIFY...) = 1
    
  • 但是如果失败了,也就是说 你的监听器已满,它会显示:
    inotify_add_watch(4, "/var/log/dmesg", IN_MODIFY..)
    = -1 ENOSPC (设备上没有剩余空间)
    

你能增加监听器吗?增加多少?有什么权衡之处吗?

简短回答:当然,没问题。如果你愿意,直接增加到五十二万五千个(524288),在现代系统中,额外使用的内存应该是微不足道的,只要系统有4GB以上的内存。

每个使用的inotify watch占用540字节(32位系统)或1 kB(64位双倍)[来源:12]。
这些都来自内核内存,无法交换。
所以,假设您将最大值设置为524288,并且全部被使用(不太可能),您将使用大约256MB / 512MB的32位/ 64位内核内存。
请注意,您的应用程序还将使用额外的内存来跟踪inotify handles、文件/目录路径等,具体取决于其设计。
最大值是多少?理论上没有限制,只要您有足够的RAM。实际上,524288 已经被应用程序官方推荐,而且人们已经将其设置为200万,当然伴随着相应的内存使用。

8如果你还想知道当前的inotify观察器数量(而不仅仅是是/否),请运行sudo lsof | grep -i inotify | wc -l - Frank N
2"well-written-app"的链接已损坏。 - Gaurav Sharma
@FrankNocke 你可能需要对你的grep命令更加小心一些。它可能会捕捉到很多不是inotify监视的东西。例如,如果你有一个名为"inotify.txt"的打开文件,它也会计算在内。实际上,在我的系统上,这似乎捕捉到了两种不同类型的行:一种是NAME(最后一列)为inotify的行,另一种是TASKCMD(第四列)为inotify_reader的行。我不确定这两者中哪一个是真正的inotify监视。 - Nick S

我不知道是否应该只增加这个数字

检查是否达到了max_user_watches值的简单方法是,使用inotify-tools软件包中的inotifywatch命令,并检查您是否仍然可以从文件中收集信息。

例如,对于我来说,运行inotifywatch -v /home/bruno/.profile返回:

Establishing watches...
Total of 1 watches.
Finished establishing watches, now collecting statistics.

所以inotify在创建新的监视时没有任何问题,这里也没有问题。
如果您已经达到了inotify监视的最大限制,它会返回类似以下内容的信息:
Failed to watch /home/bruno/.profile; upper limit on inotify watches reached!

如果你看到类似这样的东西,那么说明你已经达到了限制,并且需要增加允许的监视器数量。
它会消耗更多的内存吗?
是的,确实会。但根据这篇旧文章所说,与运行桌面的其他方面相比,它所消耗的数量是微不足道的。
--内存使用--
inotify的数据结构非常轻量:
每个inotify watch占用40字节 每个inotify设备占用68字节 每个inotify事件占用272字节
因此,假设一个设备有8192个watch,这些结构只会消耗320KB的内存。在同一时间最多允许存在8个设备,总共只需2.5MB的内存。
每个设备还可以同时排队256个事件,每个设备需要68KB的内存。如果所有设备都打开并且事件队列已满,则总共只需0.5MB的内存。
因此,在极少数情况下,即使所有内容都打开并且队列已满,也仅使用约3MB的内存。
每个inotify watch将目录/文件的inode固定在内存中,每个文件系统的inode大小不同,但我们假设为512字节。
因此,假设最大数量的全局watch处于活动状态,这将在inode缓存中固定32MB的inodes。对于现代系统来说,这也不是问题。
我当然是假设自从文章写出来以后情况没有发生太大变化,但是从数据来看,我不会担心,增加限制也不会显著增加内存消耗。

关于inotify的相关帖子


1抱歉,昨天我开着一个草稿几个小时,并没有在发布我的回答前看到你的回复。我想这没关系,因为它们有两种不同的方法 :-) 你能不能简单澄清一下,最近的内核中,inotify每个监视使用0.5千字节(32位)或1千字节(64位)的内核内存,因为2005年的旧信息似乎不再准确? - ish