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

oli*_*ren 5 linux ubuntu inotify

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

我还假设我可以基于该脚本中当前的内容进行构建。例如,

sudo find /proc/*/fd -lname anon_inode:inotify  | cut -d "/" -f 3
Run Code Online (Sandbox Code Playgroud)

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

Run Code Online (Sandbox Code Playgroud)

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

LL3*_*LL3 7

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

\n

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

\n

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

\n

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

\n

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

\n

一旦获得主要和次要,您就可以在目标进程的文件中查找它们mountinfo。在你的例子中,那就是/proc/50679/mountinfo. 具体来说,您要寻找一条带有第三个major:minor字段的行。找到的行的第五个字段是您寻找所需文件/目录的最终所需的路径。find

\n

注意:inotifyin 行中获取的主调和副调/proc/*/fdinfo/*是用十六进制表示的,而 inmountinfo是用十进制表示的,所以在 中搜索之前需要将它们转换mountinfo

\n

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

\n

注意:为了考虑命名空间(即容器),您需要在目标进程find所在的挂载命名空间中运行最终命令,因此例如(对于您的示例):

\n
nsenter -mt 50679 find "$unescaped_path" -inum "$decimal_ino" -print -quit\n
Run Code Online (Sandbox Code Playgroud)\n