@@ -19,6 +19,7 @@ package cinder
1919import (
2020 "fmt"
2121 "strconv"
22+ "time"
2223
2324 "github.com/container-storage-interface/spec/lib/go/csi"
2425 "github.com/gophercloud/gophercloud/openstack/blockstorage/v3/snapshots"
@@ -29,6 +30,7 @@ import (
2930 "google.golang.org/grpc/status"
3031 "google.golang.org/protobuf/types/known/timestamppb"
3132
33+ "k8s.io/apimachinery/pkg/util/wait"
3234 "k8s.io/cloud-provider-openstack/pkg/csi/cinder/openstack"
3335 "k8s.io/cloud-provider-openstack/pkg/util"
3436 cpoerrors "k8s.io/cloud-provider-openstack/pkg/util/errors"
@@ -93,12 +95,16 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
9395 if volSizeGB != volumes [0 ].Size {
9496 return nil , status .Error (codes .AlreadyExists , "Volume Already exists with same name and different capacity" )
9597 }
98+
99+ if volumes [0 ].Status != openstack .VolumeAvailableStatus {
100+ return nil , status .Error (codes .Internal , fmt .Sprintf ("Volume %s is not in available state" , volumes [0 ].ID ))
101+ }
102+
96103 klog .V (4 ).Infof ("Volume %s already exists in Availability Zone: %s of size %d GiB" , volumes [0 ].ID , volumes [0 ].AvailabilityZone , volumes [0 ].Size )
97104 return getCreateVolumeResponse (& volumes [0 ], ignoreVolumeAZ , req .GetAccessibilityRequirements ()), nil
98105 } else if len (volumes ) > 1 {
99106 klog .V (3 ).Infof ("found multiple existing volumes with selected name (%s) during create" , volName )
100107 return nil , status .Error (codes .Internal , "Multiple volumes reported by Cinder with same name" )
101-
102108 }
103109
104110 // Volume Create
@@ -136,11 +142,21 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
136142 }
137143
138144 vol , err := cloud .CreateVolume (volName , volSizeGB , volType , volAvailability , snapshotID , sourcevolID , & properties )
139-
140145 if err != nil {
141146 klog .Errorf ("Failed to CreateVolume: %v" , err )
142147 return nil , status .Error (codes .Internal , fmt .Sprintf ("CreateVolume failed with error %v" , err ))
148+ }
143149
150+ targetStatus := []string {openstack .VolumeAvailableStatus }
151+ err = cloud .WaitVolumeTargetStatusWithCustomBackoff (vol .ID , targetStatus ,
152+ & wait.Backoff {
153+ Duration : 20 * time .Second ,
154+ Steps : 5 ,
155+ Factor : 1.28 ,
156+ })
157+ if err != nil {
158+ klog .Errorf ("Failed to WaitVolumeTargetStatus of volume %s: %v" , vol .ID , err )
159+ return nil , status .Error (codes .Internal , fmt .Sprintf ("CreateVolume Volume %s failed getting available in time: %v" , vol .ID , err ))
144160 }
145161
146162 klog .V (4 ).Infof ("CreateVolume: Successfully created volume %s in Availability Zone: %s of size %d GiB" , vol .ID , vol .AvailabilityZone , vol .Size )
0 commit comments