Skip to content

Commit b57e29e

Browse files
authored
Merge pull request #303 from andyzhangx/ensureMountPoint-fix
fix: should skip and return success if mount point is already mounted
2 parents a87052f + 2d1c797 commit b57e29e

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

pkg/blob/nodeserver.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func (d *Driver) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolu
4545
if req.GetVolumeCapability() == nil {
4646
return nil, status.Error(codes.InvalidArgument, "Volume capability missing in request")
4747
}
48+
volumeID := req.GetVolumeId()
4849
if len(req.GetVolumeId()) == 0 {
4950
return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request")
5051
}
@@ -64,18 +65,23 @@ func (d *Driver) NodePublishVolume(ctx context.Context, req *csi.NodePublishVolu
6465
mountOptions = append(mountOptions, "ro")
6566
}
6667

67-
if err := d.ensureMountPoint(target); err != nil {
68+
mnt, err := d.ensureMountPoint(target)
69+
if err != nil {
6870
return nil, status.Errorf(codes.Internal, "Could not mount target %q: %v", target, err)
6971
}
72+
if mnt {
73+
klog.V(2).Infof("NodePublishVolume: volume %s is already mounted on %s", volumeID, target)
74+
return &csi.NodePublishVolumeResponse{}, nil
75+
}
7076

71-
klog.V(2).Infof("NodePublishVolume: mounting %s at %s with mountOptions: %v", source, target, mountOptions)
77+
klog.V(2).Infof("NodePublishVolume: volume %s mounting %s at %s with mountOptions: %v", volumeID, source, target, mountOptions)
7278
if err := d.mounter.Mount(source, target, "", mountOptions); err != nil {
7379
if removeErr := os.Remove(target); removeErr != nil {
7480
return nil, status.Errorf(codes.Internal, "Could not remove mount target %q: %v", target, removeErr)
7581
}
7682
return nil, status.Errorf(codes.Internal, "Could not mount %q at %q: %v", source, target, err)
7783
}
78-
klog.V(2).Infof("NodePublishVolume: mount %s at %s successfully", source, target)
84+
klog.V(2).Infof("NodePublishVolume: volume %s mount %s at %s successfully", volumeID, source, target)
7985

8086
return &csi.NodePublishVolumeResponse{}, nil
8187
}
@@ -103,7 +109,8 @@ func (d *Driver) NodeUnpublishVolume(ctx context.Context, req *csi.NodeUnpublish
103109

104110
// NodeStageVolume mount the volume to a staging path
105111
func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRequest) (*csi.NodeStageVolumeResponse, error) {
106-
if len(req.GetVolumeId()) == 0 {
112+
volumeID := req.GetVolumeId()
113+
if len(volumeID) == 0 {
107114
return nil, status.Error(codes.InvalidArgument, "Volume ID missing in request")
108115
}
109116
targetPath := req.GetStagingTargetPath()
@@ -115,11 +122,15 @@ func (d *Driver) NodeStageVolume(ctx context.Context, req *csi.NodeStageVolumeRe
115122
return nil, status.Error(codes.InvalidArgument, "Volume capability not provided")
116123
}
117124

118-
if err := d.ensureMountPoint(targetPath); err != nil {
125+
mnt, err := d.ensureMountPoint(targetPath)
126+
if err != nil {
119127
return nil, status.Errorf(codes.Internal, "Could not mount target %q: %v", targetPath, err)
120128
}
129+
if mnt {
130+
klog.V(2).Infof("NodeStageVolume: volume %s is already mounted on %s", volumeID, targetPath)
131+
return &csi.NodeStageVolumeResponse{}, nil
132+
}
121133

122-
volumeID := req.GetVolumeId()
123134
mountFlags := req.GetVolumeCapability().GetMount().GetMountFlags()
124135
attrib := req.GetVolumeContext()
125136
secrets := req.GetSecrets()
@@ -228,12 +239,12 @@ func (d *Driver) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstageVolu
228239
return nil, status.Error(codes.InvalidArgument, "Staging target not provided")
229240
}
230241

231-
klog.V(2).Infof("NodeUnstageVolume: unmounting %s", stagingTargetPath)
242+
klog.V(2).Infof("NodeUnstageVolume: volume %s unmounting on %s", volumeID, stagingTargetPath)
232243
err := mount.CleanupMountPoint(stagingTargetPath, d.mounter, false)
233244
if err != nil {
234245
return nil, status.Errorf(codes.Internal, "failed to unmount staing target %q: %v", stagingTargetPath, err)
235246
}
236-
klog.V(2).Infof("NodeUnstageVolume: unmount %s successfully", stagingTargetPath)
247+
klog.V(2).Infof("NodeUnstageVolume: volume %s unmount on %s successfully", volumeID, stagingTargetPath)
237248

238249
return &csi.NodeUnstageVolumeResponse{}, nil
239250
}
@@ -324,14 +335,15 @@ func (d *Driver) NodeExpandVolume(ctx context.Context, req *csi.NodeExpandVolume
324335
}
325336

326337
// ensureMountPoint: create mount point if not exists
327-
func (d *Driver) ensureMountPoint(target string) error {
338+
// return <true, nil> if it's already a mounted point otherwise return <false, nil>
339+
func (d *Driver) ensureMountPoint(target string) (bool, error) {
328340
notMnt, err := d.mounter.IsLikelyNotMountPoint(target)
329341
if err != nil && !os.IsNotExist(err) {
330342
if IsCorruptedDir(target) {
331343
notMnt = false
332344
klog.Warningf("detected corrupted mount for targetPath [%s]", target)
333345
} else {
334-
return err
346+
return !notMnt, err
335347
}
336348
}
337349

@@ -340,21 +352,20 @@ func (d *Driver) ensureMountPoint(target string) error {
340352
_, err := ioutil.ReadDir(target)
341353
if err == nil {
342354
klog.V(2).Infof("already mounted to target %s", target)
343-
return nil
355+
return !notMnt, nil
344356
}
345357
// mount link is invalid, now unmount and remount later
346358
klog.Warningf("ReadDir %s failed with %v, unmount this directory", target, err)
347359
if err := d.mounter.Unmount(target); err != nil {
348360
klog.Errorf("Unmount directory %s failed with %v", target, err)
349-
return err
361+
return !notMnt, err
350362
}
351-
// notMnt = true
363+
notMnt = true
364+
return !notMnt, err
352365
}
353-
354366
if err := volumehelper.MakeDir(target); err != nil {
355367
klog.Errorf("MakeDir failed on target: %s (%v)", target, err)
356-
return err
368+
return !notMnt, err
357369
}
358-
359-
return nil
370+
return !notMnt, nil
360371
}

pkg/blob/nodeserver_test.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ func TestNodeGetCapabilities(t *testing.T) {
7373
func TestEnsureMountPoint(t *testing.T) {
7474
errorTarget := "./error_is_likely_target"
7575
alreadyExistTarget := "./false_is_likely_exist_target"
76-
azureunit := "./azure.go"
76+
falseTarget := "./false_is_likely_target"
77+
azureFile := "./azure.go"
7778

7879
tests := []struct {
7980
desc string
@@ -85,9 +86,14 @@ func TestEnsureMountPoint(t *testing.T) {
8586
target: errorTarget,
8687
expectedErr: fmt.Errorf("fake IsLikelyNotMountPoint: fake error"),
8788
},
89+
{
90+
desc: "[Error] Error opening file",
91+
target: falseTarget,
92+
expectedErr: &os.PathError{Op: "open", Path: "./false_is_likely_target", Err: syscall.ENOENT},
93+
},
8894
{
8995
desc: "[Error] Not a directory",
90-
target: azureunit,
96+
target: azureFile,
9197
expectedErr: &os.PathError{Op: "mkdir", Path: "./azure.go", Err: syscall.ENOTDIR},
9298
},
9399
{
@@ -106,14 +112,16 @@ func TestEnsureMountPoint(t *testing.T) {
106112
_ = makeDir(alreadyExistTarget)
107113
d := NewFakeDriver()
108114
fakeMounter := &fakeMounter{}
115+
fakeExec := &testingexec.FakeExec{ExactOrder: true}
109116
d.mounter = &mount.SafeFormatAndMount{
110117
Interface: fakeMounter,
118+
Exec: fakeExec,
111119
}
112120

113121
for _, test := range tests {
114-
err := d.ensureMountPoint(test.target)
122+
_, err := d.ensureMountPoint(test.target)
115123
if !reflect.DeepEqual(err, test.expectedErr) {
116-
t.Errorf("desc: %s\n actualErr: (%v), expectedErr: (%v)", test.desc, err, test.expectedErr)
124+
t.Errorf("[%s]: Unexpected Error: %v, expected error: %v", test.desc, err, test.expectedErr)
117125
}
118126
}
119127

0 commit comments

Comments
 (0)