O_SYNC什么时候有效果?

When does O_SYNC have an effect?

我正在调查我遇到的 Mender 问题,其中安装进度(关于在块设备上复制文件)未正确报告。

我的感觉是关于内核页面缓存:当代码读取整个图像时进度条显示“100%”,但这并不意味着内核已完成写入。

更具体地说,Mender 在内核完成写入后调用 n, err := io.Copy(dev, image),returns。但是进度条链接的是“图片”Reader,在io.Copyreturns.

前几十秒完整读取

因为文件是用标志here打开的,我天真地以为我只需要设置flag |= O_SYNC,这样io.Copy(dev, image)就不会比image读得快它写入 dev.

但是设置O_SYNC并没有什么不同。

我不清楚 O_SYNC 是否只是一个提示(所以我不能指望它),是否可能是我的设备上遗漏了一些东西(比如,我忘记了内核选项在我的 Raspberry Pi 上,因此 O_SYNC 没用),或者如果我只是误解了 O_SYNC 的作用?

编辑:我也尝试设置 O_SYNC | O_DIRECT(虽然 O_DIRECT 显然没有在 Go 中公开,所以我做了 O_SYNC | 0o40000),但是打开时出现以下错误块设备:

Opening device: /dev/mmcblk0p2 for writing with flag: 1069058
Failed to open the device: "/dev/mmcblk0p2": open /dev/mmcblk0p2: not a directory

总结评论:

  1. 主要问题是进度条装饰的是reader(如),而不是作者;延迟在作者一方。

  2. 在大多数Linux系统上,O_DIRECT确实是0o40000,但在ARM(包括Raspberry Pi)上是0o200000 ,其中 0o40000O_DIRECTORY。这解释了“不是目录”错误。

  3. O_SYNC 实际上是您想要的位,或者您可以简单地发出 fsync 系统调用(如果合适,使用 Flush,然后 Sync,如 When to flush a file in Go? 中所述)。 O_SYNC 位意味着 fsync 系统调用作为每个 write 系统调用的一部分。

完全同步I/O有点像雷区:有些设备会谎报它们是否已将数据写入非易失性存储。但是,O_SYNCfsync 是您到达这里的最大保证。 O_DIRECT 可能无关紧要,因为您要直接转到设备分区 /dev 文件。 O_SYNCfsync 可能 被传递给设备驱动程序,可能 对其进行一些处理,可能让设备写入非易失性存储。

中有更多相关内容