From 14629c66f93e473420f022dc4448137368544f19 Mon Sep 17 00:00:00 2001 From: AThePeanut4 <49614525+AThePeanut4@users.noreply.github.com> Date: Mon, 15 Jul 2024 22:41:51 +0200 Subject: [PATCH] systemd: prevent unmount rc command from sending a STOPPING=1 sd-notify message This prevents an `rclone rcd` server from prematurely going into the 'deactivating' state, which was causing systemd to kill it with a SIGABRT after the stop timeout. Fixes #7540 --- cmd/mountlib/mount.go | 9 ++------- lib/systemd/notify.go | 5 ++++- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index 4a539e0f7..0e5419398 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -18,11 +18,11 @@ import ( "github.com/rclone/rclone/fs/config/flags" "github.com/rclone/rclone/lib/atexit" "github.com/rclone/rclone/lib/daemonize" + "github.com/rclone/rclone/lib/systemd" "github.com/rclone/rclone/vfs" "github.com/rclone/rclone/vfs/vfscommon" "github.com/rclone/rclone/vfs/vfsflags" - "github.com/coreos/go-systemd/v22/daemon" "github.com/spf13/cobra" "github.com/spf13/pflag" ) @@ -307,6 +307,7 @@ func NewMountCommand(commandName string, hidden bool, mount MountFn) *cobra.Comm // Wait for foreground mount, if any... if mountDaemon == nil { if err == nil { + defer systemd.Notify()() err = mnt.Wait() } if err != nil { @@ -385,7 +386,6 @@ func (m *MountPoint) Wait() error { var finaliseOnce sync.Once finalise := func() { finaliseOnce.Do(func() { - _, _ = daemon.SdNotify(false, daemon.SdNotifyStopping) // Unmount only if directory was mounted by rclone, e.g. don't unmount autofs hooks. if err := CheckMountReady(m.MountPoint); err != nil { fs.Debugf(m.MountPoint, "Unmounted externally. Just exit now.") @@ -401,11 +401,6 @@ func (m *MountPoint) Wait() error { fnHandle := atexit.Register(finalise) defer atexit.Unregister(fnHandle) - // Notify systemd - if _, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil { - return fmt.Errorf("failed to notify systemd: %w", err) - } - // Reload VFS cache on SIGHUP sigHup := make(chan os.Signal, 1) NotifyOnSigHup(sigHup) diff --git a/lib/systemd/notify.go b/lib/systemd/notify.go index 8dccafb4f..237343147 100644 --- a/lib/systemd/notify.go +++ b/lib/systemd/notify.go @@ -9,10 +9,13 @@ import ( "github.com/rclone/rclone/lib/atexit" ) -// Notify systemd that the service is starting. This returns a +// Notify systemd that the service is ready. This returns a // function which should be called to notify that the service is // stopping. This function will be called on exit if the service exits // on a signal. +// NOTE: this function should only be called once, and so it +// should generally only be used directly in a command's Run handler. +// It should not be called as a result of rc commands. See #7540. func Notify() func() { if _, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil { log.Printf("failed to notify ready to systemd: %v", err)