我在ext4 no ubuntu 14.04上测试Inotify,在执行复制或创建操作时,我会在Inotify事件后得到相同的内容:
cp file newfile
IN_CREATE newfile
IN_MODIFY新文件
IN_CLOSE newfile
echo“foo”>> newfile中
IN_CREATE newfile
IN_MODIFY新文件
IN_CLOSE newfile
有没有可能区分这两种情况? 我希望获得有关执行副本以及源文件和目标文件的信息。 如果没有可能通过Inotify进行,可以通过任何其他方式完成吗?
感谢您的帮助。
答案 0 :(得分:1)
Unix中没有“复制”这样的东西。即使是用于复制文件的最先进的系统调用(sendfile和copy_file_range)最终也可以归结为使用中间缓冲区在两个独立文件之间复制数据。
但你可以用一些猜测来确定文件副本的确定性。
假设,
注意,上面的序列只是常见的启发式算法,而不是严格的规则。可能存在其他事件具有不那么明显的顺序(例如,在打开源文件之前截断或分离目标文件-IN_MODIFY)。复制过程可能会取消链接现有目标文件并创建专门用于复制的新文件,在这种情况下,新文件必须及时进行inotify(!!)观察。由于订阅比赛,您可能会错过一些(或所有)事件,这些比赛完全无法通过设计检测到。
由于inotify队列溢出(IN_Q_OVERFLOW),您可能还会大量错过事件。
Inotify无法检测mmap-ed文件中的内存操作,mmap通常用于文件复制。因此可能缺少整个步骤2和3。
您尚未指定目标文件系统(以及您是否希望在不受控制的环境中使用inotify),但请注意,某些文件系统可能不支持inotify(基于FUSE和网络文件系统往往特别成问题)。在FUSE的情况下,这可能取决于特定的文件系统和内核版本。
创建硬链接并不严格限定为副本,但它可能会导致类似于这种情况的事后模式(两个文件具有相同的大小和相同的明显内容),因此您的应用应该更好地了解inode。
由于上述原因,使用inotify识别副本过于繁琐,除非您期望获得显着的回报。您应该考虑从使用静态分析来识别副本开始(因为无论如何您有时会使用inotify回退它)。