summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--miscutils/watchdog.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index 07ae64e..95e2f1a 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -42,17 +42,36 @@
#define OPT_STIMER (1 << 1)
#define OPT_HTIMER (1 << 2)
-static void watchdog_shutdown(int sig UNUSED_PARAM)
+static void shutdown_watchdog(void)
{
static const char V = 'V';
+ write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
+ close(3);
+}
+static void shutdown_on_signal(int sig UNUSED_PARAM)
+{
remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
- write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
- if (ENABLE_FEATURE_CLEAN_UP)
- close(3);
+ shutdown_watchdog();
_exit(EXIT_SUCCESS);
}
+static void watchdog_open(const char* device)
+{
+ /* Use known fd # - avoid needing global 'int fd' */
+ xmove_fd(xopen(device, O_WRONLY), 3);
+
+ /* If the watchdog driver can do something other than cause a reboot
+ * on a timeout, then it's possible this program may be starting from
+ * a state when the watchdog hadn't been previously stopped with
+ * the magic write followed by a close. In this case the driver may
+ * not start properly, so always do the proper stop first just in case.
+ */
+ shutdown_watchdog();
+
+ xmove_fd(xopen(device, O_WRONLY), 3);
+}
+
int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int watchdog_main(int argc, char **argv)
{
@@ -86,10 +105,9 @@ int watchdog_main(int argc, char **argv)
if (opts & OPT_STIMER)
stimer_duration = xatou_sfx(st_arg, suffixes);
- bb_signals(BB_FATAL_SIGS, watchdog_shutdown);
+ bb_signals(BB_FATAL_SIGS, shutdown_on_signal);
- /* Use known fd # - avoid needing global 'int fd' */
- xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
+ watchdog_open(argv[argc - 1]);
/* WDIOC_SETTIMEOUT takes seconds, not milliseconds */
htimer_duration = htimer_duration / 1000;