From 3571efc391f7e86d92401f8e46814a8fd343c87f Mon Sep 17 00:00:00 2001 From: Jannis Pohlmann Date: Wed, 13 Jun 2012 11:07:40 +0100 Subject: [PATCH] Update systemd's watchdog timeout in luc-handler using WatchdogClient 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 | 184 +++++++++++++++++++++++++++++++++++++++++++++++ common/watchdog-client.h | 34 +++++++++ luc-handler/Makefile.am | 2 + luc-handler/main.c | 17 +++-- 4 files changed, 232 insertions(+), 5 deletions(-) create mode 100644 common/watchdog-client.c create mode 100644 common/watchdog-client.h diff --git a/common/watchdog-client.c b/common/watchdog-client.c new file mode 100644 index 0000000..6645fd5 --- /dev/null +++ b/common/watchdog-client.c @@ -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 +#endif + +#include + +#include +#include + +#include + + + +/* 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 index 0000000..e48f170 --- /dev/null +++ b/common/watchdog-client.h @@ -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 + +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__ */ + diff --git a/luc-handler/Makefile.am b/luc-handler/Makefile.am index 5204c25..8dc5fbc 100644 --- a/luc-handler/Makefile.am +++ b/luc-handler/Makefile.am @@ -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 \ diff --git a/luc-handler/main.c b/luc-handler/main.c index 9c65b33..4b2c6a1 100644 --- a/luc-handler/main.c +++ b/luc-handler/main.c @@ -18,6 +18,8 @@ #include #include +#include + #include @@ -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); -- 2.7.4