Skip to content

[17.0] volumemgr: retry failed volume deletes instead of leaking them - #6205

Merged
eriknordmark merged 1 commit into
lf-edge:17.0from
rene:17.0-fix-volumedelete-after-prune
Jul 22, 2026
Merged

[17.0] volumemgr: retry failed volume deletes instead of leaking them#6205
eriknordmark merged 1 commit into
lf-edge:17.0from
rene:17.0-fix-volumedelete-after-prune

Conversation

@rene

@rene rene commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Description

Backport of #6176

How to test and validate this PR

Changelog notes

Implement deletion of Longhorn orphan volumes created after failed purge operations.

Checklist

  • I've provided a proper description
  • I've added the proper documentation
  • I've tested my PR on amd64 device
  • I've tested my PR on arm64 device
  • I've written the test verification instructions
  • I've set the proper labels to this PR
  • I've added a reference link to the original PR
  • PR's title follows the template
  • I've checked the boxes above, or I've provided a good reason why I didn't
    check them.

maybeDeleteVolume logged a failed volume delete, set the error, and
unpublished the VolumeStatus anyway ("we have no retrial mechanism for
volume delete now"). Once the status was gone volumemgr had no record of
the volume, so nothing retried and the underlying PVC/Longhorn volume was
leaked forever.

This is how a failed+retried app purge on a kubevirt/longhorn cluster
ends up with several orphaned Longhorn volumes for one app: each purge
bumps the volume generation counter, so GetPVCName() yields a new PVC
name (<VolumeID>-pvc-<gen>) and a new Longhorn volume, while the old
generation's delete was fire-and-forget and dropped on failure. For a
replicated volume the owner node being unreachable at delete time (mid
-purge, or during a node reboot for a cluster update) is enough to
trigger it. The leaked volumes keep replicating and consuming space and
don't show in the Longhorn UI (no PV/PVC/workload binding them).

On delete failure, keep the VolumeStatus published in the Deleting
sub-state with the error and re-drive it from the gc tick via
retryFailedVolumeDelete, mirroring the bounded, gc-driven pattern already
used for transient cluster-volume creates (retryclustervolume.go): a pure
volumeDeleteRetryActionFor decision function, a per-volume retry count in
an in-memory map, and give-up after maxVolumeDeleteRetries so a
permanently-undeletable volume parks terminally rather than resubmitting a
worker job forever. On give-up the volume is left published in the
Deleting sub-state with its error (like the cluster-create give-up) so an
orphaned, undeletable volume stays visible to the operator in status
instead of disappearing; it just stops being re-driven. On successful
delete, or when the volume leaves the candidate set another way (e.g. it
gets re-referenced), the retry count is cleared.

Signed-off-by: Renê de Souza Pinto <rene@renesp.com.br>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
(cherry picked from commit 55edeb4)
@eriknordmark eriknordmark added the next-17.0.x-rc PR must be present in the next 17.0.x-lts release label Jul 22, 2026

@eriknordmark eriknordmark left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@eriknordmark
eriknordmark merged commit 8682a16 into lf-edge:17.0 Jul 22, 2026
34 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

next-17.0.x-rc PR must be present in the next 17.0.x-lts release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants