From 7690e43bed12296e4520bb686d01d1e925915698 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Thu, 12 Aug 2021 12:58:13 +0530 Subject: [PATCH] rbd: Cleanup OMAP data for secondary image If the image is in a secondary state and its up+replaying means its an healthy secondary and the image is primary somewhere in the remote cluster and the local image is getting replayed. Delete the OMAP data generated as we cannot delete the secondary image. When the image on the primary cluster gets deleted/mirroring disabled, the image on all the remote (secondary) clusters will get auto-deleted. This helps in garbage collecting the OMAP, PVC and PV objects after failback operation. Signed-off-by: Madhu Rajanna (cherry picked from commit 5562e46d0f5ca1bb7cab492bb77f05873698bb80) --- internal/rbd/controllerserver.go | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index ce7b51770..ee0e1d871 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -831,6 +831,51 @@ func (cs *ControllerServer) DeleteVolume( } defer cs.VolumeLocks.Release(rbdVol.RequestName) + return cleanupRBDImage(ctx, rbdVol, cr) +} + +// cleanupRBDImage removes the rbd image and OMAP metadata associated with it. +func cleanupRBDImage(ctx context.Context, + rbdVol *rbdVolume, cr *util.Credentials) (*csi.DeleteVolumeResponse, error) { + mirroringInfo, err := rbdVol.getImageMirroringInfo() + if err != nil { + util.ErrorLog(ctx, err.Error()) + + return nil, status.Error(codes.Internal, err.Error()) + } + // Cleanup only omap data if the following condition is met + // Mirroring is enabled on the image + // Local image is secondary + // Local image is in up+replaying state + if mirroringInfo.State == librbd.MirrorImageEnabled && !mirroringInfo.Primary { + // If the image is in a secondary state and its up+replaying means its + // an healthy secondary and the image is primary somewhere in the + // remote cluster and the local image is getting replayed. Delete the + // OMAP data generated as we cannot delete the secondary image. When + // the image on the primary cluster gets deleted/mirroring disabled, + // the image on all the remote (secondary) clusters will get + // auto-deleted. This helps in garbage collecting the OMAP, PVC and PV + // objects after failback operation. + localStatus, rErr := rbdVol.getLocalState() + if rErr != nil { + return nil, status.Error(codes.Internal, rErr.Error()) + } + if localStatus.Up && localStatus.State == librbd.MirrorImageStatusStateReplaying { + if err = undoVolReservation(ctx, rbdVol, cr); err != nil { + util.ErrorLog(ctx, "failed to remove reservation for volume (%s) with backing image (%s) (%s)", + rbdVol.RequestName, rbdVol.RbdImageName, err) + + return nil, status.Error(codes.Internal, err.Error()) + } + + return &csi.DeleteVolumeResponse{}, nil + } + util.ErrorLog(ctx, + "secondary image status is up=%t and state=%s", + localStatus.Up, + localStatus.State) + } + inUse, err := rbdVol.isInUse() if err != nil { util.ErrorLog(ctx, "failed getting information for image (%s): (%s)", rbdVol, err)