mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 02:33:34 +00:00
cleanup: resolve nlreturn linter issues
nlreturn linter requires a new line before return and branch statements except when the return is alone inside a statement group (such as an if statement) to increase code clarity. This commit addresses such issues. Updates: #1586 Signed-off-by: Rakshith R <rar@redhat.com>
This commit is contained in:
@ -61,12 +61,14 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
|
||||
if errors.Is(err, ErrSnapNotFound) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
err = tempClone.deleteSnapshot(ctx, snap)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
@ -90,6 +92,7 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
case !errors.Is(err, ErrImageNotFound):
|
||||
// any error other than image not found return error
|
||||
@ -104,13 +107,16 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to clone rbd image %s from snapshot %s: %v", rv.RbdImageName, snap.RbdSnapName, err)
|
||||
err = fmt.Errorf("failed to clone rbd image %s from snapshot %s: %w", rv.RbdImageName, snap.RbdSnapName, err)
|
||||
|
||||
return false, err
|
||||
}
|
||||
err = tempClone.deleteSnapshot(ctx, snap)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to delete snapshot: %v", err)
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
// as the temp clone does not exist,check snapshot exists on parent volume
|
||||
@ -125,6 +131,7 @@ func (rv *rbdVolume) checkCloneImage(ctx context.Context, parentVol *rbdVolume)
|
||||
if errors.Is(err, ErrSnapNotFound) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -142,6 +149,7 @@ func (rv *rbdVolume) generateTempClone() *rbdVolume {
|
||||
// this name will be always unique, as cephcsi never creates an image with
|
||||
// this format for new rbd images
|
||||
tempClone.RbdImageName = rv.RbdImageName + "-temp"
|
||||
|
||||
return &tempClone
|
||||
}
|
||||
|
||||
@ -160,6 +168,7 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
|
||||
err = rv.getImageID()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get volume id %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -180,8 +189,10 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
|
||||
err = j.StoreImageID(ctx, rv.JournalPool, rv.ReservedID, rv.ImageID)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to store volume %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -248,6 +259,7 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro
|
||||
if errClone != nil {
|
||||
// set errFlatten error to cleanup temporary snapshot and temporary clone
|
||||
errFlatten = errors.New("failed to create user requested cloned image")
|
||||
|
||||
return errClone
|
||||
}
|
||||
}
|
||||
@ -285,5 +297,6 @@ func (rv *rbdVolume) flattenCloneImage(ctx context.Context) error {
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
return rv.flattenRbdImage(ctx, rv.conn.Creds, false, hardLimit, softLimit)
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ func (cs *ControllerServer) validateVolumeReq(ctx context.Context, req *csi.Crea
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(
|
||||
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil {
|
||||
util.ErrorLog(ctx, "invalid create volume req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return err
|
||||
}
|
||||
// Check sanity of request Name, Volume Capabilities
|
||||
@ -175,6 +176,7 @@ func buildCreateVolumeResponse(req *csi.CreateVolumeRequest, rbdVol *rbdVolume)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return &csi.CreateVolumeResponse{Volume: volume}
|
||||
}
|
||||
|
||||
@ -188,6 +190,7 @@ func getGRPCErrorForCreateVolume(err error) error {
|
||||
if errors.Is(err, ErrFlattenInProgress) {
|
||||
return status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -223,6 +226,7 @@ func validateRequestedVolumeSize(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSnaps
|
||||
parentVol.VolSize)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -254,6 +258,7 @@ func checkValidCreateVolumeRequest(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSna
|
||||
return status.Errorf(codes.InvalidArgument, "cannot clone from volume %s: %s", parentVol, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -281,6 +286,7 @@ func (cs *ControllerServer) CreateVolume(
|
||||
// Existence and conflict checks
|
||||
if acquired := cs.VolumeLocks.TryAcquire(req.GetName()); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, req.GetName())
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, req.GetName())
|
||||
}
|
||||
defer cs.VolumeLocks.Release(req.GetName())
|
||||
@ -288,6 +294,7 @@ func (cs *ControllerServer) CreateVolume(
|
||||
err = rbdVol.Connect(cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to connect to volume %v: %v", rbdVol.RbdImageName, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -333,6 +340,7 @@ func (cs *ControllerServer) CreateVolume(
|
||||
if errors.Is(err, ErrFlattenInProgress) {
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -356,6 +364,7 @@ func flattenParentImage(ctx context.Context, rbdVol *rbdVolume, cr *util.Credent
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -402,6 +411,7 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Aborted, "failed to remove volume %q from journal: %s", rbdVol, err)
|
||||
}
|
||||
|
||||
return nil, status.Errorf(
|
||||
codes.Aborted,
|
||||
"restoring thick-provisioned volume %q has been interrupted, please retry", rbdVol)
|
||||
@ -443,6 +453,7 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "failed to remove volume %q from journal: %s", rbdVol, err)
|
||||
}
|
||||
|
||||
return nil, status.Errorf(
|
||||
codes.Internal,
|
||||
"cloning thick-provisioned volume %q has been interrupted, please retry", rbdVol)
|
||||
@ -470,6 +481,7 @@ func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *ut
|
||||
if errors.Is(err, ErrImageNotFound) {
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -490,6 +502,7 @@ func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *ut
|
||||
if err != nil {
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return status.Errorf(codes.ResourceExhausted, "rbd image %s has %d snapshots", rbdVol, len(snaps))
|
||||
}
|
||||
|
||||
@ -515,6 +528,7 @@ func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *ut
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -530,14 +544,17 @@ func checkFlatten(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials)
|
||||
}
|
||||
if errDefer := deleteImage(ctx, rbdVol, cr); errDefer != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s with error: %v", rbdVol, errDefer)
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
errDefer := undoVolReservation(ctx, rbdVol, cr)
|
||||
if errDefer != nil {
|
||||
util.WarningLog(ctx, "failed undoing reservation of volume: %s (%s)", rbdVol.RequestName, errDefer)
|
||||
}
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -550,6 +567,7 @@ func (cs *ControllerServer) createVolumeFromSnapshot(
|
||||
rbdSnap := &rbdSnapshot{}
|
||||
if acquired := cs.SnapshotLocks.TryAcquire(snapshotID); !acquired {
|
||||
util.ErrorLog(ctx, util.SnapshotOperationAlreadyExistsFmt, snapshotID)
|
||||
|
||||
return status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, snapshotID)
|
||||
}
|
||||
defer cs.SnapshotLocks.Release(snapshotID)
|
||||
@ -558,8 +576,10 @@ func (cs *ControllerServer) createVolumeFromSnapshot(
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrPoolNotFound) {
|
||||
util.ErrorLog(ctx, "failed to get backend snapshot for %s: %v", snapshotID, err)
|
||||
|
||||
return status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -583,11 +603,13 @@ func (cs *ControllerServer) createVolumeFromSnapshot(
|
||||
err = rbdVol.cloneRbdImageFromSnapshot(ctx, rbdSnap, parentVol)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to clone rbd image %s from snapshot %s: %v", rbdVol, rbdSnap, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
util.DebugLog(ctx, "create volume %s from snapshot %s", rbdVol.RequestName, rbdSnap.RbdSnapName)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -609,6 +631,7 @@ func (cs *ControllerServer) createBackingImage(
|
||||
case rbdSnap != nil:
|
||||
if err = cs.OperationLocks.GetRestoreLock(rbdSnap.VolID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseRestoreLock(rbdSnap.VolID)
|
||||
@ -621,14 +644,17 @@ func (cs *ControllerServer) createBackingImage(
|
||||
case parentVol != nil:
|
||||
if err = cs.OperationLocks.GetCloneLock(parentVol.VolID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseCloneLock(parentVol.VolID)
|
||||
|
||||
return rbdVol.createCloneFromImage(ctx, parentVol)
|
||||
default:
|
||||
err = createImage(ctx, rbdVol, cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to create volume: %v", err)
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -653,9 +679,11 @@ func (cs *ControllerServer) createBackingImage(
|
||||
err = rbdVol.flattenRbdImage(ctx, cr, false, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to flatten image %s: %v", rbdVol, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -683,8 +711,10 @@ func checkContentSource(
|
||||
if !errors.Is(err, ErrSnapNotFound) {
|
||||
return nil, nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, nil, status.Errorf(codes.NotFound, "%s snapshot does not exist", snapshotID)
|
||||
}
|
||||
|
||||
return nil, rbdSnap, nil
|
||||
case *csi.VolumeContentSource_Volume:
|
||||
vol := req.VolumeContentSource.GetVolume()
|
||||
@ -701,10 +731,13 @@ func checkContentSource(
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
return nil, nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, nil, status.Errorf(codes.NotFound, "%s image does not exist", volID)
|
||||
}
|
||||
|
||||
return rbdvol, nil, nil
|
||||
}
|
||||
|
||||
return nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source")
|
||||
}
|
||||
|
||||
@ -717,6 +750,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(
|
||||
csi.ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME); err != nil {
|
||||
util.ErrorLog(ctx, "invalid delete volume req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -734,6 +768,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
|
||||
if acquired := cs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer cs.VolumeLocks.Release(volumeID)
|
||||
@ -741,6 +776,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
// lock out volumeID for clone and expand operation
|
||||
if err = cs.OperationLocks.GetDeleteLock(volumeID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseDeleteLock(volumeID)
|
||||
@ -750,6 +786,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
if err != nil {
|
||||
if errors.Is(err, util.ErrPoolNotFound) {
|
||||
util.WarningLog(ctx, "failed to get backend volume for %s: %v", volumeID, err)
|
||||
|
||||
return &csi.DeleteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -758,6 +795,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
// success as deletion is complete
|
||||
if errors.Is(err, util.ErrKeyNotFound) {
|
||||
util.WarningLog(ctx, "Failed to volume options for %s: %v", volumeID, err)
|
||||
|
||||
return &csi.DeleteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -771,6 +809,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
// unreserve for the same
|
||||
if acquired := cs.VolumeLocks.TryAcquire(rbdVol.RequestName); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
|
||||
}
|
||||
defer cs.VolumeLocks.Release(rbdVol.RequestName)
|
||||
@ -778,6 +817,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
if err = undoVolReservation(ctx, rbdVol, cr); err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &csi.DeleteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -785,6 +825,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
// cleanup the image and associated omaps for the same
|
||||
if acquired := cs.VolumeLocks.TryAcquire(rbdVol.RequestName); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, rbdVol.RequestName)
|
||||
}
|
||||
defer cs.VolumeLocks.Release(rbdVol.RequestName)
|
||||
@ -792,10 +833,12 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
inUse, err := rbdVol.isInUse()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting information for image (%s): (%s)", rbdVol, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
if inUse {
|
||||
util.ErrorLog(ctx, "rbd %s is still being used", rbdVol)
|
||||
|
||||
return nil, status.Errorf(codes.Internal, "rbd %s is still being used", rbdVol.RbdImageName)
|
||||
}
|
||||
|
||||
@ -808,6 +851,7 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s with error: %v",
|
||||
tempClone, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -817,12 +861,14 @@ func (cs *ControllerServer) DeleteVolume(
|
||||
if err = deleteImage(ctx, rbdVol, cr); err != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s with error: %v",
|
||||
rbdVol, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
@ -847,6 +893,7 @@ func (cs *ControllerServer) ValidateVolumeCapabilities(
|
||||
return &csi.ValidateVolumeCapabilitiesResponse{Message: ""}, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &csi.ValidateVolumeCapabilitiesResponse{
|
||||
Confirmed: &csi.ValidateVolumeCapabilitiesResponse_Confirmed{
|
||||
VolumeCapabilities: req.VolumeCapabilities,
|
||||
@ -881,6 +928,7 @@ func (cs *ControllerServer) CreateSnapshot(
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -903,6 +951,7 @@ func (cs *ControllerServer) CreateSnapshot(
|
||||
|
||||
if acquired := cs.SnapshotLocks.TryAcquire(req.GetName()); !acquired {
|
||||
util.ErrorLog(ctx, util.SnapshotOperationAlreadyExistsFmt, req.GetName())
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, req.GetName())
|
||||
}
|
||||
defer cs.SnapshotLocks.Release(req.GetName())
|
||||
@ -910,6 +959,7 @@ func (cs *ControllerServer) CreateSnapshot(
|
||||
// Take lock on parent rbd image
|
||||
if err = cs.OperationLocks.GetSnapshotCreateLock(rbdSnap.SourceVolumeID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseSnapshotCreateLock(rbdSnap.SourceVolumeID)
|
||||
@ -921,6 +971,7 @@ func (cs *ControllerServer) CreateSnapshot(
|
||||
if errors.Is(err, util.ErrSnapNameConflict) {
|
||||
return nil, status.Error(codes.AlreadyExists, err.Error())
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
if found {
|
||||
@ -977,6 +1028,7 @@ func cloneFromSnapshot(
|
||||
if uErr != nil {
|
||||
util.WarningLog(ctx, "failed undoing reservation of snapshot: %s %v", rbdSnap.RequestName, uErr)
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
defer vol.Destroy()
|
||||
@ -1025,6 +1077,7 @@ func cloneFromSnapshot(
|
||||
if uErr != nil {
|
||||
util.WarningLog(ctx, "failed undoing reservation of snapshot: %s %v", rbdSnap.RequestName, uErr)
|
||||
}
|
||||
|
||||
return nil, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -1043,6 +1096,7 @@ func (cs *ControllerServer) validateSnapshotReq(ctx context.Context, req *csi.Cr
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(
|
||||
csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT); err != nil {
|
||||
util.ErrorLog(ctx, "invalid create snapshot req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1061,6 +1115,7 @@ func (cs *ControllerServer) validateSnapshotReq(ctx context.Context, req *csi.Cr
|
||||
if value, ok := options["pool"]; ok && value == "" {
|
||||
return status.Error(codes.InvalidArgument, "empty pool name in which rbd image will be created")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1085,6 +1140,7 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
err = createRBDClone(ctx, parentVol, cloneRbd, rbdSnap, cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to create snapshot: %v", err)
|
||||
|
||||
return ready, cloneRbd, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -1105,6 +1161,7 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
if cryptErr != nil {
|
||||
util.WarningLog(ctx, "failed copy encryption "+
|
||||
"config for %q: %v", cloneRbd, cryptErr)
|
||||
|
||||
return ready, nil, status.Errorf(codes.Internal,
|
||||
err.Error())
|
||||
}
|
||||
@ -1131,6 +1188,7 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
// update rbd image name for logging
|
||||
rbdSnap.RbdImageName = cloneRbd.RbdImageName
|
||||
util.ErrorLog(ctx, "failed to create snapshot %s: %v", rbdSnap, err)
|
||||
|
||||
return ready, cloneRbd, err
|
||||
}
|
||||
}
|
||||
@ -1138,12 +1196,14 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
err = cloneRbd.getImageID()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get image id: %v", err)
|
||||
|
||||
return ready, cloneRbd, err
|
||||
}
|
||||
// save image ID
|
||||
j, err := snapJournal.Connect(rbdSnap.Monitors, rbdSnap.RadosNamespace, cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to connect to cluster: %v", err)
|
||||
|
||||
return ready, cloneRbd, err
|
||||
}
|
||||
defer j.Destroy()
|
||||
@ -1151,6 +1211,7 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
err = j.StoreImageID(ctx, rbdSnap.JournalPool, rbdSnap.ReservedID, cloneRbd.ImageID)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to reserve volume id: %v", err)
|
||||
|
||||
return ready, cloneRbd, err
|
||||
}
|
||||
|
||||
@ -1159,9 +1220,11 @@ func (cs *ControllerServer) doSnapshotClone(
|
||||
if errors.Is(err, ErrFlattenInProgress) {
|
||||
return ready, cloneRbd, nil
|
||||
}
|
||||
|
||||
return ready, cloneRbd, err
|
||||
}
|
||||
ready = true
|
||||
|
||||
return ready, cloneRbd, nil
|
||||
}
|
||||
|
||||
@ -1173,6 +1236,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(
|
||||
csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT); err != nil {
|
||||
util.ErrorLog(ctx, "invalid delete snapshot req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1189,6 +1253,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
|
||||
if acquired := cs.SnapshotLocks.TryAcquire(snapshotID); !acquired {
|
||||
util.ErrorLog(ctx, util.SnapshotOperationAlreadyExistsFmt, snapshotID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, snapshotID)
|
||||
}
|
||||
defer cs.SnapshotLocks.Release(snapshotID)
|
||||
@ -1196,6 +1261,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
// lock out snapshotID for restore operation
|
||||
if err = cs.OperationLocks.GetDeleteLock(snapshotID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseDeleteLock(snapshotID)
|
||||
@ -1206,6 +1272,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
// need to worry about deleting snapshot or omap data, return success
|
||||
if errors.Is(err, util.ErrPoolNotFound) {
|
||||
util.WarningLog(ctx, "failed to get backend snapshot for %s: %v", snapshotID, err)
|
||||
|
||||
return &csi.DeleteSnapshotResponse{}, nil
|
||||
}
|
||||
|
||||
@ -1223,6 +1290,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
// name
|
||||
if acquired := cs.SnapshotLocks.TryAcquire(rbdSnap.RequestName); !acquired {
|
||||
util.ErrorLog(ctx, util.SnapshotOperationAlreadyExistsFmt, rbdSnap.RequestName)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, rbdSnap.RequestName)
|
||||
}
|
||||
defer cs.SnapshotLocks.Release(rbdSnap.RequestName)
|
||||
@ -1242,6 +1310,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s/%s with error: %v", rbdVol.Pool, rbdVol.VolName, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
} else {
|
||||
@ -1251,6 +1320,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
err = cleanUpSnapshot(ctx, rbdVol, rbdSnap, rbdVol, cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to delete image: %v", err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -1258,6 +1328,7 @@ func (cs *ControllerServer) DeleteSnapshot(
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to remove reservation for snapname (%s) with backing snap (%s) on image (%s) (%s)",
|
||||
rbdSnap.RequestName, rbdSnap.RbdSnapName, rbdSnap.RbdImageName, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -1270,6 +1341,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
||||
req *csi.ControllerExpandVolumeRequest) (*csi.ControllerExpandVolumeResponse, error) {
|
||||
if err := cs.Driver.ValidateControllerServiceRequest(csi.ControllerServiceCapability_RPC_EXPAND_VOLUME); err != nil {
|
||||
util.ErrorLog(ctx, "invalid expand volume req: %v", protosanitizer.StripSecrets(req))
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1292,6 +1364,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
||||
// lock out parallel requests against the same volume ID
|
||||
if acquired := cs.VolumeLocks.TryAcquire(volID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
}
|
||||
defer cs.VolumeLocks.Release(volID)
|
||||
@ -1299,6 +1372,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
||||
// lock out volumeID for clone and delete operation
|
||||
if err := cs.OperationLocks.GetExpandLock(volID); err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
defer cs.OperationLocks.ReleaseExpandLock(volID)
|
||||
@ -1321,6 +1395,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1338,6 +1413,7 @@ func (cs *ControllerServer) ControllerExpandVolume(
|
||||
err = rbdVol.resize(volSize)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to resize rbd image: %s with error: %v", rbdVol, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ func NewReplicationServer(c *ControllerServer) *ReplicationServer {
|
||||
// NewNodeServer initialize a node server for rbd CSI driver.
|
||||
func NewNodeServer(d *csicommon.CSIDriver, t string, topology map[string]string) (*NodeServer, error) {
|
||||
mounter := mount.New("")
|
||||
|
||||
return &NodeServer{
|
||||
DefaultNodeServer: csicommon.NewDefaultNodeServer(d, t, topology),
|
||||
mounter: mounter,
|
||||
|
@ -65,14 +65,17 @@ func (ri *rbdImage) checkRbdImageEncrypted(ctx context.Context) (rbdEncryptionSt
|
||||
value, err := ri.GetMetadata(encryptionMetaKey)
|
||||
if errors.Is(err, librbd.ErrNotFound) {
|
||||
util.DebugLog(ctx, "image %s encrypted state not set", ri)
|
||||
|
||||
return rbdImageEncryptionUnknown, nil
|
||||
} else if err != nil {
|
||||
util.ErrorLog(ctx, "checking image %s encrypted state metadata failed: %s", ri, err)
|
||||
|
||||
return rbdImageEncryptionUnknown, err
|
||||
}
|
||||
|
||||
encrypted := rbdEncryptionState(strings.TrimSpace(value))
|
||||
util.DebugLog(ctx, "image %s encrypted state metadata reports %q", ri, encrypted)
|
||||
|
||||
return encrypted, nil
|
||||
}
|
||||
|
||||
@ -98,6 +101,7 @@ func (ri *rbdImage) setupEncryption(ctx context.Context) error {
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to save encryption passphrase for "+
|
||||
"image %s: %s", ri, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -105,6 +109,7 @@ func (ri *rbdImage) setupEncryption(ctx context.Context) error {
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to save encryption status, deleting "+
|
||||
"image %s: %s", ri, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -181,18 +186,21 @@ func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v",
|
||||
ri, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if err = util.EncryptVolume(ctx, devicePath, passphrase); err != nil {
|
||||
err = fmt.Errorf("failed to encrypt volume %s: %w", ri, err)
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
err = ri.ensureEncryptionMetadataSet(rbdImageEncrypted)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -204,6 +212,7 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v",
|
||||
rv, err)
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -212,6 +221,7 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string)
|
||||
isOpen, err := util.IsDeviceOpen(ctx, mapperFilePath)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to check device %s encryption status: %s", devicePath, err)
|
||||
|
||||
return devicePath, err
|
||||
}
|
||||
if isOpen {
|
||||
@ -221,6 +231,7 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to open device %s: %v",
|
||||
rv, err)
|
||||
|
||||
return devicePath, err
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ func (ri *rbdImage) enableImageMirroring(mode librbd.ImageMirrorMode) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to enable mirroring on %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -53,6 +54,7 @@ func (ri *rbdImage) disableImageMirroring(force bool) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to disable mirroring on %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -68,6 +70,7 @@ func (ri *rbdImage) getImageMirroringInfo() (*librbd.MirrorImageInfo, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get mirroring info of %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@ -82,6 +85,7 @@ func (ri *rbdImage) promoteImage(force bool) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to promote image %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -96,6 +100,7 @@ func (ri *rbdImage) demoteImage() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to demote image %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -110,6 +115,7 @@ func (ri *rbdImage) resyncImage() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resync image %q with error: %w", ri, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -148,6 +154,7 @@ func (ri *rbdImage) getImageMirroringStatus() (*imageMirrorStatus, error) {
|
||||
": (2) No such file or directory") {
|
||||
return nil, util.JoinErrors(ErrImageNotFound, err)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -157,5 +164,6 @@ func (ri *rbdImage) getImageMirroringStatus() (*imageMirrorStatus, error) {
|
||||
return nil, fmt.Errorf("unmarshal failed (%w), raw buffer response: %s", err, stdout)
|
||||
}
|
||||
}
|
||||
|
||||
return &imgStatus, nil
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ func isHealerContext(parameters map[string]string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return healerContext
|
||||
}
|
||||
|
||||
@ -121,6 +122,7 @@ func isStaticVolume(parameters map[string]string) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return staticVol
|
||||
}
|
||||
|
||||
@ -130,6 +132,7 @@ func healerStageTransaction(ctx context.Context, cr *util.Credentials, volOps *r
|
||||
imgInfo, err := lookupRBDImageMetadataStash(metaDataPath)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to find image metadata, at stagingPath: %s, err: %v", metaDataPath, err)
|
||||
|
||||
return err
|
||||
}
|
||||
if imgInfo.DevicePath == "" {
|
||||
@ -141,6 +144,7 @@ func healerStageTransaction(ctx context.Context, cr *util.Credentials, volOps *r
|
||||
return err
|
||||
}
|
||||
util.DebugLog(ctx, "rbd volID: %s was successfully attached to device: %s", volOps.VolID, devicePath)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -177,6 +181,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
"invalid AccessMode for volume: %v",
|
||||
req.GetVolumeId(),
|
||||
)
|
||||
|
||||
return nil, status.Error(
|
||||
codes.InvalidArgument,
|
||||
"rbd: RWX access mode request is only valid for volumes with access type `block`",
|
||||
@ -196,6 +201,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
|
||||
if acquired := ns.VolumeLocks.TryAcquire(volID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
}
|
||||
defer ns.VolumeLocks.Release(volID)
|
||||
@ -212,6 +218,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
} else if !isNotMnt {
|
||||
util.DebugLog(ctx, "rbd: volume %s is already mounted to %s, skipping", volID, stagingTargetPath)
|
||||
|
||||
return &csi.NodeStageVolumeResponse{}, nil
|
||||
}
|
||||
}
|
||||
@ -241,12 +248,14 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
err = vi.DecomposeCSIID(volID)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error decoding volume ID (%s): %w", volID, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
j, connErr := volJournal.Connect(volOptions.Monitors, volOptions.RadosNamespace, cr)
|
||||
if connErr != nil {
|
||||
util.ErrorLog(ctx, "failed to establish cluster connection: %v", connErr)
|
||||
|
||||
return nil, status.Error(codes.Internal, connErr.Error())
|
||||
}
|
||||
defer j.Destroy()
|
||||
@ -255,6 +264,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
ctx, volOptions.Pool, vi.ObjectUUID, false)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error fetching image attributes for volume ID (%s): %w", volID, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
volOptions.RbdImageName = imageAttributes.ImageName
|
||||
@ -268,6 +278,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
err = volOptions.Connect(cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to connect to volume %s: %v", volOptions, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
defer volOptions.Destroy()
|
||||
@ -277,6 +288,7 @@ func (ns *NodeServer) NodeStageVolume(
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &csi.NodeStageVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -409,6 +421,7 @@ func (ns *NodeServer) stageTransaction(
|
||||
// #nosec - allow anyone to write inside the target path
|
||||
err = os.Chmod(stagingTargetPath, 0o777)
|
||||
}
|
||||
|
||||
return transaction, err
|
||||
}
|
||||
|
||||
@ -424,6 +437,7 @@ func (ns *NodeServer) undoStagingTransaction(
|
||||
err = ns.mounter.Unmount(stagingTargetPath)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to unmount stagingtargetPath: %s with error: %v", stagingTargetPath, err)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -458,6 +472,7 @@ func (ns *NodeServer) undoStagingTransaction(
|
||||
// Cleanup the stashed image metadata
|
||||
if err = cleanupRBDImageMetadataStash(req.GetStagingTargetPath()); err != nil {
|
||||
util.ErrorLog(ctx, "failed to cleanup image metadata stash (%v)", err)
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -468,10 +483,12 @@ func (ns *NodeServer) createStageMountPoint(ctx context.Context, mountPath strin
|
||||
pathFile, err := os.OpenFile(mountPath, os.O_CREATE|os.O_RDWR, 0o600)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to create mountPath:%s with error: %v", mountPath, err)
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
if err = pathFile.Close(); err != nil {
|
||||
util.ErrorLog(ctx, "failed to close mountPath:%s with error: %v", mountPath, err)
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -482,6 +499,7 @@ func (ns *NodeServer) createStageMountPoint(ctx context.Context, mountPath strin
|
||||
if err != nil {
|
||||
if !os.IsExist(err) {
|
||||
util.ErrorLog(ctx, "failed to create mountPath:%s with error: %v", mountPath, err)
|
||||
|
||||
return status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -524,6 +542,7 @@ func (ns *NodeServer) NodePublishVolume(
|
||||
}
|
||||
|
||||
util.DebugLog(ctx, "rbd: successfully mounted stagingPath %s to targetPath %s", stagingPath, targetPath)
|
||||
|
||||
return &csi.NodePublishVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -548,6 +567,7 @@ func (ns *NodeServer) mountVolumeToStagePath(
|
||||
existingFormat, err := diskMounter.GetDiskFormat(devicePath)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get disk format for path %s, error: %v", devicePath, err)
|
||||
|
||||
return readOnly, err
|
||||
}
|
||||
|
||||
@ -587,6 +607,7 @@ func (ns *NodeServer) mountVolumeToStagePath(
|
||||
cmdOut, cmdErr := diskMounter.Exec.Command("mkfs."+fsType, args...).CombinedOutput()
|
||||
if cmdErr != nil {
|
||||
util.ErrorLog(ctx, "failed to run mkfs error: %v, output: %v", cmdErr, string(cmdOut))
|
||||
|
||||
return readOnly, cmdErr
|
||||
}
|
||||
}
|
||||
@ -607,6 +628,7 @@ func (ns *NodeServer) mountVolumeToStagePath(
|
||||
req.GetVolumeId(),
|
||||
err)
|
||||
}
|
||||
|
||||
return readOnly, err
|
||||
}
|
||||
|
||||
@ -647,10 +669,12 @@ func (ns *NodeServer) createTargetMountPath(ctx context.Context, mountPath strin
|
||||
pathFile, e := os.OpenFile(mountPath, os.O_CREATE|os.O_RDWR, 0o750)
|
||||
if e != nil {
|
||||
util.DebugLog(ctx, "Failed to create mountPath:%s with error: %v", mountPath, err)
|
||||
|
||||
return notMnt, status.Error(codes.Internal, e.Error())
|
||||
}
|
||||
if err = pathFile.Close(); err != nil {
|
||||
util.DebugLog(ctx, "Failed to close mountPath:%s with error: %v", mountPath, err)
|
||||
|
||||
return notMnt, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
} else {
|
||||
@ -660,6 +684,7 @@ func (ns *NodeServer) createTargetMountPath(ctx context.Context, mountPath strin
|
||||
}
|
||||
}
|
||||
notMnt = true
|
||||
|
||||
return notMnt, err
|
||||
}
|
||||
|
||||
@ -680,14 +705,17 @@ func (ns *NodeServer) NodeUnpublishVolume(
|
||||
if os.IsNotExist(err) {
|
||||
// targetPath has already been deleted
|
||||
util.DebugLog(ctx, "targetPath: %s has already been deleted", targetPath)
|
||||
|
||||
return &csi.NodeUnpublishVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
return nil, status.Error(codes.NotFound, err.Error())
|
||||
}
|
||||
if notMnt {
|
||||
if err = os.RemoveAll(targetPath); err != nil {
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return &csi.NodeUnpublishVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -730,6 +758,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
|
||||
if acquired := ns.VolumeLocks.TryAcquire(volID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volID)
|
||||
}
|
||||
defer ns.VolumeLocks.Release(volID)
|
||||
@ -750,6 +779,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
err = ns.mounter.Unmount(stagingTargetPath)
|
||||
if err != nil {
|
||||
util.ExtendedLog(ctx, "failed to unmount targetPath: %s with error: %v", stagingTargetPath, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
util.DebugLog(ctx, "successfully unmounted volume (%s) from staging path (%s)",
|
||||
@ -762,6 +792,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
// error
|
||||
if !os.IsNotExist(err) {
|
||||
util.ErrorLog(ctx, "failed to remove staging target path (%s): (%v)", stagingTargetPath, err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -800,6 +831,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
req.GetVolumeId(),
|
||||
stagingTargetPath,
|
||||
err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -807,6 +839,7 @@ func (ns *NodeServer) NodeUnstageVolume(
|
||||
|
||||
if err = cleanupRBDImageMetadataStash(stagingParentPath); err != nil {
|
||||
util.ErrorLog(ctx, "failed to cleanup image metadata stash (%v)", err)
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -837,6 +870,7 @@ func (ns *NodeServer) NodeExpandVolume(
|
||||
|
||||
if acquired := ns.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer ns.VolumeLocks.Release(volumeID)
|
||||
@ -853,6 +887,7 @@ func (ns *NodeServer) NodeExpandVolume(
|
||||
if !ok {
|
||||
return nil, status.Errorf(codes.Internal, "rbd: resize failed on path %s, error: %v", req.GetVolumePath(), err)
|
||||
}
|
||||
|
||||
return &csi.NodeExpandVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -870,6 +905,7 @@ func getDevicePath(ctx context.Context, volumePath string) (string, error) {
|
||||
if found {
|
||||
return device, nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("failed to get device for stagingtarget path %v", volumePath)
|
||||
}
|
||||
|
||||
@ -913,6 +949,7 @@ func (ns *NodeServer) processEncryptedDevice(
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get encryption status for rbd image %s: %v",
|
||||
imageSpec, err)
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -928,6 +965,7 @@ func (ns *NodeServer) processEncryptedDevice(
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to setup encryption for rbd"+
|
||||
"image %s: %v", imageSpec, err)
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -988,11 +1026,13 @@ func (ns *NodeServer) xfsSupportsReflink() bool {
|
||||
// mkfs.xfs should fail with an error message (and help text)
|
||||
if strings.Contains(string(out), "reflink=0|1") {
|
||||
xfsHasReflink = xfsReflinkSupport
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
xfsHasReflink = xfsReflinkNoSupport
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -1004,6 +1044,7 @@ func (ns *NodeServer) NodeGetVolumeStats(
|
||||
targetPath := req.GetVolumePath()
|
||||
if targetPath == "" {
|
||||
err = fmt.Errorf("targetpath %v is empty", targetPath)
|
||||
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
@ -1033,6 +1074,7 @@ func blockNodeGetVolumeStats(ctx context.Context, targetPath string) (*csi.NodeG
|
||||
if err != nil {
|
||||
err = fmt.Errorf("lsblk %v returned an error: %w", args, err)
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -1040,6 +1082,7 @@ func blockNodeGetVolumeStats(ctx context.Context, targetPath string) (*csi.NodeG
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to convert %q to bytes: %w", lsblkSize, err)
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
|
@ -140,6 +140,7 @@ func findDeviceMappingImage(ctx context.Context, pool, namespace, image string,
|
||||
rbdDeviceList, err := rbdGetDeviceList(ctx, accessType)
|
||||
if err != nil {
|
||||
util.WarningLog(ctx, "failed to determine if image (%s) is mapped to a device (%v)", imageSpec, err)
|
||||
|
||||
return "", false
|
||||
}
|
||||
|
||||
@ -177,14 +178,17 @@ func checkRbdNbdTools() bool {
|
||||
_, _, err = util.ExecCommand(context.TODO(), "modprobe", moduleNbd)
|
||||
if err != nil {
|
||||
util.ExtendedLogMsg("rbd-nbd: nbd modprobe failed with error %v", err)
|
||||
|
||||
return false
|
||||
}
|
||||
}
|
||||
if _, _, err := util.ExecCommand(context.TODO(), rbdTonbd, "--version"); err != nil {
|
||||
util.ExtendedLogMsg("rbd-nbd: running rbd-nbd --version failed with error %v", err)
|
||||
|
||||
return false
|
||||
}
|
||||
util.ExtendedLogMsg("rbd-nbd tools were found.")
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -325,6 +329,7 @@ func createPath(ctx context.Context, volOpt *rbdVolume, device string, cr *util.
|
||||
util.WarningLog(ctx, "rbd: %s unmap error %v", imagePath, detErr)
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("rbd: map failed with error %w, rbd error output: %s", err, stderr)
|
||||
}
|
||||
devicePath := strings.TrimSuffix(stdout, "\n")
|
||||
@ -342,8 +347,10 @@ func waitForrbdImage(ctx context.Context, backoff wait.Backoff, volOptions *rbdV
|
||||
}
|
||||
if (volOptions.DisableInUseChecks) && (used) {
|
||||
util.UsefulLog(ctx, "valid multi-node attach requested, ignoring watcher in-use result")
|
||||
|
||||
return used, nil
|
||||
}
|
||||
|
||||
return !used, nil
|
||||
})
|
||||
// return error if rbd image has not become available for the specified timeout
|
||||
@ -376,6 +383,7 @@ func detachRBDImageOrDeviceSpec(
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "error determining LUKS device on %s, %s: %s",
|
||||
mapperPath, imageOrDeviceSpec, err)
|
||||
|
||||
return err
|
||||
}
|
||||
if len(mapper) > 0 {
|
||||
@ -384,6 +392,7 @@ func detachRBDImageOrDeviceSpec(
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "error closing LUKS device on %s, %s: %s",
|
||||
mapperPath, imageOrDeviceSpec, err)
|
||||
|
||||
return err
|
||||
}
|
||||
imageOrDeviceSpec = mappedDevice
|
||||
@ -402,8 +411,10 @@ func detachRBDImageOrDeviceSpec(
|
||||
strings.Contains(stderr, fmt.Sprintf(rbdUnmapCmdNbdMissingMap, imageOrDeviceSpec))) {
|
||||
// Devices found not to be mapped are treated as a successful detach
|
||||
util.TraceLog(ctx, "image or device spec (%s) not mapped", imageOrDeviceSpec)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("rbd: unmap for spec (%s) failed (%w): (%s)", imageOrDeviceSpec, err, stderr)
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ func accessModeStrToInt(mode v1.PersistentVolumeAccessMode) csi.VolumeCapability
|
||||
case v1.ReadWriteMany:
|
||||
return csi.VolumeCapability_AccessMode_MULTI_NODE_MULTI_WRITER
|
||||
}
|
||||
|
||||
return csi.VolumeCapability_AccessMode_UNKNOWN
|
||||
}
|
||||
|
||||
@ -54,6 +55,7 @@ func getSecret(c *k8s.Clientset, ns, name string) (map[string]string, error) {
|
||||
secret, err := c.CoreV1().Secrets(ns).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
util.ErrorLogMsg("get secret failed, err: %v", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -78,6 +80,7 @@ func callNodeStageVolume(ns *NodeServer, c *k8s.Clientset, pv *v1.PersistentVolu
|
||||
pv.Spec.PersistentVolumeSource.CSI.NodeStageSecretRef.Name)
|
||||
if err != nil {
|
||||
util.ErrorLogMsg("getSecret failed for volID: %s, err: %v", volID, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -113,6 +116,7 @@ func callNodeStageVolume(ns *NodeServer, c *k8s.Clientset, pv *v1.PersistentVolu
|
||||
if err != nil {
|
||||
util.ErrorLogMsg("nodeStageVolume request failed, volID: %s, stagingPath: %s, err: %v",
|
||||
volID, stagingParentPath, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -125,6 +129,7 @@ func runVolumeHealer(ns *NodeServer, conf *util.Config) error {
|
||||
val, err := c.StorageV1().VolumeAttachments().List(context.TODO(), metav1.ListOptions{})
|
||||
if err != nil {
|
||||
util.ErrorLogMsg("list volumeAttachments failed, err: %v", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -142,6 +147,7 @@ func runVolumeHealer(ns *NodeServer, conf *util.Config) error {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
util.ErrorLogMsg("get persistentVolumes failed for pv: %s, err: %v", pvName, err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
// TODO: check with pv delete annotations, for eg: what happens when the pv is marked for delete
|
||||
@ -162,6 +168,7 @@ func runVolumeHealer(ns *NodeServer, conf *util.Config) error {
|
||||
util.ErrorLogMsg("get volumeAttachments failed for volumeAttachment: %s, volID: %s, err: %v",
|
||||
val.Items[i].Name, pv.Spec.PersistentVolumeSource.CSI.VolumeHandle, err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
if !va.Status.Attached {
|
||||
|
@ -168,11 +168,13 @@ func checkSnapCloneExists(
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrSnapNotFound) {
|
||||
util.ErrorLog(ctx, "failed to delete snapshot %s: %v", rbdSnap, err)
|
||||
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
err = undoSnapshotCloning(ctx, parentVol, rbdSnap, vol, cr)
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -198,6 +200,7 @@ func checkSnapCloneExists(
|
||||
if sErr != nil {
|
||||
util.ErrorLog(ctx, "failed to create snapshot %s: %v", rbdSnap, sErr)
|
||||
err = undoSnapshotCloning(ctx, parentVol, rbdSnap, vol, cr)
|
||||
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@ -210,18 +213,21 @@ func checkSnapCloneExists(
|
||||
if sErr != nil {
|
||||
util.ErrorLog(ctx, "failed to get image id %s: %v", vol, sErr)
|
||||
err = undoSnapshotCloning(ctx, parentVol, rbdSnap, vol, cr)
|
||||
|
||||
return false, err
|
||||
}
|
||||
sErr = j.StoreImageID(ctx, vol.JournalPool, vol.ReservedID, vol.ImageID)
|
||||
if sErr != nil {
|
||||
util.ErrorLog(ctx, "failed to store volume id %s: %v", vol, sErr)
|
||||
err = undoSnapshotCloning(ctx, parentVol, rbdSnap, vol, cr)
|
||||
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
util.DebugLog(ctx, "found existing image (%s) with name (%s) for request (%s)",
|
||||
rbdSnap.VolID, rbdSnap.RbdSnapName, rbdSnap.RequestName)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@ -299,8 +305,10 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
|
||||
}
|
||||
err = j.UndoReservation(ctx, rv.JournalPool, rv.Pool,
|
||||
rv.RbdImageName, rv.RequestName)
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -327,6 +335,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
|
||||
err = parentVol.copyEncryptionConfig(&rv.rbdImage)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
@ -348,11 +357,13 @@ func (rv *rbdVolume) repairImageID(ctx context.Context, j *journal.Connection) e
|
||||
err := rv.getImageID()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get image id %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
err = j.StoreImageID(ctx, rv.JournalPool, rv.ReservedID, rv.ImageID)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to store volume id %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -544,6 +555,7 @@ func RegenerateJournal(
|
||||
rbdVol.Monitors, _, err = util.GetMonsAndClusterID(options)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting mons (%s)", err)
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -593,6 +605,7 @@ func RegenerateJournal(
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return rbdVol.VolID, nil
|
||||
}
|
||||
|
||||
@ -635,12 +648,15 @@ func (rv *rbdVolume) storeImageID(ctx context.Context, j *journal.Connection) er
|
||||
err := rv.getImageID()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to get image id %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
err = j.StoreImageID(ctx, rv.JournalPool, rv.ReservedID, rv.ImageID)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to store volume id %s: %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ func (ri *rbdImage) Connect(cr *util.Credentials) error {
|
||||
}
|
||||
|
||||
ri.conn = conn
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -212,6 +213,7 @@ func (ri *rbdImage) String() string {
|
||||
if ri.RadosNamespace != "" {
|
||||
return fmt.Sprintf("%s/%s/%s", ri.Pool, ri.RadosNamespace, ri.RbdImageName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", ri.Pool, ri.RbdImageName)
|
||||
}
|
||||
|
||||
@ -220,6 +222,7 @@ func (rs *rbdSnapshot) String() string {
|
||||
if rs.RadosNamespace != "" {
|
||||
return fmt.Sprintf("%s/%s/%s@%s", rs.Pool, rs.RadosNamespace, rs.RbdImageName, rs.RbdSnapName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s@%s", rs.Pool, rs.RbdImageName, rs.RbdSnapName)
|
||||
}
|
||||
|
||||
@ -275,6 +278,7 @@ func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
||||
// nolint:errcheck // deleteImage() will log errors in
|
||||
// case it fails, no need to log them here again
|
||||
_ = deleteImage(ctx, pOpts, cr)
|
||||
|
||||
return fmt.Errorf("failed to thick provision image: %w", err)
|
||||
}
|
||||
|
||||
@ -283,6 +287,7 @@ func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
||||
// nolint:errcheck // deleteImage() will log errors in
|
||||
// case it fails, no need to log them here again
|
||||
_ = deleteImage(ctx, pOpts, cr)
|
||||
|
||||
return fmt.Errorf("failed to mark image as thick-provisioned: %w", err)
|
||||
}
|
||||
}
|
||||
@ -324,6 +329,7 @@ func (rv *rbdVolume) getImageID() error {
|
||||
return err
|
||||
}
|
||||
rv.ImageID = id
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -342,8 +348,10 @@ func (ri *rbdImage) open() (*librbd.Image, error) {
|
||||
if errors.Is(err, librbd.ErrNotFound) {
|
||||
err = util.JoinErrors(ErrImageNotFound, err)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
|
||||
@ -454,6 +462,7 @@ func (rv *rbdVolume) isInUse() (bool, error) {
|
||||
// mirror daemon for mirrored images.
|
||||
defaultWatchers++
|
||||
}
|
||||
|
||||
return len(watchers) > defaultWatchers, nil
|
||||
}
|
||||
|
||||
@ -471,6 +480,7 @@ func isNotMountPoint(mounter mount.Interface, stagingTargetPath string) (bool, e
|
||||
if os.IsNotExist(err) {
|
||||
err = nil
|
||||
}
|
||||
|
||||
return isNotMnt, err
|
||||
}
|
||||
|
||||
@ -509,6 +519,7 @@ func addRbdManagerTask(ctx context.Context, pOpts *rbdVolume, arg []string) (boo
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%w. stdError:%s", err, stderr)
|
||||
}
|
||||
|
||||
return supported, err
|
||||
}
|
||||
|
||||
@ -540,6 +551,7 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
||||
err = rbdImage.Trash(0)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s, error: %v", pOpts, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -554,6 +566,7 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
||||
rbdCephMgrSupported, err := addRbdManagerTask(ctx, pOpts, args)
|
||||
if rbdCephMgrSupported && err != nil {
|
||||
util.ErrorLog(ctx, "failed to add task to delete rbd image: %s, %v", pOpts, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -561,6 +574,7 @@ func deleteImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er
|
||||
err = librbd.TrashRemove(pOpts.ioctx, pOpts.ImageID, true)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s, %v", pOpts, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -599,6 +613,7 @@ func (rv *rbdVolume) getCloneDepth(ctx context.Context) (uint, error) {
|
||||
return depth, nil
|
||||
}
|
||||
util.ErrorLog(ctx, "failed to check depth on image %s: %s", &vol, err)
|
||||
|
||||
return depth, err
|
||||
}
|
||||
if vol.ParentName != "" {
|
||||
@ -627,6 +642,7 @@ func flattenClonedRbdImages(
|
||||
err := rv.Connect(cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to open connection %s; err %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
var origNameList []trashSnapInfo
|
||||
@ -652,9 +668,11 @@ func flattenClonedRbdImages(
|
||||
err = rv.flattenRbdImage(ctx, cr, true, rbdHardMaxCloneDepth, rbdSoftMaxCloneDepth)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to flatten %s; err %v", rv, err)
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -694,6 +712,7 @@ func (rv *rbdVolume) flattenRbdImage(
|
||||
return nil
|
||||
}
|
||||
util.ErrorLog(ctx, "failed to add task flatten for %s : %v", rv, err)
|
||||
|
||||
return err
|
||||
}
|
||||
if forceFlatten || depth >= hardlimit {
|
||||
@ -713,6 +732,7 @@ func (rv *rbdVolume) flattenRbdImage(
|
||||
err := rv.flatten()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "rbd failed to flatten image %s %s: %v", rv.Pool, rv.RbdImageName, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -732,6 +752,7 @@ func (rv *rbdVolume) getParentName() (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return parentInfo.Image.ImageName, nil
|
||||
}
|
||||
|
||||
@ -753,6 +774,7 @@ func (rv *rbdVolume) flatten() error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -792,6 +814,7 @@ func (rv *rbdVolume) checkImageChainHasFeature(ctx context.Context, feature uint
|
||||
return false, nil
|
||||
}
|
||||
util.ErrorLog(ctx, "failed to get image info for %s: %s", vol.String(), err)
|
||||
|
||||
return false, err
|
||||
}
|
||||
if f := vol.hasFeature(feature); f {
|
||||
@ -821,6 +844,7 @@ func genSnapFromSnapID(
|
||||
err := vi.DecomposeCSIID(rbdSnap.VolID)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "error decoding snapshot ID (%s) (%s)", err, rbdSnap.VolID)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -830,6 +854,7 @@ func genSnapFromSnapID(
|
||||
rbdSnap.Monitors, _, err = util.GetMonsAndClusterID(options)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting mons (%s)", err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -925,6 +950,7 @@ func generateVolumeFromVolumeID(
|
||||
rbdVol.Monitors, _, err = util.GetMonsAndClusterID(options)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting mons (%s)", err)
|
||||
|
||||
return rbdVol, err
|
||||
}
|
||||
|
||||
@ -983,6 +1009,7 @@ func generateVolumeFromVolumeID(
|
||||
}
|
||||
}
|
||||
err = rbdVol.getImageInfo()
|
||||
|
||||
return rbdVol, err
|
||||
}
|
||||
|
||||
@ -1016,10 +1043,12 @@ func genVolFromVolID(
|
||||
if pvlist.Items[i].Spec.CSI != nil && pvlist.Items[i].Spec.CSI.VolumeHandle == volumeID {
|
||||
if v, ok := pvlist.Items[i].Annotations[PVVolumeHandleAnnotationKey]; ok {
|
||||
util.UsefulLog(ctx, "found new volumeID %s for existing volumeID %s", v, volumeID)
|
||||
|
||||
return generateVolumeFromVolumeID(ctx, v, cr, secrets)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vol, err
|
||||
}
|
||||
|
||||
@ -1047,6 +1076,7 @@ func genVolFromVolumeOptions(
|
||||
rbdVol.Monitors, rbdVol.ClusterID, err = util.GetMonsAndClusterID(volOptions)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting mons (%s)", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1061,6 +1091,7 @@ func genVolFromVolumeOptions(
|
||||
// which disable all RBD image features as we expected
|
||||
if err = rbdVol.validateImageFeatures(volOptions["imageFeatures"]); err != nil {
|
||||
util.ErrorLog(ctx, "failed to validate image features %v", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1107,6 +1138,7 @@ func (rv *rbdVolume) validateImageFeatures(imageFeatures string) error {
|
||||
}
|
||||
}
|
||||
rv.imageFeatureSet = librbd.FeatureSetFromNames(arr)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1121,6 +1153,7 @@ func genSnapFromOptions(ctx context.Context, rbdVol *rbdVolume, snapOptions map[
|
||||
rbdSnap.Monitors, rbdSnap.ClusterID, err = util.GetMonsAndClusterID(snapOptions)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed getting mons (%s)", err)
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -1145,6 +1178,7 @@ func (rv *rbdVolume) createSnapshot(ctx context.Context, pOpts *rbdSnapshot) err
|
||||
defer image.Close()
|
||||
|
||||
_, err = image.CreateSnapshot(pOpts.RbdSnapName)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1164,6 +1198,7 @@ func (rv *rbdVolume) deleteSnapshot(ctx context.Context, pOpts *rbdSnapshot) err
|
||||
if errors.Is(err, librbd.ErrNotFound) {
|
||||
return util.JoinErrors(ErrSnapNotFound, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1299,6 +1334,7 @@ func (rv *rbdVolume) getImageInfo() error {
|
||||
return err
|
||||
}
|
||||
rv.CreatedAt = protoTime
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1332,6 +1368,7 @@ func (rv *rbdVolume) updateVolWithImageInfo() error {
|
||||
": (2) No such file or directory") {
|
||||
return util.JoinErrors(ErrImageNotFound, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -1342,6 +1379,7 @@ func (rv *rbdVolume) updateVolWithImageInfo() error {
|
||||
}
|
||||
rv.Primary = imgInfo.Mirroring.Primary
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1391,6 +1429,7 @@ func (ri *rbdImageMetadataStash) String() string {
|
||||
if ri.RadosNamespace != "" {
|
||||
return fmt.Sprintf("%s/%s/%s", ri.Pool, ri.RadosNamespace, ri.ImageName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", ri.Pool, ri.ImageName)
|
||||
}
|
||||
|
||||
@ -1471,6 +1510,7 @@ func updateRBDImageMetadataStash(metaDataPath, device string) error {
|
||||
return fmt.Errorf("failed to stash JSON image metadata at path: (%s) for spec:(%s) : %w",
|
||||
fPath, imgMeta.String(), err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -1522,6 +1562,7 @@ func (rv *rbdVolume) resize(newSize int64) error {
|
||||
if resizeErr != nil {
|
||||
err = fmt.Errorf("failed to shrink image (%v) after failed allocation: %w", resizeErr, err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -1605,6 +1646,7 @@ func (ri *rbdImage) isThickProvisioned() (bool, error) {
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to convert %q=%q to a boolean: %w", thickProvisionMetaKey, value, err)
|
||||
}
|
||||
|
||||
return thick, nil
|
||||
}
|
||||
|
||||
@ -1699,6 +1741,7 @@ func (rv *rbdVolume) listSnapshots() ([]librbd.SnapInfo, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return snapInfoList, nil
|
||||
}
|
||||
|
||||
@ -1719,6 +1762,7 @@ func (rv *rbdVolume) isTrashSnap(snapID uint64) (bool, error) {
|
||||
if nsType == librbd.SnapNamespaceTypeTrash {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
@ -1830,5 +1874,6 @@ func (ri *rbdImage) addSnapshotScheduling(
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ func TestValidateImageFeatures(t *testing.T) {
|
||||
err := test.rbdVol.validateImageFeatures(test.imageFeatures)
|
||||
if test.isErr {
|
||||
assert.EqualError(t, err, test.errMsg)
|
||||
|
||||
continue
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
@ -90,12 +90,14 @@ func getForceOption(ctx context.Context, parameters map[string]string) (bool, er
|
||||
val, ok := parameters[forceKey]
|
||||
if !ok {
|
||||
util.WarningLog(ctx, "%s is not set in parameters, setting to default (%v)", forceKey, false)
|
||||
|
||||
return false, nil
|
||||
}
|
||||
force, err := strconv.ParseBool(val)
|
||||
if err != nil {
|
||||
return false, status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return force, nil
|
||||
}
|
||||
|
||||
@ -109,6 +111,7 @@ func getMirroringMode(ctx context.Context, parameters map[string]string) (librbd
|
||||
"%s is not set in parameters, setting to mirroringMode to default (%s)",
|
||||
imageMirroringKey,
|
||||
imageMirrorModeSnapshot)
|
||||
|
||||
return librbd.ImageMirrorModeSnapshot, nil
|
||||
}
|
||||
|
||||
@ -119,6 +122,7 @@ func getMirroringMode(ctx context.Context, parameters map[string]string) (librbd
|
||||
default:
|
||||
return mirroringMode, status.Errorf(codes.InvalidArgument, "%s %s not supported", imageMirroringKey, val)
|
||||
}
|
||||
|
||||
return mirroringMode, nil
|
||||
}
|
||||
|
||||
@ -159,6 +163,7 @@ func getSchedulingDetails(parameters map[string]string) (admin.Interval, admin.S
|
||||
return admInt, admin.NoStartTime, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return admInt, adminStartTime, nil
|
||||
}
|
||||
|
||||
@ -169,6 +174,7 @@ func validateSchedulingInterval(interval string) (admin.Interval, error) {
|
||||
if re.MatchString(interval) {
|
||||
return admin.Interval(interval), nil
|
||||
}
|
||||
|
||||
return "", errors.New("interval specified without d, h, m suffix")
|
||||
}
|
||||
|
||||
@ -195,6 +201,7 @@ func (rs *ReplicationServer) EnableVolumeReplication(ctx context.Context,
|
||||
|
||||
if acquired := rs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer rs.VolumeLocks.Release(volumeID)
|
||||
@ -210,6 +217,7 @@ func (rs *ReplicationServer) EnableVolumeReplication(ctx context.Context,
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
// extract the mirroring mode
|
||||
@ -221,6 +229,7 @@ func (rs *ReplicationServer) EnableVolumeReplication(ctx context.Context,
|
||||
mirroringInfo, err := rbdVol.getImageMirroringInfo()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -228,6 +237,7 @@ func (rs *ReplicationServer) EnableVolumeReplication(ctx context.Context,
|
||||
err = rbdVol.enableImageMirroring(mirroringMode)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -266,6 +276,7 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
|
||||
|
||||
if acquired := rs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer rs.VolumeLocks.Release(volumeID)
|
||||
@ -281,6 +292,7 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
// extract the force option
|
||||
@ -292,6 +304,7 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
|
||||
mirroringInfo, err := rbdVol.getImageMirroringInfo()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -308,6 +321,7 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
|
||||
err = rbdVol.disableImageMirroring(force)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
// the image state can be still disabling once we disable the mirroring
|
||||
@ -315,11 +329,13 @@ func (rs *ReplicationServer) DisableVolumeReplication(ctx context.Context,
|
||||
mirroringInfo, err = rbdVol.getImageMirroringInfo()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
if mirroringInfo.State == librbd.MirrorImageDisabling {
|
||||
return nil, status.Errorf(codes.Aborted, "%s is in disabling state", volumeID)
|
||||
}
|
||||
|
||||
return &replication.DisableVolumeReplicationResponse{}, nil
|
||||
default:
|
||||
// TODO: use string instead of int for returning valid error message
|
||||
@ -348,6 +364,7 @@ func (rs *ReplicationServer) PromoteVolume(ctx context.Context,
|
||||
|
||||
if acquired := rs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer rs.VolumeLocks.Release(volumeID)
|
||||
@ -363,12 +380,14 @@ func (rs *ReplicationServer) PromoteVolume(ctx context.Context,
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mirroringInfo, err := rbdVol.getImageMirroringInfo()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -394,6 +413,7 @@ func (rs *ReplicationServer) PromoteVolume(ctx context.Context,
|
||||
if strings.Contains(err.Error(), "Device or resource busy") {
|
||||
return nil, status.Error(codes.FailedPrecondition, err.Error())
|
||||
}
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -420,6 +440,7 @@ func (rs *ReplicationServer) DemoteVolume(ctx context.Context,
|
||||
|
||||
if acquired := rs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer rs.VolumeLocks.Release(volumeID)
|
||||
@ -435,11 +456,13 @@ func (rs *ReplicationServer) DemoteVolume(ctx context.Context,
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
mirroringInfo, err := rbdVol.getImageMirroringInfo()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
@ -456,9 +479,11 @@ func (rs *ReplicationServer) DemoteVolume(ctx context.Context,
|
||||
err = rbdVol.demoteImage()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return &replication.DemoteVolumeResponse{}, nil
|
||||
}
|
||||
|
||||
@ -481,6 +506,7 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
|
||||
if acquired := rs.VolumeLocks.TryAcquire(volumeID); !acquired {
|
||||
util.ErrorLog(ctx, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
|
||||
return nil, status.Errorf(codes.Aborted, util.VolumeOperationAlreadyExistsFmt, volumeID)
|
||||
}
|
||||
defer rs.VolumeLocks.Release(volumeID)
|
||||
@ -495,6 +521,7 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
default:
|
||||
err = status.Errorf(codes.Internal, err.Error())
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -503,6 +530,7 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
// in case of Resync the image will get deleted and gets recreated and
|
||||
// it takes time for this operation.
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Aborted, err.Error())
|
||||
}
|
||||
|
||||
@ -523,9 +551,11 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
resp := &replication.ResyncVolumeResponse{
|
||||
Ready: false,
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
ready := false
|
||||
@ -561,6 +591,7 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
err = rbdVol.resyncImage()
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, err.Error())
|
||||
|
||||
return nil, status.Error(codes.Internal, err.Error())
|
||||
}
|
||||
}
|
||||
@ -574,5 +605,6 @@ func (rs *ReplicationServer) ResyncVolume(ctx context.Context,
|
||||
resp := &replication.ResyncVolumeResponse{
|
||||
Ready: ready,
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ func TestValidateSchedulingInterval(t *testing.T) {
|
||||
got, err := validateSchedulingInterval(tt.interval)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("validateSchedulingInterval() error = %v, wantErr %v", err, tt.wantErr)
|
||||
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
@ -145,6 +146,7 @@ func TestGetSchedulingDetails(t *testing.T) {
|
||||
interval, startTime, err := getSchedulingDetails(tt.parameters)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getSchedulingDetails() error = %v, wantErr %v", err, tt.wantErr)
|
||||
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(interval, tt.wantInterval) {
|
||||
|
@ -32,6 +32,7 @@ func createRBDClone(
|
||||
err := parentVol.createSnapshot(ctx, snap)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to create snapshot %s: %v", snap, err)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -58,6 +59,7 @@ func createRBDClone(
|
||||
if delErr != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s with error: %v", cloneRbdVol, delErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -68,6 +70,7 @@ func createRBDClone(
|
||||
if delErr != nil {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image: %s with error: %v", cloneRbdVol, delErr)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@ -86,6 +89,7 @@ func cleanUpSnapshot(
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrSnapNotFound) {
|
||||
util.ErrorLog(ctx, "failed to delete snapshot %q: %v", rbdSnap, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -95,6 +99,7 @@ func cleanUpSnapshot(
|
||||
if err != nil {
|
||||
if !errors.Is(err, ErrImageNotFound) {
|
||||
util.ErrorLog(ctx, "failed to delete rbd image %q with error: %v", rbdVol, err)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -117,6 +122,7 @@ func generateVolFromSnap(rbdSnap *rbdSnapshot) *rbdVolume {
|
||||
// snapshot will have the same volumeID which cases the panic in
|
||||
// copyEncryptionConfig function.
|
||||
vol.encryption = rbdSnap.encryption
|
||||
|
||||
return vol
|
||||
}
|
||||
|
||||
@ -129,8 +135,10 @@ func undoSnapshotCloning(
|
||||
err := cleanUpSnapshot(ctx, parentVol, rbdSnap, cloneVol, cr)
|
||||
if err != nil {
|
||||
util.ErrorLog(ctx, "failed to clean up %s or %s: %v", cloneVol, rbdSnap, err)
|
||||
|
||||
return err
|
||||
}
|
||||
err = undoSnapReservation(ctx, rbdSnap, cr)
|
||||
|
||||
return err
|
||||
}
|
||||
|
Reference in New Issue
Block a user