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

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