From b9854af690195b3eeadeba11272304be4623c4f8 Mon Sep 17 00:00:00 2001 From: Manolo van Ee Date: Wed, 4 Sep 2024 15:05:23 +0200 Subject: [PATCH] Get watchdog configuration from systemd --- Sources/Systemd/SystemdHelpers.swift | 23 +++++++++++++++++++ Sources/SystemdLifecycle/SystemdService.swift | 16 +++++-------- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/Sources/Systemd/SystemdHelpers.swift b/Sources/Systemd/SystemdHelpers.swift index ec60a84..6b7724c 100644 --- a/Sources/Systemd/SystemdHelpers.swift +++ b/Sources/Systemd/SystemdHelpers.swift @@ -1,12 +1,17 @@ #if os(Linux) import Glibc +import CSystemd #endif import Foundation public struct SystemdHelpers { public static let isSystemdService: Bool = getIsSystemdService() + public static let watchdogTimeout: Duration? = getWatchdogTimeout() + + public static var watchdogEnabled: Bool { watchdogTimeout != nil } + public static var watchdogRecommendedNotifyInterval: Duration? { watchdogTimeout.map { $0 / 2 } } private static func getIsSystemdService() -> Bool { #if os(Linux) @@ -22,4 +27,22 @@ public struct SystemdHelpers { return false } + + private static func getWatchdogTimeout() -> Duration? { + #if os(Linux) + var usec: UInt64 = 0 + let ret = sd_watchdog_enabled(0, &usec) + if ret > 0 { + return .microseconds(usec) + } else if ret == 0 { + return nil // Watchdog disabled + } else { + let error = String(cString: strerror(-ret)) + print("Unable to get watchdog configuration: \(error)") + return nil + } + #else + return nil + #endif + } } diff --git a/Sources/SystemdLifecycle/SystemdService.swift b/Sources/SystemdLifecycle/SystemdService.swift index 91b8174..41a5b2e 100644 --- a/Sources/SystemdLifecycle/SystemdService.swift +++ b/Sources/SystemdLifecycle/SystemdService.swift @@ -4,14 +4,7 @@ import ServiceLifecycle import Systemd public struct SystemdService: Service { - private let _watchdogEnabled: Bool - private let _watchdogInterval: Duration - - public init(watchdogEnabled: Bool = false, - watchdogInterval: Duration = .seconds(5)) { - _watchdogEnabled = watchdogEnabled - _watchdogInterval = watchdogInterval - } + public init() {} public func run() async throws { let notifier = SystemdNotifier() @@ -19,9 +12,12 @@ public struct SystemdService: Service { // Send ready signal at startup notifier.notify(ServiceState.Ready) + // Run the task until cancelled - for await _ in AsyncTimerSequence(interval: _watchdogInterval, clock: .continuous).cancelOnGracefulShutdown() { - if _watchdogEnabled { + let watchdogEnabled = SystemdHelpers.watchdogEnabled + let interval = SystemdHelpers.watchdogRecommendedNotifyInterval ?? .seconds(3600) + for await _ in AsyncTimerSequence(interval: interval, clock: .continuous).cancelOnGracefulShutdown() { + if watchdogEnabled { notifier.notify(ServiceState.Watchdog) } }