[systemd-devel] [PATCH 3/3] manager: add a global watchdog reboot timestamp
Michael Olbrich
m.olbrich at pengutronix.de
Fri Nov 4 07:38:42 PDT 2011
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.
---
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 7b68156..227755b 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(×tamp) || ((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;
@@ -506,6 +543,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
{ "org.freedesktop.systemd1.Manager", "StartupTimestampMonotonic", bus_property_append_uint64, "t", &m->startup_timestamp.monotonic },
{ "org.freedesktop.systemd1.Manager", "FinishTimestamp", bus_property_append_uint64, "t", &m->finish_timestamp.realtime },
{ "org.freedesktop.systemd1.Manager", "FinishTimestampMonotonic", bus_property_append_uint64, "t",&m->finish_timestamp.monotonic },
+ { "org.freedesktop.systemd1.Manager", "WatchdogRebootTimestamp", bus_manager_append_watchdog, "t", m },
+ { "org.freedesktop.systemd1.Manager", "WatchdogRebootTimestampMonotonic", bus_manager_append_watchdog, "t", m },
{ "org.freedesktop.systemd1.Manager", "LogLevel", bus_manager_append_log_level, "s", m, bus_manager_set_log_level },
{ "org.freedesktop.systemd1.Manager", "LogTarget", bus_manager_append_log_target, "s", m, bus_manager_set_log_target },
{ "org.freedesktop.systemd1.Manager", "NNames", bus_manager_append_n_names, "u", m },
--
1.7.7
More information about the systemd-devel
mailing list