1
0
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:
dougal
2025-09-01 12:14:57 +01:00
committed by Nick Craig-Wood
parent 9e200531b1
commit a4962e21d1
5 changed files with 34 additions and 25 deletions

View File

@@ -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()

View File

@@ -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

View File

@@ -1,6 +1,6 @@
//go:build !plan9 && !js
package mountlib
package vfs
import (
"os"

View File

@@ -1,6 +1,6 @@
//go:build plan9 || js
package mountlib
package vfs
import (
"os"

View File

@@ -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