Skip to content

Commit b7b74c4

Browse files
committed
refactor(backup): mirror snapshot-style delete chain for NAS incrementals
Per @abh1sar's review at NASBackupProvider.java:696, the previous rebase-the-child / chain-repair logic is hard to reason about and not consistent with how CloudStack handles incremental-snapshot deletion elsewhere. Replace it with the same pattern used by DefaultSnapshotStrategy#deleteSnapshotChain: * Delete request for backup B1: * If B1 has live children, mark B1 with nas.delete_pending=true and return. The on-NAS file and DB row stay until the last descendant is gone. * If B1 has no live children, physically delete its qcow2 directory and DB row, then walk up the chain — for each ancestor that is delete-pending and now childless, sweep it too. * forced=true cascades the entire subtree leaf-first in one call (for operators who want a chain gone immediately). Drops the rebase code path entirely from NASBackupProvider (the old ChainRepairPlan / RebaseStep / PositionShift inner classes and the RebaseBackupCommand dispatch). The RebaseBackupCommand class and its libvirt wrapper remain in tree as dead code for now — separate cleanup. Tests: * New deleteWithLiveChildMarksDeletePendingAndPreservesFile verifies the tombstone-on-busy-parent path: no agent traffic, no DB removal, a DELETE_PENDING detail is persisted. * New deletingLeafSweepsUpDeletePendingParent verifies the sweep: deleting the last child cascades up and physically deletes the tombstoned parent. * Existing testDeleteBackup still passes — without a CHAIN_ID detail the backup hits the no-chain fast path.
1 parent 7e1691b commit b7b74c4

3 files changed

Lines changed: 321 additions & 196 deletions

File tree

plugins/backup/nas/src/main/java/org/apache/cloudstack/backup/NASBackupChainKeys.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ public final class NASBackupChainKeys {
4545
/** Set to the bitmap name when this incremental had to recreate its parent bitmap on the host (informational; this incremental is larger than usual). */
4646
public static final String BITMAP_RECREATED = "nas.bitmap_recreated";
4747

48+
/**
49+
* Tombstone key stored in {@code backup_details} when a backup is requested for deletion
50+
* but still has live children. The on-NAS file is preserved until the last child is gone,
51+
* at which point cascade deletion collects every tombstoned ancestor. Mirrors the snapshot
52+
* subsystem's {@code Hidden} state semantics (see {@code DefaultSnapshotStrategy}).
53+
*/
54+
public static final String DELETE_PENDING = "nas.delete_pending";
55+
4856
/**
4957
* VM-scoped detail (stored in {@code vm_instance_details}) holding the QEMU dirty-bitmap
5058
* name that currently exists on the running VM and is therefore the only valid parent

0 commit comments

Comments
 (0)