From f3d40f9e5ae5fc73ca8bee290e95edd580f5d929 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 6 Nov 2024 14:04:55 +0100 Subject: [PATCH] rbd: cleanup inconsistent state in `reserveSnap()` after a failure `reserveSnap()` can potentially fail halfway through, in that case it needs to undo the snapshot reservation and restore modified attributes of the snapshot. Fixes: #4945 Signed-off-by: Niels de Vos --- internal/rbd/rbd_journal.go | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/internal/rbd/rbd_journal.go b/internal/rbd/rbd_journal.go index 38f4c8c70..8827f5c7d 100644 --- a/internal/rbd/rbd_journal.go +++ b/internal/rbd/rbd_journal.go @@ -388,6 +388,18 @@ func (ri *rbdImage) repairImageID(ctx context.Context, j *journal.Connection, fo func reserveSnap(ctx context.Context, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, cr *util.Credentials) error { var err error + // restore original values in case of an error + origReservedID := rbdSnap.ReservedID + origRbdSnapName := rbdSnap.RbdSnapName + origVolID := rbdSnap.VolID + defer func() { + if err != nil { + rbdSnap.ReservedID = origReservedID + rbdSnap.RbdSnapName = origRbdSnapName + rbdSnap.VolID = origVolID + } + }() + journalPoolID, imagePoolID, err := util.GetPoolIDs(ctx, rbdSnap.Monitors, rbdSnap.JournalPool, rbdSnap.Pool, cr) if err != nil { return err @@ -405,6 +417,17 @@ func reserveSnap(ctx context.Context, rbdSnap *rbdSnapshot, rbdVol *rbdVolume, c ctx, rbdSnap.JournalPool, journalPoolID, rbdSnap.Pool, imagePoolID, rbdSnap.RequestName, rbdSnap.NamePrefix, rbdVol.RbdImageName, kmsID, rbdSnap.ReservedID, rbdVol.Owner, "", encryptionType) + defer func() { + // only undo the reservation when an error occurred + if err == nil { + return + } + + undoErr := undoSnapReservation(ctx, rbdSnap, cr) + if undoErr != nil { + log.WarningLog(ctx, "failed undoing reservation of snapshot %q: %v", rbdSnap, undoErr) + } + }() if err != nil { return err }