使用 Inotify 检测复制操作
Detect a copy operation with Inotify
我在 ext4 no ubuntu 14.04 上测试 Inotify,当执行复制或创建操作时,我得到相同的以下 Inotify 事件:
cp 文件新文件
IN_CREATE 新文件
IN_MODIFY 新文件
IN_CLOSE 新文件
echo "foo" >> 新文件
IN_CREATE 新文件
IN_MODIFY 新文件
IN_CLOSE 新文件
有没有可能区分这两种情况?
我想了解已执行副本以及源文件和目标文件是什么的信息。
如果inotify不行,有没有其他办法可以?
感谢您的帮助。
Unix 中没有"copy" 这样的东西。即使是用于复制文件的最高级系统调用(sendfile 和 copy_file_range)最终也归结为使用中间缓冲区在两个独立文件之间复制数据。
但是您可以使用一些猜测来相当确定地识别文件副本。
假设,
- 打开了两个文件:A 和 B(无特定顺序)
- A 是从 (IN_ACCESS)
读取的
- 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 的情况下,这可能取决于特定的文件系统和内核版本。
创建硬链接严格来说不符合复制条件,但它可能会导致类似这种情况的 post-mortem 模式(两个文件具有相同的大小和相同的外观内容),因此您的应用最好是 inode -知道。
由于上述原因,使用 inotify 识别副本太繁琐了,除非您期望获得可观的回报。你应该考虑从识别副本开始,使用静态分析(因为你有时会退回到 inotify)。
我在 ext4 no ubuntu 14.04 上测试 Inotify,当执行复制或创建操作时,我得到相同的以下 Inotify 事件:
cp 文件新文件
IN_CREATE 新文件
IN_MODIFY 新文件
IN_CLOSE 新文件
echo "foo" >> 新文件
IN_CREATE 新文件
IN_MODIFY 新文件
IN_CLOSE 新文件
有没有可能区分这两种情况? 我想了解已执行副本以及源文件和目标文件是什么的信息。 如果inotify不行,有没有其他办法可以?
感谢您的帮助。
Unix 中没有"copy" 这样的东西。即使是用于复制文件的最高级系统调用(sendfile 和 copy_file_range)最终也归结为使用中间缓冲区在两个独立文件之间复制数据。
但是您可以使用一些猜测来相当确定地识别文件副本。
假设,
- 打开了两个文件:A 和 B(无特定顺序)
- A 是从 (IN_ACCESS) 读取的
- 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 的情况下,这可能取决于特定的文件系统和内核版本。
创建硬链接严格来说不符合复制条件,但它可能会导致类似这种情况的 post-mortem 模式(两个文件具有相同的大小和相同的外观内容),因此您的应用最好是 inode -知道。
由于上述原因,使用 inotify 识别副本太繁琐了,除非您期望获得可观的回报。你应该考虑从识别副本开始,使用静态分析(因为你有时会退回到 inotify)。