mirror of
https://github.com/rclone/rclone.git
synced 2025-11-23 21:44:49 +02:00
vfs: fix SIGHUP killing serve instead of flushing directory caches
Before, rclone serve would crash when sent a SIGHUP which contradicts the documentation - saying it should flush the directory caches. Moved signal handling from the mount into the vfs layer, which now handles SIGHUP on all uses of the VFS including mount and serve. Fixes #8607
This commit is contained in:
@@ -403,27 +403,7 @@ func (m *MountPoint) Wait() error {
|
||||
fnHandle := atexit.Register(finalise)
|
||||
defer atexit.Unregister(fnHandle)
|
||||
|
||||
// Reload VFS cache on SIGHUP
|
||||
sigHup := make(chan os.Signal, 1)
|
||||
NotifyOnSigHup(sigHup)
|
||||
var err error
|
||||
|
||||
waiting := true
|
||||
for waiting {
|
||||
select {
|
||||
// umount triggered outside the app
|
||||
case err = <-m.ErrChan:
|
||||
waiting = false
|
||||
// user sent SIGHUP to clear the cache
|
||||
case <-sigHup:
|
||||
root, err := m.VFS.Root()
|
||||
if err != nil {
|
||||
fs.Errorf(m.VFS.Fs(), "Error reading root: %v", err)
|
||||
} else {
|
||||
root.ForgetAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
err := <-m.ErrChan
|
||||
|
||||
finalise()
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ func NewDriver(ctx context.Context, root string, mntOpt *mountlib.Options, vfsOp
|
||||
// start mount monitoring
|
||||
drv.hupChan = make(chan os.Signal, 1)
|
||||
drv.monChan = make(chan bool, 1)
|
||||
mountlib.NotifyOnSigHup(drv.hupChan)
|
||||
go drv.monitor()
|
||||
|
||||
// unmount all volumes on exit
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build !plan9 && !js
|
||||
|
||||
package mountlib
|
||||
package vfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
@@ -1,6 +1,6 @@
|
||||
//go:build plan9 || js
|
||||
|
||||
package mountlib
|
||||
package vfs
|
||||
|
||||
import (
|
||||
"os"
|
||||
32
vfs/vfs.go
32
vfs/vfs.go
@@ -179,6 +179,7 @@ type VFS struct {
|
||||
root *Dir
|
||||
Opt vfscommon.Options
|
||||
cache *vfscache.Cache
|
||||
cancel context.CancelFunc
|
||||
cancelCache context.CancelFunc
|
||||
usageMu sync.Mutex
|
||||
usageTime time.Time
|
||||
@@ -197,8 +198,10 @@ var (
|
||||
// DefaultOpt will be used
|
||||
func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
||||
fsDir := fs.NewDir("", time.Now())
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
vfs := &VFS{
|
||||
f: f,
|
||||
f: f,
|
||||
cancel: cancel,
|
||||
}
|
||||
vfs.inUse.Store(1)
|
||||
|
||||
@@ -259,6 +262,9 @@ func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
||||
go vfs.refresh()
|
||||
}
|
||||
|
||||
// Handle supported signals
|
||||
go vfs.signalHandler(ctx)
|
||||
|
||||
// This can take some time so do it after the Pin
|
||||
vfs.SetCacheMode(vfs.Opt.CacheMode)
|
||||
|
||||
@@ -274,6 +280,27 @@ func (vfs *VFS) refresh() {
|
||||
}
|
||||
}
|
||||
|
||||
// Reload VFS cache on SIGHUP
|
||||
func (vfs *VFS) signalHandler(ctx context.Context) {
|
||||
sigHup := make(chan os.Signal, 1)
|
||||
NotifyOnSigHup(sigHup)
|
||||
|
||||
waiting := true
|
||||
for waiting {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
waiting = false
|
||||
case <-sigHup:
|
||||
root, err := vfs.Root()
|
||||
if err != nil {
|
||||
fs.Errorf(vfs.Fs(), "Error reading root: %v", err)
|
||||
} else {
|
||||
root.ForgetAll()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stats returns info about the VFS
|
||||
func (vfs *VFS) Stats() (out rc.Params) {
|
||||
out = make(rc.Params)
|
||||
@@ -372,6 +399,9 @@ func (vfs *VFS) Shutdown() {
|
||||
close(vfs.pollChan)
|
||||
vfs.pollChan = nil
|
||||
}
|
||||
|
||||
// Cancel any background go routines
|
||||
vfs.cancel()
|
||||
}
|
||||
|
||||
// CleanUp deletes the contents of the on disk cache
|
||||
|
||||
Reference in New Issue
Block a user