Skip to content

vhost-user-blk: support snapshot and restore - #38

Draft
dangra wants to merge 1 commit into
v1.14.4-flyfrom
vhost-user-blk-snapshot
Draft

dangra wants to merge 1 commit into
v1.14.4-flyfrom
vhost-user-blk-snapshot

Conversation

@dangra

@dangra dangra commented Nov 2, 2026

Copy link
Copy Markdown
Member

Prototype: snapshot and restore for vhost-user-blk devices. Today a snapshot skips them, so a restored microVM comes back without its data drive.

What changes

  • Save. Before its state is saved, the device stops its ring with VHOST_USER_GET_VRING_BASE. The backend completes what it took into the used ring and replies with the next available index, which becomes the queue's saved position.
  • Restore. Connect to the socket again, require exactly the features and protocol features negotiated before (new RestoreFeatures error otherwise), and hand the ring over at the saved index. Resuming the same microVM after a snapshot restarts the ring the same way.
  • Ring base. SET_VRING_BASE now sends the queue's next available index rather than the guest's available index.
  • Missed interrupt. vCPU and transport state are saved before devices, so a completion the backend writes in between finds the interrupt state already saved. The queue interrupt is raised once on resume.
  • Memory.
    • A backend needs guest memory it can map, so restoring from a File memory backend copies the snapshot's memory into a memfd and maps it shared.
    • Mapping the file itself shared was rejected: guest writes would change the snapshot, and it could not be restored twice.
    • Restoring with Uffd is refused for microVMs with vhost-user devices.
  • Features. SIZE_MAX, SEG_MAX, BLK_SIZE, DISCARD and WRITE_ZEROES are offered when the backend offers them.

No seccomp changes: device restore runs before the filter is installed, and stopping and restarting the ring only uses sendmsg/recvmsg.

Not done

  • Restore cost. The memfd copy costs time in proportion to guest memory on every restore. A lazy alternative has not been explored.
  • Reconnect. There is no reconnect outside restore: a backend that goes away while the microVM runs still takes the drive with it.
  • Python integration tests are not written yet.

Testing

  • New unit tests across vhost_user, block, queue and persist. The surrounding device_manager, vhost_user, block, queue and persist tests pass, except test_device_manager_persistence, which fails attaching pmem before any block code runs. That looks environmental and pre-existing, but it has not been checked on the base commit.
  • Exercised end to end with a release musl build, seccomp on, over repeated snapshot/restore cycles with data verification, with the backend kept running, restarted, or killed between cycles.

Snapshotting a microVM with a vhost-user block device skipped the device
entirely, so a restored microVM had no data drive.

Save the device like any other virtio device. Before its state is saved,
stop the ring with VHOST_USER_GET_VRING_BASE: the backend completes what
it took into the used ring and replies with the next available index,
which becomes the queue's saved position. On restore, connect to the
socket again, require the features negotiated before, and hand the ring
over at that index. Resuming the same microVM after a snapshot restarts
the ring the same way.

A backend needs guest memory it can map, so restoring from a File memory
backend copies the snapshot's memory into a memfd and maps it shared.
Mapping the file itself would let guest writes change the snapshot.
Restoring with Uffd is refused for microVMs with vhost-user devices.

vCPU and transport state are saved before devices, so a completion the
backend writes in between finds the interrupt state already saved. Raise
the queue interrupt once on resume so the guest sees it.

Also offer SIZE_MAX, SEG_MAX, BLK_SIZE, DISCARD and WRITE_ZEROES when
the backend does, and send the queue's next available index as the
ring base rather than the guest's available index.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant