blob: 7128b8108dcead9ca2abe93a56ad72099e1e2081 [file] [log] [blame]
Matt Spinlercd9d1302017-06-13 15:42:39 -05001From a4c493ae42926ab36fdc805a5da9f0682bb98b45 Mon Sep 17 00:00:00 2001
2From: Matt Spinler <spinler@us.ibm.com>
3Date: Tue, 13 Jun 2017 15:26:49 -0500
4Subject: [PATCH] Stop watchdog first on startup
5
6Some watchdog implementations may do things other than issue
7a reboot on a watchdog timeout. In this case, there's the
8possibility of restarting this program from the state of
9the watchdog device not being properly stopped (done by writing
10a 'V' and closing the device). Since it wasn't stopped, the
11driver may not be able to restart the watchdog when this program
12reopens it and starts pinging it.
13
14To fix this, the code will always first issue the stop when it
15starts up.
16
17Signed-off-by: Matt Spinler <spinler@us.ibm.com>
18---
19 miscutils/watchdog.c | 21 +++++++++++++++++++--
20 1 file changed, 19 insertions(+), 2 deletions(-)
21
22diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
23index 07ae64e52..223e3c32d 100644
24--- a/miscutils/watchdog.c
25+++ b/miscutils/watchdog.c
26@@ -53,6 +53,24 @@ static void watchdog_shutdown(int sig UNUSED_PARAM)
27 _exit(EXIT_SUCCESS);
28 }
29
30+static void watchdog_open(const char* device)
31+{
32+ static const char magic_value = 'V';
33+
34+ /* If the watchdog driver can do something other than cause a reboot
35+ * on a timeout, then it's possible this program may be starting from
36+ * a state when the watchdog hadn't been previously stopped with
37+ * the magic write followed by a close. In this case the driver may
38+ * not start properly, so always do the proper stop first just in case.
39+ */
40+
41+ /* Use known fd # - avoid needing global 'int fd' */
42+ xmove_fd(xopen(device, O_WRONLY), 3);
43+ write(3, &magic_value, 1);
44+ close(3);
45+ xmove_fd(xopen(device, O_WRONLY), 3);
46+}
47+
48 int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
49 int watchdog_main(int argc, char **argv)
50 {
51@@ -88,8 +106,7 @@ int watchdog_main(int argc, char **argv)
52
53 bb_signals(BB_FATAL_SIGS, watchdog_shutdown);
54
55- /* Use known fd # - avoid needing global 'int fd' */
56- xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
57+ watchdog_open(argv[argc - 1]);
58
59 /* WDIOC_SETTIMEOUT takes seconds, not milliseconds */
60 htimer_duration = htimer_duration / 1000;
61--
622.11.0
63