Skip to content

fix(operator): bound CSI snapshot capture and safely abort stalled quiesced backups #719

Open

Description

@Baylem

A CSI VolumeSnapshot that never reports either readiness or an error can keep a quiesced game's saving disabled indefinitely. The Restic Job deadline does not cover this strategy. Add a persisted CSI capture deadline and an abort policy that invalidates incomplete captures before restoring saves.

Evidence comes from static inspection of master 04e41075cafc4c1a99bcb3723b0a8745ee810957; this review did not stop a CSI controller or reproduce the behavior at runtime. The issue applies to the optional volume-snapshot strategy with quiesce enabled.

Trigger and impact

Create a quiesced CSI backup, then leave its VolumeSnapshot pending by interrupting the snapshot controller/driver or delaying its response. The operator keeps polling because the object has neither readyToUse=true nor a reported error. It has already called save-off for games such as Minecraft.

Deleting the Backup is not a reliable escape. Cleanup first considers the pending CSI capture a live copy and returns before attempting unquiesce. The existing ten-minute unquiesce retry budget starts later in deletion handling, so it does not bound this wait. Other protected backups of the same server also remain behind the owner.

Pinned evidence

Recommended implementation

Persist the capture start/deadline before quiescing so controller restarts retain the same budget. Add a configurable CSI capture timeout independent of the Restic Job deadline. Report elapsed time and the pending capture condition in Backup status.

On expiry, persist a terminal abort decision before cleanup. Extend the existing abort marker into a defined state transition: the capture is invalid for restoration, the operator requests cancellation/deletion where supported, and cleanup may restore saves even if the driver later completes an abandoned capture. Prevent a late readiness event from changing that Backup to Succeeded or assigning it a usable snapshot identity.

Keep cleanup idempotent and UID-bound. Track any abandoned VolumeSnapshot/VolumeSnapshotContent for later reclamation according to its deletion policy, and expose a condition when cleanup needs administrator intervention. Specify deletion-before-deadline behavior so users can cancel a pending operation without waiting forever. Preserve normal worker/capture drainage for successful backups; the timeout path must explicitly invalidate its result.

Acceptance criteria

  • CI covers a snapshot with no status, a stalled non-ready status, and a driver that reports readiness after timeout.
  • Operator restart does not reset the deadline or repeat quiesce after abort.
  • Cancellation and expiry retry save-on and release ownership after the defined safe-abort transition.
  • An aborted capture cannot become a successful or restorable Backup.
  • Missing APIs, ambiguous creation errors, replacement UIDs, and snapshot cleanup failures retain clear conditions and existing protections.

Build on #590's API preflight and creation-error abort handling. Preserve #454's terminal cleanup retries; #573's Job deadline remains a separate Restic control.

Activity

  1. ValgulNecron commented on Oct 20, 2026

    @ValgulNecron
    Collaborator

    Thanks, confirmed on master: markVolumeSnapshotRunning requeues every 10 seconds with no elapsed-time check (operator/internal/controller/backup_volumesnapshot.go:99-120), and a pending capture counts as live (backup_guard.go:381-412), so it blocks unquiesce before the 10-minute finalize budget (backup_controller.go:51) ever applies. A stuck CSI driver can leave the game in save-off indefinitely.

    Go ahead with a PR:

    • Persist a capture deadline before quiescing, independent of the Restic Job deadline. Default 10 minutes, configurable per install.
    • On expiry, write the existing abort marker as a terminal decision so a late ready event can't flip the Backup to Succeeded, then unquiesce.
    • Mark the Backup invalid, request deletion of the VolumeSnapshot (and its content) where the driver supports it, and surface anything that couldn't be cleaned up with a condition so admins can find it.

    This builds on the ownership record from #718, so please reference it.

  2. Baylem commented on Oct 25, 2026

    @Baylem
    MemberAuthor

    Implemented in #772 on top of #760's ownership record for #718. A separate CSI capture deadline is persisted before quiesce, defaults to 10 minutes and is configurable per install. Expiry writes the durable abort decision before save-on; late readiness cannot turn the Backup into a valid restore source.

    Cleanup requests deletion of the original VolumeSnapshot and verified Delete-policy content using UID preconditions. Retain-policy, replaced or otherwise unverifiable resources are left for administrators and identified by the SnapshotCleaned condition. Snapshot reclamation proceeds independently of resuming saving, so a stuck driver cannot extend save-off indefinitely. The regression sources cover expiry/late readiness and Delete, Retain and replacement cleanup cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions