运行 `sync` 写入磁盘映像后是否有必要?

Is running `sync` necessary after writing a disk image?

将图像写入磁盘的常用方法如下所示:

dd if=file.img of=/dev/device

这条命令后,是否需要运行sync

sync(2) 解释说它只刷新文件系统缓存。由于dd命令与任何文件系统无关,我认为没有必要运行sync。但是block layer复杂且存疑,大多数人更喜欢运行 sync.

有没有人有证据证明它是有用的还是没用的?

TL;DR: 运行 blockdev --flushbufs /dev/devicedd.

之后

我尝试遵循内核中的不同路径。这是我的理解:

  • ioctl(block_dev, BLKFLSBUF, 0) 调用 blkdev_flushbuf()。考虑到它的名字,它应该刷新与设备相关的缓存(或者我认为你可以认为设备驱动程序中存在错误)。我认为它还应该负责刷新硬件缓存(如果存在)。注意 e2fsprogs use BLKFLSBUF.
  • fdatasync()(和 fsync())将调用 blkdev_fsync()。它看起来像 blkdev_flushbuf() 但它只影响当前进程写入的数据范围(它使用 filemap_write_and_wait_range()BLKFLSBUF 使用 filemap_write_and_wait)。
  • 关闭不刷新缓冲区的块设备调用 blkdev_close()
  • sync() 会调用 sync_fs()。它将刷新文件系统缓存并在底层块设备上调用 fsync()
  • 命令 sync /dev/device 将在 /dev/device 上调用 fsync()。但是,我认为它没用,因为 dd 没有触及任何文件系统。

所以我的结论是调用 sync 对块设备没有(直接)影响。但是,fdatasync(或 fsync)传递给 dd 是保证数据正确写入介质的唯一方法.

如果你运行dd但是你错过了fdatasync,运行宁sync /dev/device是不够的。您必须在整个设备上 运行 ddfdatasync。或者,您可以调用 BLKFLSBUF 来刷新整个设备。不幸的是,没有标准的命令。

编辑

您可以使用 blockdev --flushbufs /dev/device 发出 BLKFLSBUF

为确保在拔出 USB 设备之前将数据刷新到 USB 设备上,我使用以下命令:

    echo 1 > /sys/block/${device}/device/delete

这样就刷出数据了,如果设备是硬盘,则磁头停放。