Use the WATCHDOG_USEC env variable to define the watchdog timeout
authorJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Fri, 27 Jul 2012 13:27:15 +0000 (14:27 +0100)
committerJannis Pohlmann <jannis.pohlmann@codethink.co.uk>
Fri, 27 Jul 2012 13:34:40 +0000 (14:34 +0100)
Also, set WatchdogSec to 5 seconds in boot-manager.service.in and
nsm-dummy.service.in.

The way this works is that systemd will take the WatchdogSec value,
convert it to micro-seconds and set the WATCHDOG_USEC environment
variable for the boot manager or nsm-dummy process. The boot manager
or NSM dummy then halves that value and creates the WatchdogClient
so that it calls sd_notify(0, WATCHDOG=1) twice in each
WATCHDOG_USEC interval. If WATCHDOG_USEC can't be parsed into a
number or if it is not set, the systemd watchdog timestamp is
never updated.

This is what systemd's requires services to do in order to support its
watchdog feature properly.

boot-manager/boot-manager-application.c
boot-manager/boot-manager.service.in
nsm-dummy/nsm-dummy-application.c
nsm-dummy/systemd/nsm-dummy.service.in

index 0b278e0..60b6ceb 100644 (file)
@@ -94,7 +94,7 @@ struct _BootManagerApplication
    * the watchdog timestamp */
   WatchdogClient     *watchdog_client;
 
-  /* internal handler of Start() and Stop() jobs */
+  /* manager of unit start and stop operations */
   JobManager         *job_manager;
 
   /* boot manager service */
@@ -199,8 +199,33 @@ boot_manager_application_class_init (BootManagerApplicationClass *klass)
 static void
 boot_manager_application_init (BootManagerApplication *application)
 {
-  /* update systemd's watchdog timestamp every 120 seconds */
-  application->watchdog_client = watchdog_client_new (120);
+  const gchar *watchdog_str;
+  guint64      watchdog_usec = 0;
+  guint        watchdog_sec = 0;
+  gchar       *message;
+
+  /* read the WATCHDOG_USEC environment variable and parse it
+   * into an unsigned integer */
+  watchdog_str = g_getenv ("WATCHDOG_USEC");
+  if (watchdog_str != NULL)
+    watchdog_usec = g_ascii_strtoull (watchdog_str, NULL, 10);
+
+  /* only create the watchdog client if a timeout was specified */
+  if (watchdog_usec > 0)
+    {
+      /* halve the watchdog timeout because we need to notify systemd
+       * twice in every interval; also, convert it to seconds */
+      watchdog_sec = (guint) ((watchdog_usec / 2) / 1000000);
+
+      /* update systemd's watchdog timestamp in regular intervals */
+      application->watchdog_client = watchdog_client_new (watchdog_sec);
+
+      /* log information about the watchdog timeout using DLT */
+      message = g_strdup_printf ("Updating systemd's watchdog timestamp every %d seconds",
+                                 watchdog_sec);
+      DLT_LOG (boot_manager_context, DLT_LOG_INFO, DLT_STRING (message));
+      g_free (message);
+    }
 }
 
 
@@ -227,7 +252,8 @@ boot_manager_application_finalize (GObject *object)
     g_object_unref (application->connection);
 
   /* release the watchdog client */
-  g_object_unref (application->watchdog_client);
+  if (application->watchdog_client != NULL)
+    g_object_unref (application->watchdog_client);
 
   /* release the boot manager */
   g_object_unref (application->boot_manager_service);
index f46af51..e255295 100644 (file)
@@ -2,3 +2,4 @@
 Type = dbus
 BusName = org.genivi.BootManager1
 ExecStart = @libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/boot-manager
+WatchdogSec = 5
index a782ed9..38f6b94 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <systemd/sd-daemon.h>
 
+#include <dlt/dlt.h>
+
 #include <common/nsm-consumer-dbus.h>
 #include <common/nsm-lifecycle-control-dbus.h>
 #include <common/watchdog-client.h>
 
 
 
+DLT_IMPORT_CONTEXT (nsm_dummy_context);
+
+
+
 /* property identifiers */
 enum
 {
@@ -145,8 +151,33 @@ nsm_dummy_application_class_init (NSMDummyApplicationClass *klass)
 static void
 nsm_dummy_application_init (NSMDummyApplication *application)
 {
-  /* update systemd's watchdog timestamp every 120 seconds */
-  application->watchdog_client = watchdog_client_new (120);
+  const gchar *watchdog_str;
+  guint64      watchdog_usec = 0;
+  guint        watchdog_sec = 0;
+  gchar       *message;
+
+  /* read the WATCHDOG_USEC environment variable and parse it
+   * into an unsigned integer */
+  watchdog_str = g_getenv ("WATCHDOG_USEC");
+  if (watchdog_str != NULL)
+    watchdog_usec = g_ascii_strtoull (watchdog_str, NULL, 10);
+
+  /* only create the watchdog client if a timeout was specified */
+  if (watchdog_usec > 0)
+    {
+      /* halve the watchdog timeout because we need to notify systemd
+       * twice in every interval; also, convert it to seconds */
+      watchdog_sec = (guint) ((watchdog_usec / 2) / 1000000);
+
+      /* update systemd's watchdog timestamp in regular intervals */
+      application->watchdog_client = watchdog_client_new (watchdog_sec);
+
+      /* log information about the watchdog timeout using DLT */
+      message = g_strdup_printf ("Updating systemd's watchdog timestamp every %d seconds",
+                                 watchdog_sec);
+      DLT_LOG (nsm_dummy_context, DLT_LOG_INFO, DLT_STRING (message));
+      g_free (message);
+    }
 
   /* install the signal handler */
   application->sighup_id = g_unix_signal_add (SIGHUP, nsm_dummy_application_handle_sighup,
@@ -171,7 +202,8 @@ nsm_dummy_application_finalize (GObject *object)
   g_source_remove (application->sighup_id);
 
   /* release the watchdog client */
-  g_object_unref (application->watchdog_client);
+  if (application->watchdog_client != NULL)
+    g_object_unref (application->watchdog_client);
 
   /* release the main loop */
   g_main_loop_unref (application->main_loop);
index 661db79..72544aa 100644 (file)
@@ -2,3 +2,4 @@
 Type = dbus
 BusName = com.contiautomotive.NodeStateManager
 ExecStart = @libdir@/boot-manager-@BOOT_MANAGER_VERSION_API@/nsm-dummy
+WatchdogSec = 5