使用 INotify 监视具有多个符号链接的文件

Posted

技术标签:

【中文标题】使用 INotify 监视具有多个符号链接的文件【英文标题】:Use INotify to watch a file with multiple symlinks 【发布时间】:2015-02-27 16:13:45 【问题描述】:

所以我设置了一些代码来监视配置文件进行编辑,直到我使用 VIM 来编辑文件之前,它一直有效,然后我还必须监视目录以进行重命名和创建。然后我发现在路径层次结构中没有捕获更高的重命名。然后我查看了符号链接...gaaahhhh!

首先设置一个虚构的示例,展示一个(许多)棘手的符号链接场景:

mkdir config1
touch config1/config
ln -s config1 machine1

mkdir config2
touch config2/config
ln -s config2 machine2

ln -s machine1 active

现在,给定一个我想要查看的文件名,例如 active/config,我可以看到如何获取以下内容的 inotify 监视描述符:

config1/ -> watch active/ follow symlinks (watches inode for config1)
active/ -> watch active/ dont follow symlinks (watches inode for active symlink
active/config -> watch active/config (watches inode for config1/config)

如何在 machine1 符号链接上添加手表?我是否需要找到某种方法来手动遍历每个符号链接,并在此过程中为每个符号链接添加手表?怎么样?

目的是允许:

mkdir config3
touch config3/config
ln -s -f -n config3 machine1

并且有 inotify 警告 active/config 已被重定向。目前看来我必须添加手表:

- target file inode
- every directory inode leading to the file (to detect moves/renames of directories)
- every symlink inode involved in reaching any of the above

必须有一种更简单的方法来观看一个文件吗?是我迷路了还是真的是这样?

【问题讨论】:

你看的不是“一个文件”——你看的是它的完整路径,包括文件。加上inotify 不是递归的,涵盖了前两点。符号链接的存在是您最后一点的要求。 是的,我明白必须设置 INotify 以监视所有涉及访问感兴趣文件的 inode,但我不清楚 不 需要做我所描述的?它很复杂(我什至没有提到 '..' 和符号链接),很容易搞砸(引用计数多次遇到的目录和符号链接),有很多竞争条件(在有人更改符号链接时观看它?),而且每个人似乎需要它。但是没有图书馆可以做到这一点?呵呵。 尽管有所有缺点,但 inotify 仍然比它所取代的 dnotify 好很多(例如,参见lwn.net/Articles/604686)。至于缺少库,您没有提到您正在寻找它们; libinotiftytools 可以稍微简化您的任务(它为您执行系统调用),但我找不到任何涵盖您确切用例的内容。 【参考方案1】:

我的回答是直截了当的“是的,你做得对”。

在仔细阅读inotify syscall manpage 之后,我看不出有什么办法可以不查看(可能是符号链接的)文件路径的每一步,以检测对完整路径的任何和所有更改。

这似乎是inotify 的工作方式:它只查看特定的文件或文件夹,并且它自己不进行递归。加上必须明确遵循符号链接,这似乎与您的三步计划相符。

从手册页中选择的引号:

在调用 inotify_add_watch(2) 时,可以在 mask 中指定以下进一步的位: IN_DONT_FOLLOW(自 Linux 2.6.15 起)

如果它是符号链接,请不要取消引用路径名。

[...]

限制和警告

Inotify 监视目录不是递归的:要监视目录下的子目录,必须创建额外的监视。对于大型目录树,这可能会花费大量时间。 [...]

这个FAQ 也为您的策略重新符号链接提供支持:

问:IN_ONLYDIR 和 IN_DONT_FOLLOW 标志怎么样? IN_ONLYDIR 确保事件仅在目录上发生。如果您在文件上创建这样的监视,它将不会发出事件。 IN_DONT_FOLLOW 禁止跟随符号链接(这些链接将被自己监控,而不是它们指向的文件)。

【讨论】:

以上是关于使用 INotify 监视具有多个符号链接的文件的主要内容,如果未能解决你的问题,请参考以下文章

rsync+inotify实时同步

在 perl 中使用 inotify 监视多个文件

关闭文件描述符并删除 inotify watch 真的有必要吗?

c++ inotify - 监视多个目录/子目录

inotify_add_watch 是不是按升序返回监视描述符?

C程序使用inotify监视多个目录以及子目录?