使用 Inotify 检测复制操作

Posted

技术标签:

【中文标题】使用 Inotify 检测复制操作【英文标题】:Detect a copy operation with Inotify 【发布时间】:2017-05-04 18:24:43 【问题描述】:

我在 ext4 no ubuntu 14.04 上测试 Inotify,在执行复制或创建操作时,我得到以下 Inotify 事件:

cp 文件新文件

IN_CREATE 新文件 IN_MODIFY 新文件 IN_CLOSE 新文件

echo "foo" >> 新文件

IN_CREATE 新文件 IN_MODIFY 新文件 IN_CLOSE 新文件

有没有可能区分这两种情况? 我想知道执行了副本以及源文件和目标文件是什么的信息。 如果 Inotify 无法做到这一点,是否可以通过其他方式做到?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

在 Unix 中没有“复制”之类的东西。即使是用于复制文件的最先进的系统调用(sendfile 和 copy_file_range)最终归结为使用中间缓冲区在两个独立文件之间复制数据。


但您可以使用一些猜测来确定文件副本的确定性程度。

假设

    打开了两个文件:A 和 B(无特定顺序) 从 (IN_ACCESS) 读取 A B 被写入 (IN_MODIFY) A 和 B 已关闭 A 已打开以供读取(由 IN_CLOSE_NOWRITE 标识) B 已打开写入(由 IN_CLOSE_WRITE 标识) A 和 B 之后具有相同的数据大小 (stat.st_size)

注意,上面的顺序只是普通的启发式,不是严格的规则。可能还有其他顺序不那么明显的事件(例如,在打开源文件之前截断或错误定位目标文件—IN_MODIFY)。复制过程可能会取消链接现有目标文件并专门为复制创建新文件,在这种情况下,必须及时使用 inotify (!!) 对新文件进行观察。由于订阅竞赛,您可能会错过一些(或全部)活动,而这些活动在设计上是完全无法检测到的。

您还可能因为 inotify 队列溢出 (IN_Q_OVERFLOW) 而大量错过事件。

Inotify 无法检测对 mmap 文件的内存中操作,并且 mmap 经常用于文件复制。所以整个步骤 2 和 3 可能会丢失。

您尚未指定目标文件系统(以及您是否希望在不受控制的环境中使用 inotify),但请注意,某些文件系统可能不支持 inotify(基于 FUSE 的文件系统和网络文件系统往往特别成问题)。对于 FUSE,这可能取决于特定的文件系统和内核版本。

创建硬链接并不严格限定为副本,但它可能会导致类似于这种情况的事后分析模式(两个文件具有相同大小和相同的明显内容),因此您的应用应该更好地识别 inode。


由于上述原因,使用 inotify 识别副本是一件很麻烦的事,除非您期望获得可观的回报。您应该考虑从识别副本开始,使用静态分析(因为您有时会使用 inotify 退回到它)。

【讨论】:

感谢您的回答。很有帮助。

以上是关于使用 Inotify 检测复制操作的主要内容,如果未能解决你的问题,请参考以下文章

处理多个文件时如何使inotify等待

使用 inotify_read 时,pnctl_signal 不会中断 inotify_read

哪个inotify 事件标志着一个大文件操作的完成?

rsync+inotify实时同步

iNotify 如何检测移出

rsync+inotify实时备份