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)
|
fnHandle := atexit.Register(finalise)
|
||||||
defer atexit.Unregister(fnHandle)
|
defer atexit.Unregister(fnHandle)
|
||||||
|
|
||||||
// Reload VFS cache on SIGHUP
|
err := <-m.ErrChan
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
finalise()
|
finalise()
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ func NewDriver(ctx context.Context, root string, mntOpt *mountlib.Options, vfsOp
|
|||||||
// start mount monitoring
|
// start mount monitoring
|
||||||
drv.hupChan = make(chan os.Signal, 1)
|
drv.hupChan = make(chan os.Signal, 1)
|
||||||
drv.monChan = make(chan bool, 1)
|
drv.monChan = make(chan bool, 1)
|
||||||
mountlib.NotifyOnSigHup(drv.hupChan)
|
|
||||||
go drv.monitor()
|
go drv.monitor()
|
||||||
|
|
||||||
// unmount all volumes on exit
|
// unmount all volumes on exit
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build !plan9 && !js
|
//go:build !plan9 && !js
|
||||||
|
|
||||||
package mountlib
|
package vfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
//go:build plan9 || js
|
//go:build plan9 || js
|
||||||
|
|
||||||
package mountlib
|
package vfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
32
vfs/vfs.go
32
vfs/vfs.go
@@ -179,6 +179,7 @@ type VFS struct {
|
|||||||
root *Dir
|
root *Dir
|
||||||
Opt vfscommon.Options
|
Opt vfscommon.Options
|
||||||
cache *vfscache.Cache
|
cache *vfscache.Cache
|
||||||
|
cancel context.CancelFunc
|
||||||
cancelCache context.CancelFunc
|
cancelCache context.CancelFunc
|
||||||
usageMu sync.Mutex
|
usageMu sync.Mutex
|
||||||
usageTime time.Time
|
usageTime time.Time
|
||||||
@@ -197,8 +198,10 @@ var (
|
|||||||
// DefaultOpt will be used
|
// DefaultOpt will be used
|
||||||
func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
||||||
fsDir := fs.NewDir("", time.Now())
|
fsDir := fs.NewDir("", time.Now())
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
vfs := &VFS{
|
vfs := &VFS{
|
||||||
f: f,
|
f: f,
|
||||||
|
cancel: cancel,
|
||||||
}
|
}
|
||||||
vfs.inUse.Store(1)
|
vfs.inUse.Store(1)
|
||||||
|
|
||||||
@@ -259,6 +262,9 @@ func New(f fs.Fs, opt *vfscommon.Options) *VFS {
|
|||||||
go vfs.refresh()
|
go vfs.refresh()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle supported signals
|
||||||
|
go vfs.signalHandler(ctx)
|
||||||
|
|
||||||
// This can take some time so do it after the Pin
|
// This can take some time so do it after the Pin
|
||||||
vfs.SetCacheMode(vfs.Opt.CacheMode)
|
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
|
// Stats returns info about the VFS
|
||||||
func (vfs *VFS) Stats() (out rc.Params) {
|
func (vfs *VFS) Stats() (out rc.Params) {
|
||||||
out = make(rc.Params)
|
out = make(rc.Params)
|
||||||
@@ -372,6 +399,9 @@ func (vfs *VFS) Shutdown() {
|
|||||||
close(vfs.pollChan)
|
close(vfs.pollChan)
|
||||||
vfs.pollChan = nil
|
vfs.pollChan = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel any background go routines
|
||||||
|
vfs.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanUp deletes the contents of the on disk cache
|
// CleanUp deletes the contents of the on disk cache
|
||||||
|
|||||||
Reference in New Issue
Block a user