diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-06-17 09:47:51 +0200 |
---|---|---|
committer | Stijn Tintel <stijn@linux-ipv6.be> | 2022-06-23 11:57:33 +0300 |
commit | 901afeb05ee6717e4214b1d94d184b36a13be09a (patch) | |
tree | 0c61f17a921c569dd3456e05bca2038a76e8c807 | |
parent | 0ce8d7773f344016431468ea3e8cedb9d86352ff (diff) | |
download | procd-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.c | 24 |
1 files changed, 23 insertions, 1 deletions
@@ -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) |