mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
The qcow2 backend caches L2 table and refcount updates in memory and only writes them back on a guest-initiated flush, clean shutdown or drop. A paused VM therefore leaves the on-disk image without the mappings for any cluster allocated since the last guest flush: the data clusters are present in the file, but nothing references them. Anything that reads the image while the VM is paused sees those writes as missing. Copying the disk alongside vm.snapshot (the documented snapshot workflow) captures a stale image, and live migration releases the disk locks after pausing so the destination reopens the file with the same stale metadata. In both cases writes the guest has completed, and may later read back, silently disappear. Add a MetadataSync capability trait with a no-op default, fold it into FullDiskFile, implement it for the qcow2 backend as a metadata cache flush, and call it from the virtio-block pause path after in-flight requests have drained. Pause is the quiesce point both flows rely on, and it is a cold path, so the extra flush does not affect runtime I/O. Reproduced by writing to a qcow2 disk from the guest with O_DIRECT and no explicit flush, pausing the VM and copying the image: qemu-img map on the copy shows no mapped clusters and reads return zeros. With this change the copy contains every completed write. A unit test covers the same sequence at the format level: a completed write is invisible to a fresh reader until sync_metadata, and visible after. Signed-off-by: CMGS <ilskdw@gmail.com>