From 96dde03408ca27148417a72fd14692ff94cc88ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81ngel=20P=C3=A9rez?= Date: Tue, 3 Sep 2024 16:59:29 +0200 Subject: [PATCH] feat(daemon): introduce "external" reboot mode This reboot mode ensures that the machine is not restarted during daemon.Stop() when a restart has been requested. Instead, it signals the daemon.Stop() caller that further actions to ensure a restart are required through a new exported error daemon.ErrRestartExternal. This is required in scenarios where further actions are required before the machine can be safely rebooted, such as syncing and unmounting filesystems. --- internals/daemon/daemon.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internals/daemon/daemon.go b/internals/daemon/daemon.go index b39c1797..4c551dac 100644 --- a/internals/daemon/daemon.go +++ b/internals/daemon/daemon.go @@ -52,6 +52,7 @@ var ( ErrRestartSocket = fmt.Errorf("daemon stop requested to wait for socket activation") ErrRestartServiceFailure = fmt.Errorf("daemon stop requested due to service failure") ErrRestartCheckFailure = fmt.Errorf("daemon stop requested due to check failure") + ErrRestartExternal = fmt.Errorf("daemon stop requested due to reboot handled externally") systemdSdNotify = systemd.SdNotify sysGetuid = sys.Getuid @@ -711,6 +712,8 @@ const ( SystemdMode RebootMode = iota + 1 // Reboot uses direct kernel syscalls SyscallMode + // Reboot is handled externally after the daemon stops + ExternalMode ) // SetRebootMode configures how the system issues a reboot. The default @@ -722,6 +725,8 @@ func SetRebootMode(mode RebootMode) { rebootHandler = systemdModeReboot case SyscallMode: rebootHandler = syscallModeReboot + case ExternalMode: + rebootHandler = externalModeReboot default: panic(fmt.Sprintf("unsupported reboot mode %v", mode)) } @@ -773,6 +778,13 @@ func syscallModeReboot(rebootDelay time.Duration) error { return nil } +func externalModeReboot(rebootDelay time.Duration) error { + if rebootDelay > 0 { + time.Sleep(rebootDelay) + } + return ErrRestartExternal +} + func (d *Daemon) Dying() <-chan struct{} { return d.tomb.Dying() }