使用 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 检测复制操作的主要内容,如果未能解决你的问题,请参考以下文章