Skip to content

fix(vm): keep a stopped VM restorable after a transient restore failure#89

Merged
CMGS merged 1 commit into
masterfrom
fix-restore-keep-stopped
Jul 6, 2026
Merged

fix(vm): keep a stopped VM restorable after a transient restore failure#89
CMGS merged 1 commit into
masterfrom
fix-restore-keep-stopped

Conversation

@CMGS

@CMGS CMGS commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

A hibernated (stopped) VM whose restore failed transiently — host hiccup at launch, snapshot/load, resume — was marked error, and ResolveForRestore refuses error-state VMs: the wake was permanently bricked until the lease reaped the sandbox.

What

  • Backend.FailRestore(ctx, vmID, origin): post-kill restore failures now spare a stopped origin (record, snapshot, and disks untouched by the failed attempt — retry is safe and converges), and mark error otherwise. Called at the two sequence-level failure exits (RestoreSequence/DirectRestoreSequence), replacing the per-backend MarkError defers, which also closes two previously-unmarked running-origin gaps (Wrap and BeforeMerge failures).
  • Run-dir-mutating steps quarantine unconditionally at their own site: a partial MergeDirInto (stream path) or Populate clean-then-clone (direct path) leaves mixed-vintage files in the run dir that vm start must never silently boot — those failures mark error regardless of origin.
  • origin is passed as a parameter deliberately: it is the pre-kill state, and the DB record may already read stopped after the kill's metering flip — re-reading the DB would spare exactly the VMs that must be quarantined.
  • KillForRestore's MarkError is kept: a failed kill of a live VMM is a genuinely unknown state.

Tests

TestFailRestoreSparesStoppedOrigin (helper contract), TestDirectRestoreFailureKeepsOriginContract (sequence-level, 3 cases: post-populate failure spares stopped / quarantines running; populate failure quarantines even stopped), TestRestorePartialMergeQuarantinesEvenStoppedOrigin (in-memory tar staged, genuinely partial merge, quarantined). make lint test green on linux+darwin.

A hibernated (stopped) VM whose restore failed transiently was marked
error, and ResolveForRestore refuses error-state VMs — the wake was
permanently bricked until the lease reaped it. FailRestore now spares a
stopped origin at the two sequence-level failure exits: nothing ran,
record and snapshot are intact, and a retry converges. The run-dir-
mutating steps (staged merge, direct populate) still quarantine
unconditionally — a partial merge or clean-then-clone leaves mixed-
vintage files that vm start must never boot. origin is the pre-kill
state, since metering may flip the DB record to stopped after the kill.
@CMGS

CMGS commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Hardware fault-injection verification (CH, OCI ubuntu:24.04, --nics 0): run → tmpfs marker → vm hibernate (state=stopped) → hide the cloud-hypervisor binary → vm restore fails at launch and the VM stays stopped (old behavior: error, permanently unwakeable) → binary restored → retry succeeds, marker intact, machine-id unchanged.

@CMGS CMGS merged commit 1252646 into master Jul 6, 2026
6 checks passed
@CMGS CMGS deleted the fix-restore-keep-stopped branch July 6, 2026 01:28
CMGS added a commit that referenced this pull request Jul 6, 2026
KillForRestore marked the VM error on any non-ErrNotRunning failure,
including WithRunningVM's fail-closed /proc-scan error. For a hibernated
(stopped) VM the VMM is provably gone — hibernate marks error if its
terminate fails — so a transient scan hiccup during wake bricked a
perfectly restorable VM: ResolveForRestore refuses error state, and
nothing on disk had been touched. Route the failure through FailRestore
(#89's origin-aware helper): stopped origins stay stopped and the wake
remains retryable; a failed kill of a genuinely live VMM on a running
origin still quarantines.

Closes #91
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