mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
For memfd-backed guest RAM regions, walk the backing fd extent by extent via lseek(SEEK_DATA) / lseek(SEEK_HOLE) and write each populated extent into the snapshot file's per-region slot via std::os::unix::fs::FileExt::write_at. Pre-size the file with set_len(total): on filesystems that support sparse files unwritten bytes become real holes; on others the kernel zero-fills the allocation, which is still byte-correct. If set_len fails (some FUSE backends reject ftruncate-extend with EOPNOTSUPP), fall back entirely to the dense write path which streams bytes sequentially via write_volatile_to and never writes past the growing EOF. When the guest region has no backing file (anonymous mmap) or the backing fd does not support SEEK_HOLE (hugetlbfs), fall back to the dense write path on a per-region basis. The on-disk byte stream is identical to the dense format from the perspective of any reader using read/pread/mmap, so old readers see no change. Measured on a 4 GiB shared-memory VM (2 vCPUs, ~340 MiB touched), total snapshot time as reported by the in-tree timing instrumentation: Before (dense): ~2400ms, 4.0 GiB on disk After (sparse): ~132ms, 340 MiB on disk (92% smaller, 18x faster) Assisted-by: Claude:Opus-4.7 Signed-off-by: Rob Bradford <rbradford@meta.com>