[systemd-devel] [PATCH v3 3/4] manager: add a global watchdog reboot timestamp

Michael Olbrich m.olbrich at pengutronix.de
Wed Feb 1 08:17:14 PST 2012


This patch adds WatchdogRebootTimestamp[Monotonic] to the systemd
manager API. It contains the earliest point in time when systemd might
reboot the system because the timer for WatchdogRebootUSec for a
service expired.
If we assume the system takes Xus to shut down then
WatchdogRebootTimestamp + Xus should never be in the past. A watchdog
daemon handling the hardware watchdog can use this information to
determine when to let the hardware watchdog restart the system.
This is convenience information for a watchdog daemon. With this the
it can avoid a lot of D-Bus calls that are necessary to calculate the
same value.
---
changes in v2:
 - adapt to changes from "d200735 dbus: more efficient implementation of properties"

 src/dbus-manager.c |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 6d272cb..d49e947 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -223,6 +223,8 @@
         "  <property name=\"StartupTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
         "  <property name=\"FinishTimestamp\" type=\"t\" access=\"read\"/>\n" \
         "  <property name=\"FinishTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WatchdogRebootTimestamp\" type=\"t\" access=\"read\"/>\n" \
+        "  <property name=\"WatchdogRebootTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \
         "  <property name=\"LogLevel\" type=\"s\" access=\"readwrite\"/>\n"  \
         "  <property name=\"LogTarget\" type=\"s\" access=\"readwrite\"/>\n" \
         "  <property name=\"NNames\" type=\"u\" access=\"read\"/>\n"    \
@@ -310,6 +312,41 @@ static int bus_manager_append_tainted(DBusMessageIter *i, const char *property,
         return 0;
 }
 
+static int bus_manager_append_watchdog(DBusMessageIter *i, const char *property, void *data) {
+        Iterator iter;
+        Unit *u;
+        Service *s;
+        const char *k;
+        uint64_t value;
+        dual_timestamp timestamp = {0, 0};
+        Manager *m = data;
+
+        assert(i);
+        assert(property);
+        assert(m);
+
+        HASHMAP_FOREACH_KEY(u, k, m->units, iter) {
+                if (!(s = SERVICE(u)))
+                        continue;
+                if (!dual_timestamp_is_set(&s->watchdog_timestamp))
+                        continue;
+                if (!dual_timestamp_is_set(&timestamp) || ((s->watchdog_timestamp.monotonic + s->watchdog_reboot_usec) < timestamp.monotonic)) {
+                        timestamp.monotonic = s->watchdog_timestamp.monotonic + s->watchdog_reboot_usec;
+                        timestamp.realtime = s->watchdog_timestamp.realtime + s->watchdog_reboot_usec;
+                }
+        }
+
+        if (strcmp(property, "WatchdogRebootTimestamp") == 0)
+                value = timestamp.realtime;
+        else
+                value = timestamp.monotonic;
+
+        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &value))
+                return -ENOMEM;
+
+        return 0;
+}
+
 static int bus_manager_append_log_target(DBusMessageIter *i, const char *property, void *data) {
         const char *t;
 
@@ -509,6 +546,8 @@ static const BusProperty bus_manager_properties[] = {
         { "StartupTimestampMonotonic", bus_property_append_uint64, "t", offsetof(Manager, startup_timestamp.monotonic) },
         { "FinishTimestamp", bus_property_append_uint64,           "t", offsetof(Manager, finish_timestamp.realtime)   },
         { "FinishTimestampMonotonic", bus_property_append_uint64,  "t", offsetof(Manager, finish_timestamp.monotonic)  },
+        { "WatchdogRebootTimestamp", bus_manager_append_watchdog,  "t", 0 },
+        { "WatchdogRebootTimestampMonotonic", bus_manager_append_watchdog, "t", 0 },
         { "LogLevel",      bus_manager_append_log_level,           "s", 0,                                             0, bus_manager_set_log_level },
         { "LogTarget",     bus_manager_append_log_target,          "s", 0,                                             0, bus_manager_set_log_target },
         { "NNames",        bus_manager_append_n_names,             "u", 0 },
-- 
1.7.7.3



More information about the systemd-devel mailing list