@@ -19,6 +19,7 @@ import (
19
19
"math/rand"
20
20
"sort"
21
21
"strings"
22
+ "sync"
22
23
"time"
23
24
24
25
"github.com/golang/protobuf/ptypes"
@@ -41,6 +42,10 @@ type GCEControllerServer struct {
41
42
Driver * GCEDriver
42
43
CloudProvider gce.GCECompute
43
44
MetadataService metadataservice.MetadataService
45
+
46
+ // A map storing all volumes with ongoing operations so that additional operations
47
+ // for that same volume (as defined by Volume Key) return an Aborted error
48
+ volumes sync.Map
44
49
}
45
50
46
51
var _ csi.ControllerServer = & GCEControllerServer {}
@@ -138,6 +143,11 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
138
143
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("CreateVolume replication type '%s' is not supported" , replicationType ))
139
144
}
140
145
146
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
147
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
148
+ }
149
+ defer gceCS .volumes .Delete (volKey .String ())
150
+
141
151
// Validate if disk already exists
142
152
existingDisk , err := gceCS .CloudProvider .GetDisk (ctx , volKey )
143
153
if err != nil {
@@ -213,6 +223,11 @@ func (gceCS *GCEControllerServer) DeleteVolume(ctx context.Context, req *csi.Del
213
223
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
214
224
}
215
225
226
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
227
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
228
+ }
229
+ defer gceCS .volumes .Delete (volKey .String ())
230
+
216
231
err = gceCS .CloudProvider .DeleteDisk (ctx , volKey )
217
232
if err != nil {
218
233
return nil , status .Error (codes .Internal , fmt .Sprintf ("unknown Delete disk error: %v" , err ))
@@ -249,6 +264,11 @@ func (gceCS *GCEControllerServer) ControllerPublishVolume(ctx context.Context, r
249
264
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
250
265
}
251
266
267
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
268
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
269
+ }
270
+ defer gceCS .volumes .Delete (volKey .String ())
271
+
252
272
// TODO(#253): Check volume capability matches for ALREADY_EXISTS
253
273
if err = validateVolumeCapability (volumeCapability ); err != nil {
254
274
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("VolumeCapabilities is invalid: %v" , err ))
@@ -334,6 +354,11 @@ func (gceCS *GCEControllerServer) ControllerUnpublishVolume(ctx context.Context,
334
354
return nil , err
335
355
}
336
356
357
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
358
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
359
+ }
360
+ defer gceCS .volumes .Delete (volKey .String ())
361
+
337
362
instanceZone , instanceName , err := common .NodeIDToZoneAndName (nodeID )
338
363
if err != nil {
339
364
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("could not split nodeID: %v" , err ))
@@ -380,6 +405,12 @@ func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context
380
405
if err != nil {
381
406
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Volume ID is of improper format, got %v" , volumeID ))
382
407
}
408
+
409
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
410
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
411
+ }
412
+ defer gceCS .volumes .Delete (volKey .String ())
413
+
383
414
_ , err = gceCS .CloudProvider .GetDisk (ctx , volKey )
384
415
if err != nil {
385
416
if gce .IsGCEError (err , "notFound" ) {
@@ -487,6 +518,11 @@ func (gceCS *GCEControllerServer) CreateSnapshot(ctx context.Context, req *csi.C
487
518
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
488
519
}
489
520
521
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
522
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
523
+ }
524
+ defer gceCS .volumes .Delete (volKey .String ())
525
+
490
526
// Check if snapshot already exists
491
527
var snapshot * compute.Snapshot
492
528
snapshot , err = gceCS .CloudProvider .GetSnapshot (ctx , req .Name )
0 commit comments