watchdog: add support for systemd watchdog
Add interfaces and handling for systemd watchdog petting.
Systemd service files can specify a watchdog timeout and systemd will
expect the application to periodically poke a software watchdog, or
else the service will be restarted. This is enabled with the
'WatchdogSec=' service file directive. Add primitives for
interacting with the watchdog APIs.
Enable automatic support in the `async::context` for this watchdog
handling, such that if the watchdog is required (by checking
sd_watchdog_enabled) the daemon will automatically pet at the
appropriate rate, assuming that the `async::context` is functioning
correctly.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I68caf7b2c7166ca402b07ecee3db65f75365aa72
diff --git a/src/async/context.cpp b/src/async/context.cpp
index 3381cb3..d4ec5e9 100644
--- a/src/async/context.cpp
+++ b/src/async/context.cpp
@@ -1,6 +1,8 @@
#include <systemd/sd-bus.h>
#include <sdbusplus/async/context.hpp>
+#include <sdbusplus/async/task.hpp>
+#include <sdbusplus/async/timer.hpp>
#include <chrono>
@@ -146,8 +148,29 @@
}
}
+static auto watchdog_loop(sdbusplus::async::context& ctx) -> task<>
+{
+ auto watchdog_time =
+ std::chrono::microseconds(ctx.get_bus().watchdog_enabled());
+ if (watchdog_time.count() == 0)
+ {
+ co_return;
+ }
+
+ // Recommended interval is half of WATCHDOG_USEC
+ watchdog_time /= 2;
+
+ while (!ctx.stop_requested())
+ {
+ ctx.get_bus().watchdog_pet();
+ co_await sleep_for(ctx, watchdog_time);
+ }
+}
+
void context::worker_run()
{
+ internal_tasks.spawn(watchdog_loop(*this));
+
// Start the sdbus 'wait/process' loop; treat it as an internal task.
internal_tasks.spawn(details::wait_process_completion::loop(*this));