列出“inotify”实例正在监视的文件

列出“inotify”实例正在监视的文件

我有一个小脚本它列出了每个进程的 inotify 监视数量。这通常能让我得到我想要的东西,但现在我想知道哪个文件正在被监视。我认为这是可能的,并且inotify手表对应于inotify实例正在监视的文件?

我也认为我可以基于该脚本中当前的内容进行构建。例如,

sudo find /proc/*/fd -lname anon_inode:inotify  | cut -d "/" -f 3

inotify获取带有文件描述符的进程列表。如果我查看其中一个文件描述符的信息,我会得到我假设的文件句柄/监视列表:

$ sudo cat /proc/50679/fdinfo/19
pos:    0
flags:  00
mnt_id: 15
inotify wd:8 ino:640001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01006400feaad211
inotify wd:7 ino:a08da sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:da080a0094019e8f
inotify wd:6 ino:840003 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:030084005ae9e3df
inotify wd:5 ino:840002 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:020084000d506c1f
inotify wd:4 ino:840001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01008400e47bab26
inotify wd:3 ino:32004e sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:4e003200488122df
inotify wd:2 ino:320001 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:01003200545a9f32
inotify wd:1 ino:2 sdev:800001 mask:3cc ignored_mask:0 fhandle-bytes:8 fhandle-type:1 f_handle:0200000000000000

我希望我能找出f_handle:01003200545a9f32对应的文件,基本上将f_handle/proc/../fdinfo/ 中的 a 翻译为文件名。

答案1

我不知道处理该f_handle领域的标准工具。对于系统调用来说这会很方便open_by_handle_at(2),但无论如何该字段可能并不总是有效。例如内核nfsd不提供它。

然而,Linux 中任何文件的完整坐标仍然是旧的设备号和 inode 号,它们在sdevino字段中报告。这只是解码它们的问题。

这两个值(当前)以十六进制表示法表示。您可以照ino原样,只需将其转换为十进制表示法即可。

sdev 另一方面,该值需要一些解码,因为您需要将其拆分为传统的“主要和次要”设备号。请注意,即使驻留在不受实际块设备支持的文件系统中的文件仍然带有唯一的伪设备编号,该编号会在该sdev字段中报告。

假设该sdev字段根据 Linux 所谓的“巨大编码”进行编码,该编码使用 20 位(而不是 8 位)表示次数,按位的说法,主数是 ,sdev >> 20次数是sdev & 0xfffff。或者使用外行文本操作方法,次要数字是最右边(最多)5 个十六进制数字,而主要数字是最后 5 个十六进制数字之前的所有内容。如果少于 5 个十六进制数字,则主编号就是0

一旦获得了主修和辅修,你就可以在目标进程mountinfo文件。在你的例子中,那就是/proc/50679/mountinfo.具体来说,您寻找一条带有这样major:minor对的线路第三场地。找到的线的第五find字段是您寻找所需文件/目录的最终所需的路径。

笔记:inotify从in 行获取的主要和次要/proc/*/fdinfo/*以十六进制表示,但 inmountinfo以十进制表示,因此在 中搜索之前需要将它们转换mountinfo

笔记:中的第五个字段mountinfo可能包含\转义的八进制序列,以防其\本身或 <space>、<newline>、<tab> 字符是路径的一部分。这意味着空格被编码为\040、 a\\134。您可以通过例如将该路径提供给printf(1)自己的说明符来取消转义%b

笔记:为了考虑命名空间(即容器),您需要find在挂载命名空间中运行最终命令目标进程生活在,因此例如(对于你的例子):

nsenter -mt 50679 find "$unescaped_path" -inum "$decimal_ino" -print -quit

相关内容