rbd: no need to flatten thick-provisioned images

Thick-provisioned images are independent, cloned images or snapshots are
deep-flattened during creation. There is no need to try and flatten them
again.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2021-06-15 09:23:47 +02:00 committed by mergify[bot]
parent 0fe0962dc1
commit 4908ff8743
4 changed files with 23 additions and 12 deletions

View File

@ -264,6 +264,11 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro
} }
func (rv *rbdVolume) flattenCloneImage(ctx context.Context) error { func (rv *rbdVolume) flattenCloneImage(ctx context.Context) error {
if rv.ThickProvision {
// thick-provisioned images do not need flattening
return nil
}
tempClone := rv.generateTempClone() tempClone := rv.generateTempClone()
// reducing the limit for cloned images to make sure the limit is in range, // reducing the limit for cloned images to make sure the limit is in range,
// If the intermediate clone reaches the depth we may need to return ABORT // If the intermediate clone reaches the depth we may need to return ABORT

View File

@ -117,7 +117,7 @@ func (cs *ControllerServer) parseVolCreateRequest(ctx context.Context, req *csi.
return nil, status.Error(codes.InvalidArgument, err.Error()) return nil, status.Error(codes.InvalidArgument, err.Error())
} }
rbdVol.ThickProvision = cs.isThickProvisionRequest(req) rbdVol.ThickProvision = isThickProvisionRequest(req.GetParameters())
rbdVol.RequestName = req.GetName() rbdVol.RequestName = req.GetName()
@ -343,7 +343,7 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
case vcs == nil: case vcs == nil:
// continue/restart allocating the volume in case it // continue/restart allocating the volume in case it
// should be thick-provisioned // should be thick-provisioned
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
err := rbdVol.RepairThickProvision() err := rbdVol.RepairThickProvision()
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
@ -379,6 +379,11 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C
// are more than the `minSnapshotOnImage` Add a task to flatten all the // are more than the `minSnapshotOnImage` Add a task to flatten all the
// temporary cloned images. // temporary cloned images.
func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error { func flattenTemporaryClonedImages(ctx context.Context, rbdVol *rbdVolume, cr *util.Credentials) error {
if rbdVol.ThickProvision {
// thick-provisioned images do not need flattening
return nil
}
snaps, err := rbdVol.listSnapshots() snaps, err := rbdVol.listSnapshots()
if err != nil { if err != nil {
if errors.Is(err, ErrImageNotFound) { if errors.Is(err, ErrImageNotFound) {
@ -1171,10 +1176,10 @@ func (cs *ControllerServer) ControllerExpandVolume(ctx context.Context, req *csi
// isThickProvisionRequest returns true in case the request contains the // isThickProvisionRequest returns true in case the request contains the
// `thickProvision` option set to `true`. // `thickProvision` option set to `true`.
func (cs *ControllerServer) isThickProvisionRequest(req *csi.CreateVolumeRequest) bool { func isThickProvisionRequest(parameters map[string]string) bool {
tp := "thickProvision" tp := "thickProvision"
thick, ok := req.GetParameters()[tp] thick, ok := parameters[tp]
if !ok || thick == "" { if !ok || thick == "" {
return false return false
} }

View File

@ -23,7 +23,6 @@ import (
) )
func TestIsThickProvisionRequest(t *testing.T) { func TestIsThickProvisionRequest(t *testing.T) {
cs := &ControllerServer{}
req := &csi.CreateVolumeRequest{ req := &csi.CreateVolumeRequest{
Name: "fake", Name: "fake",
Parameters: map[string]string{ Parameters: map[string]string{
@ -32,38 +31,38 @@ func TestIsThickProvisionRequest(t *testing.T) {
} }
// pass disabled/invalid values for "thickProvision" option // pass disabled/invalid values for "thickProvision" option
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Error("request is not for thick-provisioning") t.Error("request is not for thick-provisioning")
} }
req.Parameters["thickProvision"] = "" req.Parameters["thickProvision"] = ""
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
req.Parameters["thickProvision"] = "false" req.Parameters["thickProvision"] = "false"
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
req.Parameters["thickProvision"] = "off" req.Parameters["thickProvision"] = "off"
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
req.Parameters["thickProvision"] = "no" req.Parameters["thickProvision"] = "no"
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
req.Parameters["thickProvision"] = "**true**" req.Parameters["thickProvision"] = "**true**"
if cs.isThickProvisionRequest(req) { if isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request is not for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
// only "true" should enable thick provisioning // only "true" should enable thick provisioning
req.Parameters["thickProvision"] = "true" req.Parameters["thickProvision"] = "true"
if !cs.isThickProvisionRequest(req) { if !isThickProvisionRequest(req.GetParameters()) {
t.Errorf("request should be for thick-provisioning: %s", req.Parameters["thickProvision"]) t.Errorf("request should be for thick-provisioning: %s", req.Parameters["thickProvision"])
} }
} }

View File

@ -171,6 +171,8 @@ func (ns *NodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }
volOptions.ThickProvision = isThickProvisionRequest(req.GetVolumeContext())
// get rbd image name from the volume journal // get rbd image name from the volume journal
// for static volumes, the image name is actually the volume ID itself // for static volumes, the image name is actually the volume ID itself
switch { switch {