diff --git a/internal/rbd/clone.go b/internal/rbd/clone.go index 648d85621..5a14c417d 100644 --- a/internal/rbd/clone.go +++ b/internal/rbd/clone.go @@ -34,13 +34,11 @@ import ( // checkCloneImage check the cloned image exists, if the cloned image is not // found it will check the temporary cloned snapshot exists, and again it will // check the snapshot exists on the temporary cloned image, if yes it will -// create a new cloned and delete the temporary snapshot and adds a task to -// flatten the temp cloned image and return success. +// create a new cloned and adds a task to flatten the temp cloned image and return success. // // if the temporary snapshot does not exists it creates a temporary snapshot on // temporary cloned image and creates a new cloned with user-provided image -// features and delete the temporary snapshot and adds a task to flatten the -// temp cloned image and return success +// features and adds a task to flatten the temp cloned image and return success // // if the temporary clone does not exist and if there is a temporary snapshot // present on the parent image it will delete the temporary snapshot and @@ -59,9 +57,9 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume) if err != nil { switch { case errors.Is(err, ErrSnapNotFound): - // as the snapshot is not present, create new snapshot,clone and - // delete the temporary snapshot - err = createRBDClone(ctx, tempClone, rv, snap) + // as the snapshot is not present, create new snapshot, clone and + // don't delete the temporary snapshot + err = createRBDClone(ctx, tempClone, rv, snap, false) if err != nil { return false, err } @@ -100,12 +98,6 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume) return false, err } - err = tempClone.deleteSnapshot(ctx, snap) - if err != nil { - log.ErrorLog(ctx, "failed to delete snapshot: %v", err) - - return false, err - } return true, nil } @@ -207,7 +199,7 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro cloneSnap.Pool = rv.Pool // create snapshot and temporary clone and delete snapshot - err := createRBDClone(ctx, parentVol, tempClone, tempSnap) + err := createRBDClone(ctx, parentVol, tempClone, tempSnap, true) if err != nil { return err } @@ -238,8 +230,8 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro // create snap of temp clone from temporary cloned image // create final clone - // delete snap of temp clone - errClone = createRBDClone(ctx, tempClone, rv, cloneSnap) + // don't delete snap of temp clone (needed for mirroring of PVC-PVC clone). + errClone = createRBDClone(ctx, tempClone, rv, cloneSnap, false) if errClone != nil { return errClone } diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 15f49a145..9c454614e 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -1388,7 +1388,8 @@ func (cs *ControllerServer) doSnapshotClone( return cloneRbd, err } - err = createRBDClone(ctx, parentVol, cloneRbd, rbdSnap) + // create snapshot, clone and delete snapshot + err = createRBDClone(ctx, parentVol, cloneRbd, rbdSnap, true) if err != nil { log.ErrorLog(ctx, "failed to create snapshot: %v", err) diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index f01ee79e2..50baa57b4 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -750,7 +750,21 @@ func (ri *rbdImage) trashRemoveImage(ctx context.Context) error { // DeleteTempImage deletes the temporary image created for volume datasource. func (rv *rbdVolume) DeleteTempImage(ctx context.Context) error { tempClone := rv.generateTempClone() - err := tempClone.Delete(ctx) + snap := &rbdSnapshot{} + defer snap.Destroy(ctx) + + snap.RbdImageName = tempClone.RbdImageName + snap.RbdSnapName = rv.RbdImageName + snap.Pool = rv.Pool + snap.RadosNamespace = rv.RadosNamespace + err := tempClone.deleteSnapshot(ctx, snap) + if err != nil { + if !errors.Is(err, util.ErrImageNotFound) && !errors.Is(err, ErrSnapNotFound) { + return fmt.Errorf("failed to delete snapshot %q: %w", snap, err) + } + } + + err = tempClone.Delete(ctx) if err != nil { if errors.Is(err, util.ErrImageNotFound) { return tempClone.ensureImageCleanup(ctx) diff --git a/internal/rbd/snapshot.go b/internal/rbd/snapshot.go index e35a68ecb..6493341b3 100644 --- a/internal/rbd/snapshot.go +++ b/internal/rbd/snapshot.go @@ -29,10 +29,14 @@ import ( "github.com/ceph/ceph-csi/internal/util/log" ) +// createRBDClone creates a clone of the parentVol by creating a +// snapshot of the parentVol and cloning the snapshot to the cloneRbdVol. +// If deleteSnap is true, the snapshot is deleted after the clone is created. func createRBDClone( ctx context.Context, parentVol, cloneRbdVol *rbdVolume, snap *rbdSnapshot, + deleteSnap bool, ) error { // create snapshot err := parentVol.createSnapshot(ctx, snap) @@ -58,6 +62,10 @@ func createRBDClone( snap.RbdSnapName, err) } + if !deleteSnap { + return nil + } + errSnap := parentVol.deleteSnapshot(ctx, snap) if errSnap != nil { log.ErrorLog(ctx, "failed to delete snapshot: %v", errSnap)