2023-09-04 23:32:04 +08:00
|
|
|
package systemd
|
|
|
|
|
|
|
|
import (
|
2023-11-29 17:25:30 +08:00
|
|
|
"fmt"
|
2023-09-04 23:32:04 +08:00
|
|
|
"sync"
|
|
|
|
|
2023-11-29 17:25:30 +08:00
|
|
|
"github.com/coreos/go-systemd/v22/daemon"
|
2024-08-18 22:58:35 +08:00
|
|
|
"github.com/rclone/rclone/fs"
|
2023-09-04 23:32:04 +08:00
|
|
|
"github.com/rclone/rclone/lib/atexit"
|
|
|
|
)
|
|
|
|
|
2024-07-16 04:41:51 +08:00
|
|
|
// Notify systemd that the service is ready. This returns a
|
2023-09-04 23:32:04 +08:00
|
|
|
// 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.
|
2024-07-16 04:41:51 +08:00
|
|
|
// 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.
|
2023-09-04 23:32:04 +08:00
|
|
|
func Notify() func() {
|
2023-11-29 17:25:30 +08:00
|
|
|
if _, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil {
|
2024-08-18 22:58:35 +08:00
|
|
|
fs.Logf(nil, "failed to notify ready to systemd: %v", err)
|
2023-09-04 23:32:04 +08:00
|
|
|
}
|
|
|
|
var finaliseOnce sync.Once
|
|
|
|
finalise := func() {
|
|
|
|
finaliseOnce.Do(func() {
|
2023-11-29 17:25:30 +08:00
|
|
|
if _, err := daemon.SdNotify(false, daemon.SdNotifyStopping); err != nil {
|
2024-08-18 22:58:35 +08:00
|
|
|
fs.Logf(nil, "failed to notify stopping to systemd: %v", err)
|
2023-09-04 23:32:04 +08:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
finaliseHandle := atexit.Register(finalise)
|
|
|
|
return func() {
|
|
|
|
atexit.Unregister(finaliseHandle)
|
|
|
|
finalise()
|
|
|
|
}
|
|
|
|
}
|
2023-11-29 17:25:30 +08:00
|
|
|
|
|
|
|
// UpdateStatus updates the systemd status
|
|
|
|
func UpdateStatus(status string) error {
|
|
|
|
systemdStatus := fmt.Sprintf("STATUS=%s", status)
|
|
|
|
_, err := daemon.SdNotify(false, systemdStatus)
|
|
|
|
return err
|
|
|
|
}
|