(移自堆栈溢出。)
我有一个简单的备份过程,将一堆文件复制到 USB 闪存驱动器。我想通过重新读取闪存驱动器并将其与原始文件进行比较来验证复制是否成功。我想确保重新读取读取闪存驱动器,而不仅仅是返回 Linux 已缓存的数据。 (我希望闪存驱动器具有内部缓存,但我并不担心这些。)如何以编程方式确保 Linux 删除特定文件系统(或者可能是特定驱动器分区)的缓存信息? (我可以卸载闪存驱动器并物理删除并重新插入它,但我更喜欢编程解决方案。)
我目前正在卸载然后安装文件系统,我预计这会导致 Linux 删除“按文件”组织的缓存数据。但可能存在“按分区”或“按设备”组织的较低级别的块缓存,不受此影响。
我知道echo N >/proc/sys/vm/drop_caches
,但这会删除所有文件系统的缓存块,这比我需要的更广泛,并且可能会导致其他文件系统的性能下降。
有一个 blockdev 命令很适合实现此功能,但它没有删除缓存的选项(从 Linux 5.17.12 开始)。 (它确实有--flushbufs
,但这不是我需要的。)
答案1
这是一个可能的解决方案,但不太理想:事实证明,由于我的备份过程的先前版本,它正在生成我正在备份的文件树的 ISO 9660 文件。我可以使用以下命令将 ISO 复制到备份介质,dd oflag=direct
这样块就不会放入缓存中。然后为了验证备份,我可以使用cmp
,它必须从介质中读取块。可以通过在某处安装 ISO 文件来访问树中的各个文件。
由于写入绕过缓存,因此它们可能无法利用内核中的巧妙算法来批量写入以减少驱动器上的“磨损”。似乎可以通过传输包含整个写入页面的块来避免这种情况。看起来闪存驱动器的写入页面通常为 64kiB 或更少,因此dd bs=128K
应该足够使用几年。
并且dd
似乎正确地复制了尾部部分块。
cp
似乎没有直接写入选项。