@@ -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"
@@ -42,6 +43,10 @@ type GCEControllerServer struct {
42
43
Driver * GCEDriver
43
44
CloudProvider gce.GCECompute
44
45
MetadataService metadataservice.MetadataService
46
+
47
+ // A map storing all volumes with ongoing operations so that additional operations
48
+ // for that same volume (as defined by Volume Key) return an Aborted error
49
+ volumes sync.Map
45
50
}
46
51
47
52
var _ csi.ControllerServer = & GCEControllerServer {}
@@ -139,6 +144,11 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
139
144
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("CreateVolume replication type '%s' is not supported" , replicationType ))
140
145
}
141
146
147
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
148
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
149
+ }
150
+ defer gceCS .volumes .Delete (volKey .String ())
151
+
142
152
// Validate if disk already exists
143
153
existingDisk , err := gceCS .CloudProvider .GetDisk (ctx , volKey )
144
154
if err != nil {
@@ -222,6 +232,11 @@ func (gceCS *GCEControllerServer) DeleteVolume(ctx context.Context, req *csi.Del
222
232
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
223
233
}
224
234
235
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
236
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
237
+ }
238
+ defer gceCS .volumes .Delete (volKey .String ())
239
+
225
240
err = gceCS .CloudProvider .DeleteDisk (ctx , volKey )
226
241
if err != nil {
227
242
return nil , status .Error (codes .Internal , fmt .Sprintf ("unknown Delete disk error: %v" , err ))
@@ -258,6 +273,11 @@ func (gceCS *GCEControllerServer) ControllerPublishVolume(ctx context.Context, r
258
273
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
259
274
}
260
275
276
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
277
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
278
+ }
279
+ defer gceCS .volumes .Delete (volKey .String ())
280
+
261
281
// TODO(#253): Check volume capability matches for ALREADY_EXISTS
262
282
if err = validateVolumeCapability (volumeCapability ); err != nil {
263
283
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("VolumeCapabilities is invalid: %v" , err ))
@@ -343,6 +363,11 @@ func (gceCS *GCEControllerServer) ControllerUnpublishVolume(ctx context.Context,
343
363
return nil , err
344
364
}
345
365
366
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
367
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
368
+ }
369
+ defer gceCS .volumes .Delete (volKey .String ())
370
+
346
371
instanceZone , instanceName , err := common .NodeIDToZoneAndName (nodeID )
347
372
if err != nil {
348
373
return nil , status .Error (codes .InvalidArgument , fmt .Sprintf ("could not split nodeID: %v" , err ))
@@ -389,6 +414,12 @@ func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context
389
414
if err != nil {
390
415
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Volume ID is of improper format, got %v" , volumeID ))
391
416
}
417
+
418
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
419
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
420
+ }
421
+ defer gceCS .volumes .Delete (volKey .String ())
422
+
392
423
_ , err = gceCS .CloudProvider .GetDisk (ctx , volKey )
393
424
if err != nil {
394
425
if gce .IsGCEError (err , "notFound" ) {
@@ -496,6 +527,11 @@ func (gceCS *GCEControllerServer) CreateSnapshot(ctx context.Context, req *csi.C
496
527
return nil , status .Error (codes .NotFound , fmt .Sprintf ("Could not find volume with ID %v: %v" , volumeID , err ))
497
528
}
498
529
530
+ if _ , alreadyExists := gceCS .volumes .LoadOrStore (volKey .String (), true ); alreadyExists {
531
+ return nil , status .Error (codes .Aborted , fmt .Sprintf ("An operation with the given Volume Key %s already exists" , volKey .String ()))
532
+ }
533
+ defer gceCS .volumes .Delete (volKey .String ())
534
+
499
535
// Check if snapshot already exists
500
536
var snapshot * compute.Snapshot
501
537
snapshot , err = gceCS .CloudProvider .GetSnapshot (ctx , req .Name )
0 commit comments