I was looking into an issue I had with Mender, where the installation progress (which is about copying a file on a block device) is not reported correctly.
My feeling is that it's about the kernel page cache: the progress bar says "100%" when the code has read the whole image, but that does not mean that the kernel is done writing it.
More specifically, Mender calls n, err := io.Copy(dev, image)
, which returns after the kernel is done writing. But the progress bar is linked to the "image" Reader
, which is fully read tens of seconds before io.Copy
returns.
Because the file is opened with flags here, I naively thought that I just had to set flag |= O_SYNC
, so that io.Copy(dev, image)
would not read image
faster than it writes to dev
.
But setting O_SYNC
does not make a difference.
It is not clear to me if O_SYNC
is merely a hint (so I cannot count on it), if it could be that I am missing something on my device (say, I forgot a kernel option on my Raspberry Pi and therefore O_SYNC
is useless), or if I just misunderstood what O_SYNC
does?
EDIT: I also tried to set O_SYNC | O_DIRECT
(though O_DIRECT
is apparently not exposed in Go and so I did O_SYNC | 0o40000
), but I got the following error when opening the block device:
Opening device: /dev/mmcblk0p2 for writing with flag: 1069058
Failed to open the device: "/dev/mmcblk0p2": open /dev/mmcblk0p2: not a directory