Repository navigation
feat(disk): vm disk attach --from-snapshot/--from-dir attaches a snapshot's COW copy - #285
Merged
Merged
Conversation
…p take glob patterns The snapshot disk attach copies only the sidecar's cow entry, by basename, so another node's sidecar works. Stop needs to sweep per-name copies, which fixed runtime names cannot express; non-pattern names keep the plain remove so dangling symlinks still go.
Identity check, pre-check, copy and vm.add-disk all run under one ops lock, so a retry after a lost result returns the attached disk instead of truncating its file. Detach removes the copy after the eject; stop, restore and start sweep snapdisk-* with the runtime files.
…lope Both export paths fill disk_attach_files from the sidecar, so an archive consumer fetches only those. A snapshot without a sidecar exports as before, without the field.
…apshot/--from-dir --from-snapshot holds the snapshot's read lease across the attach; --from-dir reads the envelope. The cmd layer resolves the local cloudimg base so the hypervisor stays free of image-store knowledge. --name defaults to snap-<id prefix>; --readonly and --directio do not apply to the copy.
The sidecar is cocoon-written and a degenerate cow path already fails the copy loudly, so the basename guard defended nothing reachable.
… and remove responses A lost vm.add-disk response may have attached the copy, so the error path no longer unlinks it; a retry, detach or stop reclaims it. A detach whose vm.remove-device response was lost finds no device, so the copy cleanup now also runs on that path.
With a caller-chosen name two snapshots of one image could share a copy path, and the idempotent pre-check then returned the first snapshot's disk for the second. Deriving the name from the snapshot id makes a repeat of the same snapshot a no-op and gives different snapshots different disks.
Contributor
Author
Hardware acceptanceBare-metal node (Linux 6.12 amd64, XFS data volume), Cloud Hypervisor v54, isolated lane with its own root, run dir and CNI bridge. Images:
Not run on hardware: same layers in a different order (no such image pair exists; unit test only). Timings (XFS unless noted):
|
This was referenced Oct 18, 2026
CMGS
added a commit
that referenced
this pull request
Oct 18, 2026
…deps, docs) (#286) Orphan sweep matches the VMM cmdline instead of kill(0) so an exited, unreaped scan match is not reported killed; Firecracker validates the disk detach name before locking; modern-go and reuse cleanup; dependency and lint tool bumps; docs synced with the code and the v0.7.2 release.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #284.
What
vm disk attach VM --from-snapshot SNAPSHOTand--from-dir DIRhot-attach a private read-write copy of a snapshot's COW disk to a running Cloud Hypervisor VM. The reader VM runs the same image as the sleeping VM, so it already has the image's read-only disks (erofs layers for OCI, the qcow2 base for cloudimg); cocoon hands over only the COW copy. The memory image is never read.image_blob_idsmust equal the target VM's, read from the record reloaded under the ops lock. Digests only, so another node's export works when the image is local. A mismatch is refused with both sides in the error.role=cowentry ofcocoon.jsonnames the file (cow.raw/overlay.qcow2). It is reflinked, without fsync, into the target's run dir assnapdisk-<name>.<raw|qcow2>and attached through the existing add-disk path. A qcow2 copy is always rebased (qemu-img rebase -u) onto the local base blob, since an imported snapshot keeps the source node's backing path.vm.add-diskresponse leaves the copy for the retry; a lostvm.remove-deviceresponse still reclaims it on the next detach.vm rmwith the run dir, and swept wherever runtime files are cleaned after the VMM is dead (stop, hibernate, restore kill, start prepare, failed launch):CleanupRuntimeFilesnow expands glob patterns.snapshot.jsongains the additivedisk_attach_files(["cocoon.json", <cow file>]) in both the tar and--to-direxports, so an archive consumer fetches only those.format(raw|qcow2). The copy is always namedsnap-<first 8 chars of the snapshot id>, so a repeat of the same snapshot is a no-op and two snapshots never share a disk;--name,--readonlyand--directioare refused with the snapshot sources. Firecracker is unsupported (its drives carry no serial).Nothing is pinned and GC is unchanged: the target VM's own record pins the image blobs. No change on the create, clone or claim paths; each lifecycle cleanup adds one ReadDir of the run dir.
Verification
go build ./...,go vet ./...,asl -forwarder=false ./...: clean.make lint:0 issues.for GOOS=linux and GOOS=darwin.gofumpt -extra -l .,goimports -l: no output.go test ./...on darwin and, for the touched packages, indocker run --platform linux/arm64 golang:1.27.1: all ok.Hardware acceptance on a bare-metal node is in the first comment: real attach and guest mount with journal replay on OCI and cloudimg, the source snapshot byte-identical afterwards, the memory image never opened, qcow2 rebase from another root, repeat attach, detach, stop and
vm rmcleanup,--from-dirfrom a three-file export, image mismatch and Firecracker refusals, and the copy time on XFS (0.05 s) versus ext4 (1.1 s for 1.6 GiB allocated).