Skip to content

Commit 0e85efa

Browse files
committed
add timeout on mount
1 parent 18fdc4a commit 0e85efa

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

pkg/nfs/nodeserver.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ func (ns *NodeServer) NodePublishVolume(_ context.Context, req *csi.NodePublishV
130130
}
131131

132132
klog.V(2).Infof("NodePublishVolume: volumeID(%v) source(%s) targetPath(%s) mountflags(%v)", volumeID, source, targetPath, mountOptions)
133+
execFunc := func() error {
134+
return ns.mounter.Mount(source, targetPath, "nfs", mountOptions)
135+
}
136+
timeoutFunc := func() error { return fmt.Errorf("time out") }
137+
if err := WaitUntilTimeout(90*time.Second, execFunc, timeoutFunc); err != nil {
138+
return nil, status.Error(codes.Internal, fmt.Sprintf("volume(%s) mount %q on %q failed with %v", volumeID, source, targetPath, err))
139+
}
133140
err = ns.mounter.Mount(source, targetPath, "nfs", mountOptions)
134141
if err != nil {
135142
if os.IsPermission(err) {

pkg/nfs/utils.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,30 @@ func getRootDir(path string) string {
221221
parts := strings.Split(path, "/")
222222
return parts[0]
223223
}
224+
225+
// ExecFunc returns a exec function's output and error
226+
type ExecFunc func() (err error)
227+
228+
// TimeoutFunc returns output and error if an ExecFunc timeout
229+
type TimeoutFunc func() (err error)
230+
231+
// WaitUntilTimeout waits for the exec function to complete or return timeout error
232+
func WaitUntilTimeout(timeout time.Duration, execFunc ExecFunc, timeoutFunc TimeoutFunc) error {
233+
// Create a channel to receive the result of the exec function
234+
done := make(chan bool)
235+
var err error
236+
237+
// Start the exec function in a goroutine
238+
go func() {
239+
err = execFunc()
240+
done <- true
241+
}()
242+
243+
// Wait for the function to complete or time out
244+
select {
245+
case <-done:
246+
return err
247+
case <-time.After(timeout):
248+
return timeoutFunc()
249+
}
250+
}

pkg/nfs/utils_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,55 @@ func TestGetRootPath(t *testing.T) {
428428
}
429429
}
430430
}
431+
432+
func TestWaitUntilTimeout(t *testing.T) {
433+
tests := []struct {
434+
desc string
435+
timeout time.Duration
436+
execFunc ExecFunc
437+
timeoutFunc TimeoutFunc
438+
expectedErr error
439+
}{
440+
{
441+
desc: "execFunc returns error",
442+
timeout: 1 * time.Second,
443+
execFunc: func() error {
444+
return fmt.Errorf("execFunc error")
445+
},
446+
timeoutFunc: func() error {
447+
return fmt.Errorf("timeout error")
448+
},
449+
expectedErr: fmt.Errorf("execFunc error"),
450+
},
451+
{
452+
desc: "execFunc timeout",
453+
timeout: 1 * time.Second,
454+
execFunc: func() error {
455+
time.Sleep(2 * time.Second)
456+
return nil
457+
},
458+
timeoutFunc: func() error {
459+
return fmt.Errorf("timeout error")
460+
},
461+
expectedErr: fmt.Errorf("timeout error"),
462+
},
463+
{
464+
desc: "execFunc completed successfully",
465+
timeout: 1 * time.Second,
466+
execFunc: func() error {
467+
return nil
468+
},
469+
timeoutFunc: func() error {
470+
return fmt.Errorf("timeout error")
471+
},
472+
expectedErr: nil,
473+
},
474+
}
475+
476+
for _, test := range tests {
477+
err := WaitUntilTimeout(test.timeout, test.execFunc, test.timeoutFunc)
478+
if err != nil && (err.Error() != test.expectedErr.Error()) {
479+
t.Errorf("unexpected error: %v, expected error: %v", err, test.expectedErr)
480+
}
481+
}
482+
}

0 commit comments

Comments
 (0)