Update systemd's watchdog timeout in luc-handler using WatchdogClient
authorJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Wed, 13 Jun 2012 10:07:40 +0000 (11:07 +0100)
committerJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Wed, 13 Jun 2012 10:08:59 +0000 (11:08 +0100)
WatchdogClient is a new class that takes a timeout and asks systemd to
update its watchdog timeout in regular intervals using sd_notify().

common/watchdog-client.c [new file with mode: 0644]
common/watchdog-client.h [new file with mode: 0644]
luc-handler/Makefile.am
luc-handler/main.c

diff --git a/common/watchdog-client.c b/common/watchdog-client.c
new file mode 100644 (file)
index 0000000..6645fd5
--- /dev/null
@@ -0,0 +1,184 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <systemd/sd-daemon.h>
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+#include <common/watchdog-client.h>
+
+
+
+/* property identifiers */
+enum
+{
+  PROP_0,
+  PROP_TIMEOUT,
+};
+
+
+
+static void     watchdog_client_constructed  (GObject      *object);
+static void     watchdog_client_finalize     (GObject      *object);
+static void     watchdog_client_get_property (GObject      *object,
+                                              guint         prop_id,
+                                              GValue       *value,
+                                              GParamSpec   *pspec);
+static void     watchdog_client_set_property (GObject      *object,
+                                              guint         prop_id,
+                                              const GValue *value,
+                                              GParamSpec   *pspec);
+static gboolean watchdog_client_timeout      (gpointer      user_data);
+
+
+
+struct _WatchdogClientClass
+{
+  GObjectClass __parent__;
+};
+
+struct _WatchdogClient
+{
+  GObject          __parent__;
+
+  guint            timeout;
+  guint            timeout_id;
+};
+
+
+
+G_DEFINE_TYPE (WatchdogClient, watchdog_client, G_TYPE_OBJECT);
+
+
+
+static void
+watchdog_client_class_init (WatchdogClientClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->constructed = watchdog_client_constructed;
+  gobject_class->finalize = watchdog_client_finalize;
+  gobject_class->get_property = watchdog_client_get_property;
+  gobject_class->set_property = watchdog_client_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TIMEOUT,
+                                   g_param_spec_uint ("timeout",
+                                                      "timeout",
+                                                      "timeout",
+                                                      0, G_MAXUINT, 120,
+                                                      G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT_ONLY));
+}
+
+
+
+static void
+watchdog_client_init (WatchdogClient *client)
+{
+}
+
+
+
+static void
+watchdog_client_constructed (GObject *object)
+{
+  WatchdogClient *client = WATCHDOG_CLIENT (object);
+
+  /* trigger a systemd watchdog timestap update now */
+  watchdog_client_timeout (client);
+
+  /* schedule a regular timeout to update the systemd watchdog timestamp */
+  client->timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
+                                                   client->timeout,
+                                                   watchdog_client_timeout,
+                                                   g_object_ref (client),
+                                                   (GDestroyNotify) g_object_unref);
+}
+
+
+
+static void
+watchdog_client_finalize (GObject *object)
+{
+  WatchdogClient *client = WATCHDOG_CLIENT (object);
+
+  /* drop the watchdog timeout */
+  if (client->timeout_id > 0)
+    g_source_remove (client->timeout_id);
+
+  (*G_OBJECT_CLASS (watchdog_client_parent_class)->finalize) (object);
+}
+
+
+
+static void
+watchdog_client_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  WatchdogClient *client = WATCHDOG_CLIENT (object);
+
+  switch (prop_id)
+    {
+    case PROP_TIMEOUT:
+      g_value_set_uint (value, client->timeout);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void watchdog_client_set_property (GObject      *object,
+                                          guint         prop_id,
+                                          const GValue *value,
+                                          GParamSpec   *pspec)
+{
+  WatchdogClient *client = WATCHDOG_CLIENT (object);
+
+  switch (prop_id)
+    {
+    case PROP_TIMEOUT:
+      client->timeout = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static gboolean
+watchdog_client_timeout (gpointer user_data)
+{
+  WatchdogClient *client = WATCHDOG_CLIENT (user_data);
+
+  sd_notify (0, "WATCHDOG=1");
+
+  return TRUE;
+}
+
+
+
+WatchdogClient *
+watchdog_client_new (guint timeout)
+{
+  return g_object_new (TYPE_WATCHDOG_CLIENT, "timeout", timeout, NULL);
+}
diff --git a/common/watchdog-client.h b/common/watchdog-client.h
new file mode 100644 (file)
index 0000000..e48f170
--- /dev/null
@@ -0,0 +1,34 @@
+/* vi:set et ai sw=2 sts=2 ts=2: */
+/* -
+ * Copyright (c) 2012 GENIVI.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __WATCHDOG_CLIENT_H__
+#define __WATCHDOG_CLIENT_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define TYPE_WATCHDOG_CLIENT            (watchdog_client_get_type ())
+#define WATCHDOG_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_WATCHDOG_CLIENT, WatchdogClient))
+#define WATCHDOG_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_WATCHDOG_CLIENT, WatchdogClientClass))
+#define IS_WATCHDOG_CLIENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_WATCHDOG_CLIENT))
+#define IS_WATCHDOG_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_WATCHDOG_CLIENT)
+#define WATCHDOG_CLIENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TYPE_WATCHDOG_CLIENT, WatchdogClientClass))
+
+typedef struct _WatchdogClientClass WatchdogClientClass;
+typedef struct _WatchdogClient      WatchdogClient;
+
+GType           watchdog_client_get_type (void) G_GNUC_CONST;
+
+WatchdogClient *watchdog_client_new      (guint timeout) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
+
+G_END_DECLS
+
+#endif /* !__WATCHDOG_CLIENT_H__ */
+
index 5204c25..8dc5fbc 100644 (file)
@@ -14,6 +14,8 @@ luc_handler_built_sources =                                           \
        $(luc_handler_built_headers)
 
 luc_handler_SOURCES =                                                  \
+       ../common/watchdog-client.c                                     \
+       ../common/watchdog-client.h                                     \
        luc-handler-service.c                                           \
        luc-handler-service.h                                           \
        main.c                                                          \
index 9c65b33..4b2c6a1 100644 (file)
@@ -18,6 +18,8 @@
 #include <glib.h>
 #include <gio/gio.h>
 
+#include <common/watchdog-client.h>
+
 #include <luc-handler/luc-handler-service.h>
 
 
@@ -26,11 +28,12 @@ int
 main (int    argc,
       char **argv)
 {
-  LUCHandlerService     *service;
-  GDBusConnection       *connection;
-  GMainLoop             *main_loop;
-  GError                *error = NULL;
-  gint                   exit_status = EXIT_SUCCESS;
+  LUCHandlerService *service;
+  GDBusConnection   *connection;
+  WatchdogClient    *watchdog_client;
+  GMainLoop         *main_loop;
+  GError            *error = NULL;
+  gint               exit_status = EXIT_SUCCESS;
 
   /* initialize the GType type system */
   g_type_init ();
@@ -61,11 +64,15 @@ main (int    argc,
       return EXIT_FAILURE;
     }
 
+  /* update systemd's watchdog timestamp every 120 seconds */
+  watchdog_client = watchdog_client_new (120);
+
   /* create and run the application's main loop */
   main_loop = g_main_loop_new (NULL, FALSE);
   g_main_loop_run (main_loop);
 
   /* release allocated objects */
+  g_object_unref (watchdog_client);
   g_object_unref (service);
   g_object_unref (connection);