summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-06-17 09:47:51 +0200
committerStijn Tintel <stijn@linux-ipv6.be>2022-06-23 11:57:33 +0300
commit901afeb05ee6717e4214b1d94d184b36a13be09a (patch)
tree0c61f17a921c569dd3456e05bca2038a76e8c807
parent0ce8d7773f344016431468ea3e8cedb9d86352ff (diff)
downloadprocd-staging/stintel/watchdog.tar.gz
watchdog: retry with larger timeout value if effective timeout is 0staging/stintel/watchdog
Some watchdog drivers, such as w83793, have a very low timeout granularity of only one minute. The procd default timeout of 30s will yield an effective timeout of 0 with this driver, leading to an almost instant reset once activated. In order to gracefully deal with watchdogs having no sub-30s resolution, check that the effectively calculated timeout returned by the ioctl() call is zero and retry with a duplicated timeout value in this case. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--watchdog.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/watchdog.c b/watchdog.c
index bedb545..a2689a5 100644
--- a/watchdog.c
+++ b/watchdog.c
@@ -87,10 +87,32 @@ static void watchdog_close(void)
static int watchdog_set_drv_timeout(void)
{
+ int timeout = wdt_drv_timeout;
+ int rv;
+
if (wdt_fd < 0)
return -1;
- return ioctl(wdt_fd, WDIOC_SETTIMEOUT, &wdt_drv_timeout);
+ while (1) {
+ rv = ioctl(wdt_fd, WDIOC_SETTIMEOUT, &timeout);
+
+ if (rv != 0)
+ break;
+
+ if (timeout == 0 && wdt_drv_timeout != 0) {
+ DEBUG(2, "Watchdog timeout %d too low, retrying with %d\n", wdt_drv_timeout, wdt_drv_timeout * 2);
+
+ wdt_drv_timeout *= 2;
+ timeout = wdt_drv_timeout;
+
+ continue;
+ }
+
+ wdt_drv_timeout = timeout;
+ break;
+ }
+
+ return rv;
}
static void watchdog_print_status(void)