From d357bebbc21895cd8d01bf0f04e2db425b4b95c9 Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Mon, 17 Jan 2022 12:44:39 +0530 Subject: [PATCH] cephfs: disallow creating small volumes from snapshot/volume as per the CSI standard the size is optional parameter, as we are allowing the clone to a bigger size today we need to block the clone to a smaller size as its a have side effects like data corruption etc. Note:- Even though this check is present in kubernetes sidecar as CSI is CO independent adding the check here. fixes: #2718 Signed-off-by: Madhu Rajanna --- internal/cephfs/controllerserver.go | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/internal/cephfs/controllerserver.go b/internal/cephfs/controllerserver.go index 9a35475e8..5aa94c551 100644 --- a/internal/cephfs/controllerserver.go +++ b/internal/cephfs/controllerserver.go @@ -148,6 +148,35 @@ func checkContentSource( return nil, nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source %v", volumeSource) } +// checkValidCreateVolumeRequest checks if the request is valid +// CreateVolumeRequest by inspecting the request parameters. +func checkValidCreateVolumeRequest( + vol, + parentVol *store.VolumeOptions, + pvID *store.VolumeIdentifier, + sID *store.SnapshotIdentifier) error { + switch { + case pvID != nil: + if vol.Size < parentVol.Size { + return fmt.Errorf( + "cannot clone from volume %s: volume size %d is smaller than source volume size %d", + pvID.VolumeID, + parentVol.Size, + vol.Size) + } + case sID != nil: + if vol.Size < parentVol.Size { + return fmt.Errorf( + "cannot restore from snapshot %s: volume size %d is smaller than source volume size %d", + sID.SnapshotID, + parentVol.Size, + vol.Size) + } + } + + return nil +} + // CreateVolume creates a reservation and the volume in backend, if it is not already present. // nolint:gocognit,gocyclo,nestif,cyclop // TODO: reduce complexity func (cs *ControllerServer) CreateVolume( @@ -199,6 +228,11 @@ func (cs *ControllerServer) CreateVolume( defer parentVol.Destroy() } + err = checkValidCreateVolumeRequest(volOptions, parentVol, pvID, sID) + if err != nil { + return nil, status.Error(codes.InvalidArgument, err.Error()) + } + vID, err := store.CheckVolExists(ctx, volOptions, parentVol, pvID, sID, cr) if err != nil { if cerrors.IsCloneRetryError(err) {