watchdog: improve seting watchdog timeout and frequency
authorHans Dedecker <dedeckeh@gmail.com>
Sun, 4 Nov 2018 10:14:31 +0000 (11:14 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Thu, 8 Nov 2018 10:21:18 +0000 (11:21 +0100)
Due to the watchdog file descriptor check in both watchdog_timeout and
watchdog_frequency it's impossible to set the timeout/frequency via ubus
in case the watchdog was stopped.
Fix this by removing the watchdog file descriptor check in both functions
and by caching locally the set watchdog driver timeout value. The latter
will be used to set the watchdog driver timeout value in case the
watchdog is active or when the watchdog is started.
In addition when parsing the watchdog ubus call check if timeout
attribute is set so the correct value is used when doing the frequency
sanity check.

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
system.c
watchdog.c

index 46c420b..8ed3f93 100644 (file)
--- a/system.c
+++ b/system.c
@@ -304,7 +304,8 @@ static int watchdog_set(struct ubus_context *ctx, struct ubus_object *obj,
 
        blobmsg_parse(watchdog_policy, __WDT_MAX, tb, blob_data(msg), blob_len(msg));
        if (tb[WDT_FREQUENCY]) {
-               unsigned int timeout = watchdog_timeout(0);
+               unsigned int timeout = tb[WDT_TIMEOUT] ? blobmsg_get_u32(tb[WDT_TIMEOUT]) :
+                                               watchdog_timeout(0);
                unsigned int freq = blobmsg_get_u32(tb[WDT_FREQUENCY]);
 
                if (freq) {
index 7493a0f..9d770b4 100644 (file)
@@ -30,6 +30,7 @@
 
 static struct uloop_timeout wdt_timeout;
 static int wdt_fd = -1;
+static int wdt_drv_timeout = 30;
 static int wdt_frequency = 5;
 static bool wdt_magicclose = false;
 
@@ -84,6 +85,14 @@ static void watchdog_close(void)
        wdt_fd = -1;
 }
 
+static int watchdog_set_drv_timeout(void)
+{
+       if (wdt_fd < 0)
+               return -1;
+
+       return ioctl(wdt_fd, WDIOC_SETTIMEOUT, &wdt_drv_timeout);
+}
+
 void watchdog_set_magicclose(bool val)
 {
        wdt_magicclose = val;
@@ -104,6 +113,7 @@ void watchdog_set_stopped(bool val)
        }
        else {
                watchdog_open(true);
+               watchdog_set_drv_timeout();
                watchdog_timeout_cb(&wdt_timeout);
        }
 }
@@ -115,23 +125,19 @@ bool watchdog_get_stopped(void)
 
 int watchdog_timeout(int timeout)
 {
-       if (wdt_fd < 0)
-               return 0;
-
        if (timeout) {
                DEBUG(4, "Set watchdog timeout: %ds\n", timeout);
-               ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
+               wdt_drv_timeout = timeout;
+
+               if (wdt_fd >= 0)
+                       watchdog_set_drv_timeout();
        }
-       ioctl(wdt_fd, WDIOC_GETTIMEOUT, &timeout);
 
-       return timeout;
+       return wdt_drv_timeout;
 }
 
 int watchdog_frequency(int frequency)
 {
-       if (wdt_fd < 0)
-               return 0;
-
        if (frequency) {
                DEBUG(4, "Set watchdog frequency: %ds\n", frequency);
                wdt_frequency = frequency;
@@ -160,7 +166,7 @@ void watchdog_init(int preinit)
                return;
 
        LOG("- watchdog -\n");
-       watchdog_timeout(30);
+       watchdog_set_drv_timeout();
        watchdog_timeout_cb(&wdt_timeout);
 
        DEBUG(4, "Opened watchdog with timeout %ds\n", watchdog_timeout(0));