@@ -26,6 +26,7 @@ import (
26
26
"github.com/container-storage-interface/spec/lib/go/csi"
27
27
"github.com/ppc64le-cloud/powervs-csi-driver/pkg/cloud"
28
28
"github.com/ppc64le-cloud/powervs-csi-driver/pkg/fibrechannel"
29
+ "github.com/ppc64le-cloud/powervs-csi-driver/pkg/util"
29
30
"google.golang.org/grpc/codes"
30
31
"google.golang.org/grpc/status"
31
32
"k8s.io/klog/v2"
@@ -64,6 +65,7 @@ type nodeService struct {
64
65
mounter Mounter
65
66
driverOptions * Options
66
67
pvmInstanceId string
68
+ volumeLocks * util.VolumeLocks
67
69
}
68
70
69
71
// newNodeService creates a new node service
@@ -85,6 +87,7 @@ func newNodeService(driverOptions *Options) nodeService {
85
87
mounter : newNodeMounter (),
86
88
driverOptions : driverOptions ,
87
89
pvmInstanceId : metadata .GetPvmInstanceId (),
90
+ volumeLocks : util .NewVolumeLocks (),
88
91
}
89
92
}
90
93
@@ -96,6 +99,11 @@ func (d *nodeService) NodeStageVolume(ctx context.Context, req *csi.NodeStageVol
96
99
return nil , status .Error (codes .InvalidArgument , "Volume ID not provided" )
97
100
}
98
101
102
+ if acquired := d .volumeLocks .TryAcquire (volumeID ); ! acquired {
103
+ return nil , status .Errorf (codes .Aborted , util .VolumeOperationAlreadyExistsFmt , volumeID )
104
+ }
105
+ defer d .volumeLocks .Release (volumeID )
106
+
99
107
target := req .GetStagingTargetPath ()
100
108
if len (target ) == 0 {
101
109
return nil , status .Error (codes .InvalidArgument , "Staging target not provided" )
@@ -195,6 +203,11 @@ func (d *nodeService) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
195
203
return nil , status .Error (codes .InvalidArgument , "Volume ID not provided" )
196
204
}
197
205
206
+ if acquired := d .volumeLocks .TryAcquire (volumeID ); ! acquired {
207
+ return nil , status .Errorf (codes .Aborted , util .VolumeOperationAlreadyExistsFmt , volumeID )
208
+ }
209
+ defer d .volumeLocks .Release (volumeID )
210
+
198
211
target := req .GetStagingTargetPath ()
199
212
if len (target ) == 0 {
200
213
return nil , status .Error (codes .InvalidArgument , "Staging target not provided" )
@@ -254,6 +267,11 @@ func (d *nodeService) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandV
254
267
return nil , status .Error (codes .InvalidArgument , "Volume ID not provided" )
255
268
}
256
269
270
+ if acquired := d .volumeLocks .TryAcquire (volumeID ); ! acquired {
271
+ return nil , status .Errorf (codes .Aborted , util .VolumeOperationAlreadyExistsFmt , volumeID )
272
+ }
273
+ defer d .volumeLocks .Release (volumeID )
274
+
257
275
args := []string {"-o" , "source" , "--noheadings" , "--target" , req .GetVolumePath ()}
258
276
output , err := d .mounter .Command ("findmnt" , args ... ).Output ()
259
277
if err != nil {
@@ -294,6 +312,12 @@ func (d *nodeService) NodePublishVolume(ctx context.Context, req *csi.NodePublis
294
312
return nil , status .Error (codes .InvalidArgument , "Target path not provided" )
295
313
}
296
314
315
+ // Acquire a lock on the target path instead of volumeID, since we do not want to serialize multiple node publish calls on the same volume.
316
+ if acquired := d .volumeLocks .TryAcquire (target ); ! acquired {
317
+ return nil , status .Errorf (codes .Aborted , util .VolumeOperationAlreadyExistsFmt , target )
318
+ }
319
+ defer d .volumeLocks .Release (target )
320
+
297
321
volCap := req .GetVolumeCapability ()
298
322
if volCap == nil {
299
323
return nil , status .Error (codes .InvalidArgument , "Volume capability not provided" )
@@ -334,6 +358,12 @@ func (d *nodeService) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpu
334
358
return nil , status .Error (codes .InvalidArgument , "Target path not provided" )
335
359
}
336
360
361
+ // Acquire a lock on the target path instead of volumeID, since we do not want to serialize multiple node publish calls on the same volume.
362
+ if acquired := d .volumeLocks .TryAcquire (target ); ! acquired {
363
+ return nil , status .Errorf (codes .Aborted , util .VolumeOperationAlreadyExistsFmt , target )
364
+ }
365
+ defer d .volumeLocks .Release (target )
366
+
337
367
klog .V (5 ).Infof ("NodeUnpublishVolume: unmounting %s" , target )
338
368
err := d .mounter .Unmount (target )
339
369
if err != nil {
0 commit comments