X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=watchdog.c;h=9b50d909d170ab6e91b1b1b9bf1e0e8d0b21b6a8;hb=HEAD;hp=7493a0f51b3b0e244d918aa1b3505cf522f61b9a;hpb=a0372ac0713957365120cf42c5469c635c1e0232;p=project%2Fprocd.git diff --git a/watchdog.c b/watchdog.c index 7493a0f..9b50d90 100644 --- a/watchdog.c +++ b/watchdog.c @@ -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; @@ -70,13 +71,15 @@ static int watchdog_open(bool cloexec) return wdt_fd; } -static void watchdog_close(void) +static void watchdog_close(bool with_release) { if (wdt_fd < 0) return; - if (write(wdt_fd, "V", 1) < 0) - ERROR("WDT failed to write release: %m\n"); + if (with_release) { + if (write(wdt_fd, "V", 1) < 0) + ERROR("WDT failed to write release: %m\n"); + } if (close(wdt_fd) == -1) ERROR("WDT failed to close watchdog: %m\n"); @@ -84,6 +87,43 @@ 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); +} + +static void watchdog_print_status(void) +{ + struct watchdog_info wdt_info; + int bootstatus; + + if (wdt_fd < 0) + return; + + if (ioctl(wdt_fd, WDIOC_GETSUPPORT, &wdt_info)) { + DEBUG(2, "Watchdog GETSUPPORT failed\n"); + return; + } + + if (!(wdt_info.options & WDIOF_CARDRESET)) { + DEBUG(2, "Watchdog does not have CARDRESET support\n"); + return; + } + + if (ioctl(wdt_fd, WDIOC_GETBOOTSTATUS, &bootstatus)) { + DEBUG(2, "Watchdog GETBOOTSTATUS failed\n"); + return; + } + + if (bootstatus & WDIOF_CARDRESET) + LOG("Watchdog has previously reset the system\n"); + else + DEBUG(2, "Watchdog did not previously reset the system\n"); +} + void watchdog_set_magicclose(bool val) { wdt_magicclose = val; @@ -99,11 +139,11 @@ void watchdog_set_stopped(bool val) if (val) { uloop_timeout_cancel(&wdt_timeout); - if (wdt_magicclose) - watchdog_close(); + watchdog_close(wdt_magicclose); } else { watchdog_open(true); + watchdog_set_drv_timeout(); watchdog_timeout_cb(&wdt_timeout); } } @@ -115,23 +155,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,10 +196,12 @@ 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)); + + watchdog_print_status(); }