Storage backends

Storage backends implement the DiskIo trait, the shared abstraction that all storage frontends use to read and write data. A frontend holds a Disk handle and doesn't know what kind of backend is behind it — the same frontend code works with a local file, a Linux block device, a remote blob, or a layered composition of multiple backends.

Backend catalog

BackendCrateWrapsPlatformKey characteristic
FileDiskdisk_fileHost fileCross-platformSimplest backend. Blocking I/O via unblock().
Vhd1Diskdisk_vhd1VHD1 fixed fileCross-platformParses VHD footer for geometry.
VhdmpDiskdisk_vhdmpWindows vhdmp driverWindowsDynamic and differencing VHD/VHDX.
VhdxDiskvhdxVHDX fileCross-platformPure-Rust VHDX parser. Dynamic, fixed, and differencing.
FlatVmdkDiskdisk_vmdkVMDK extentsCross-platformFlat and read-only. Supports the monolithicFlat and twoGbMaxExtentFlat disk types.
BlobDiskdisk_blobHTTP / Azure BlobCross-platformRead-only. HTTP range requests.
BlockDeviceDiskdisk_blockdeviceLinux block device or fileLinuxio_uring, resize via uevent, PR passthrough. Default for raw files on Linux in both OpenHCL and OpenVMM.
NvmeDiskdisk_nvmePhysical NVMe (VFIO)Linux/WindowsUser-mode NVMe driver. Resize via AEN.
StripedDiskdisk_stripedMultiple DisksCross-platformStripes data across underlying disks.

On Windows, disk_vhdmp forwards guest discard through RawSCSIVirtualDisk using the existing virtual-disk handle, without exposing a host disk device. It queries SCSI provisioning and block-limit pages before enabling UNMAP, and only promises zero reads when the driver advertises that guarantee. Discard makes space eligible for reclamation; shrinking the backing file may still require a separate compaction operation.

Decorators

Decorators wrap another Disk and transform I/O in transit. Features compose by stacking decorators without modifying the backends underneath.

DecoratorCrateTransform
CryptDiskdisk_cryptXTS-AES-256 encryption. Encrypts on write, decrypts on read.
DelayDiskdisk_delayAdds configurable latency to each I/O operation.
DiskWithReservationsdisk_prwrapIn-memory SCSI persistent reservation emulation.

Layered disks

A LayeredDisk composes multiple layers into a single DiskIo implementation. Each layer tracks which sectors it has; reads fall through from top to bottom until a layer has the requested data. This powers the memdiff: and mem: CLI options.

Two layer implementations exist today:

The storage pipeline page covers the full architecture: how frontends, backends, decorators, and the layered disk model connect, plus cross-cutting concerns like online disk resize and virtual optical media.

Test disks

Use disk_hook as a dev-dependency when a test needs a configurable disk or I/O hooks. HookDisk::new creates a sparse RAM disk using disklayer_ram, and HookDisk::wrap decorates an existing Disk while forwarding its capabilities. Use new directly instead of wrapping a RAM disk.

Configure a HookDisk, then call into_disk and keep the returned Disk in fixtures. Cloning that handle is cheap and shares storage and hook state. The crate re-exports Disk and DiskError, so callers that need to name those types do not need a direct disk_backend dependency.

with_sync_hook and with_async_hook install a callback for recording operations or injecting failures. Either method replaces any previously installed hook. Hooks run before each operation, receive operation parameters rather than disk contents, and can return a DiskError to prevent the operation. Returning Ok(()) continues normal I/O.

Metadata overrides change what the frontend sees, not the backing disk's capabilities. In particular, only advertise zeroing unmaps if the backend implements them. Ignored unmaps are not forwarded by Disk and do not invoke the hook.