nfsmount: fix exit after external unmount #7503
Before this change, if a user unmounted externally (for example, via the Finder UI), rclone would not be aware of this and wait forever to exit -- effectively causing a deadlock that would require Ctrl+C to terminate. After this change, when the handler detects an external unmount, it calls a function which allows rclone to cleanly shutdown the VFS and exit.
This commit is contained in:
parent
5638a3841f
commit
0e2f1d64e3
3 changed files with 32 additions and 4 deletions
|
@ -81,6 +81,9 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (asyncerrors
|
||||||
}
|
}
|
||||||
asyncerrors = errChan
|
asyncerrors = errChan
|
||||||
unmount = func() error {
|
unmount = func() error {
|
||||||
|
if s.UnmountedExternally {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
var umountErr error
|
var umountErr error
|
||||||
var out []byte
|
var out []byte
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
|
@ -98,5 +101,12 @@ func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (asyncerrors
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nfs.OnUnmountFunc = func() {
|
||||||
|
s.UnmountedExternally = true
|
||||||
|
errChan <- nil
|
||||||
|
VFS.Shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/go-git/go-billy/v5"
|
"github.com/go-git/go-billy/v5"
|
||||||
"github.com/rclone/rclone/fs"
|
"github.com/rclone/rclone/fs"
|
||||||
|
@ -100,6 +101,16 @@ func (o *Options) Limit() int {
|
||||||
return o.HandleLimit
|
return o.HandleLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnUnmountFunc registers a function to call when externally unmounted
|
||||||
|
var OnUnmountFunc func()
|
||||||
|
|
||||||
|
func onUnmount() {
|
||||||
|
fs.Infof(nil, "unmount detected")
|
||||||
|
if OnUnmountFunc != nil {
|
||||||
|
OnUnmountFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// LogIntercepter intercepts noisy go-nfs logs and reroutes them to DEBUG
|
// LogIntercepter intercepts noisy go-nfs logs and reroutes them to DEBUG
|
||||||
type LogIntercepter struct {
|
type LogIntercepter struct {
|
||||||
Level nfs.LogLevel
|
Level nfs.LogLevel
|
||||||
|
@ -114,6 +125,12 @@ func (l *LogIntercepter) Intercept(args ...interface{}) {
|
||||||
|
|
||||||
// Interceptf intercepts go-nfs logs and calls fs.Debugf instead
|
// Interceptf intercepts go-nfs logs and calls fs.Debugf instead
|
||||||
func (l *LogIntercepter) Interceptf(format string, args ...interface{}) {
|
func (l *LogIntercepter) Interceptf(format string, args ...interface{}) {
|
||||||
|
argsS := fmt.Sprint(args...)
|
||||||
|
// bit of a workaround... the real fix is probably https://github.com/willscott/go-nfs/pull/28
|
||||||
|
if strings.Contains(argsS, "mount.Umnt") {
|
||||||
|
onUnmount()
|
||||||
|
}
|
||||||
|
|
||||||
fs.Debugf(nil, "[NFS DEBUG] "+format, args...)
|
fs.Debugf(nil, "[NFS DEBUG] "+format, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,11 @@ import (
|
||||||
|
|
||||||
// Server contains everything to run the Server
|
// Server contains everything to run the Server
|
||||||
type Server struct {
|
type Server struct {
|
||||||
opt Options
|
opt Options
|
||||||
handler nfs.Handler
|
handler nfs.Handler
|
||||||
ctx context.Context // for global config
|
ctx context.Context // for global config
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
|
UnmountedExternally bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new server
|
// NewServer creates a new server
|
||||||
|
|
Loading…
Reference in a new issue