Repository navigation
feat(disk): vm disk attach and detach are idempotent - #282
Merged
Merged
Conversation
Attaching a disk that is already attached under the same name, path and mode now succeeds with its existing id instead of failing; the same name with a different path or mode is still refused. Detaching a name that is not attached succeeds with a warning log. A caller that retries after a crash or a lost reply (sandboxd converging a sandbox's volume set) can call either command again without parsing inspect output or matching error text. Both Cloud Hypervisor and Firecracker.
…oud Hypervisor check
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.
What
cocoon vm disk attachandcocoon vm disk detachbecome idempotent on both Cloud Hypervisor and Firecracker (--pci).disk name "x" already attachedalready attached with a different path or mode)disk "x" not attacheddisk "x" not attachedvm.remove-deviceThe decision is made under the existing VMM operation lock, from the same
vm.info/ drive-config snapshot the pre-checks already read, so a concurrent attach or detach of the same VM still serializes.Why
sandboxd hot-attaches catalog volumes into running VMs, and cocoonstack/sandbox#339 proposes attaching and detaching them on a live sandbox. A control plane that converges a desired volume set has to retry after a crash or a lost reply. Today it can only learn whether a retry is needed by parsing
vm inspect'sattached_devices(which inspect drops when the VMM query fails) or by matching thenot attachederror text. With idempotent calls it simply calls attach or detach again.Changes
hypervisor/cloudhypervisor/extend.go:preCheckFnnow returns(existingID, error), andattachWithreturns the existing id without calling the VMM when the pre-check reports one.diskAttached(same serial and path guards as before).DiskDetachwarns and returns nil for an absent disk.findIDFnnow returns(id, remove, err). CH drops a disk fromconfig.disksas soon asvm.remove-devicereturns, but keeps it indevice_treeuntil the guest acks the eject. So a disk found only indevice_treeis a pending removal:detachWithskips the remove call and waits for the eject. Without this, a retry after an eject-wait timeout would report success while the slot and backing file are still held.hypervisor/firecracker/extend.go:checkDriveFreebecomesdriveAttached(identical drive → attached, conflicting one → error), andDiskDetachwarns and returns nil for an absent drive.docs/devices.md: states the idempotency contract.Hot path: zero added VMM calls. Both the pre-check and the pending-eject check read the
vm.infosnapshot already taken under the ops lock. An identical re-attach skipsvm.add-diskentirely.Tests
TestDiskAttached(CH, new) andTestDriveAttached(FC, replacesTestCheckDriveFree) are table tests over the free, identical, same-name-other-path, same-name-other-mode, serial-in-use (CH) and same-path-other-name cases.make lint:0 issues.on linux and darwin.golangci-lint fmt --diff: clean.aslon darwin and linux: clean.go test -race -count=1 ./...: passes.LockedRunningOp, which needs a VM record and a live VMM, and no existing test drives that. The eject wait itself is covered byTestCHNICOpsRemoveNICWaitsForEject.