据我所知,如果没有并发访问数据的应用程序的配合,ext4 本身无法保证此类事务的原子性。在底层设备映射器中使用某些快照机制也不起作用,因为您基本上需要卸载文件系统(或至少重新挂载-ro)才能在块设备级别获得一致的状态。
我认为如果没有关于应用程序行为的额外知识,这将会非常复杂。因此,最简单的方法可能是以某种方式修改应用程序(例如引入锁定文件)。但是,如果您需要将其视为黑匣子,我将对此做出一些假设:
基于这些假设,我建议采取乐观的方法。简而言之,只需尝试制作目录的常规、递归、非原子副本,然后检查应用程序是否已触及任何文件。如果是这样,则表明您的副本不幸与应用程序的定期自我备份同时发生。在这种情况下,请丢弃您刚刚创建的副本并重试。也许会退缩一段时间;避免占用资源的无限循环。
您可以通过使用 Linux 中的 inotify 机制来实现这一点,作为在此过程中监视要复制的文件的一种手段。如果您想要一个简单的 shell 脚本,请查看inotify-tools。大多数发行版上都包含它。我不完全确定当文件已经打开时 inotify 的行为如何,因此参考假设 2,您可能还想使用它lsof
来确保您的应用程序在源目录的任何内容上都没有打开的文件句柄。设置inotify 手表后执行此操作。
所以这就是我要解决你的情况的方法。我希望您不介意我是否跳过勾画其实际实现。如果有任何不清楚的地方,请随时问我。