aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Spinler <mspinler@linux.vnet.ibm.com>2017-07-08 18:35:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-08 18:35:25 +0200
commit31c765081dc41f158786545fbea9294be4685bd2 (patch)
tree902b029ed3d2167743692cdcd2c941e7617c066b
parent1b84f4a22adb1a8c3fa633a5b08081694667505c (diff)
downloadbusybox-w32-31c765081dc41f158786545fbea9294be4685bd2.tar.gz
busybox-w32-31c765081dc41f158786545fbea9294be4685bd2.tar.bz2
busybox-w32-31c765081dc41f158786545fbea9294be4685bd2.zip
watchdog: stop watchdog first on startup
Some watchdog implementations may do things other than issue a reboot on a watchdog timeout. In this case, there's the possibility of restarting this program from the state of the watchdog device not being properly stopped (done by writing a 'V' and closing the device). Since it wasn't stopped, the driver may not be able to restart the watchdog when this program reopens it and starts pinging it. To fix this, the code will always first issue the stop when it starts up. function old new delta shutdown_on_signal - 32 +32 watchdog_main 268 298 +30 shutdown_watchdog - 25 +25 watchdog_shutdown 41 - -41 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 1/0 up/down: 87/-41) Total: 46 bytes Signed-off-by: Matt Spinler <spinler@us.ibm.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/watchdog.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c
index 07ae64e52..95e2f1a53 100644
--- a/miscutils/watchdog.c
+++ b/miscutils/watchdog.c
@@ -42,17 +42,36 @@
42#define OPT_STIMER (1 << 1) 42#define OPT_STIMER (1 << 1)
43#define OPT_HTIMER (1 << 2) 43#define OPT_HTIMER (1 << 2)
44 44
45static void watchdog_shutdown(int sig UNUSED_PARAM) 45static void shutdown_watchdog(void)
46{ 46{
47 static const char V = 'V'; 47 static const char V = 'V';
48 write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
49 close(3);
50}
48 51
52static void shutdown_on_signal(int sig UNUSED_PARAM)
53{
49 remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid"); 54 remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
50 write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */ 55 shutdown_watchdog();
51 if (ENABLE_FEATURE_CLEAN_UP)
52 close(3);
53 _exit(EXIT_SUCCESS); 56 _exit(EXIT_SUCCESS);
54} 57}
55 58
59static void watchdog_open(const char* device)
60{
61 /* Use known fd # - avoid needing global 'int fd' */
62 xmove_fd(xopen(device, O_WRONLY), 3);
63
64 /* If the watchdog driver can do something other than cause a reboot
65 * on a timeout, then it's possible this program may be starting from
66 * a state when the watchdog hadn't been previously stopped with
67 * the magic write followed by a close. In this case the driver may
68 * not start properly, so always do the proper stop first just in case.
69 */
70 shutdown_watchdog();
71
72 xmove_fd(xopen(device, O_WRONLY), 3);
73}
74
56int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 75int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
57int watchdog_main(int argc, char **argv) 76int watchdog_main(int argc, char **argv)
58{ 77{
@@ -86,10 +105,9 @@ int watchdog_main(int argc, char **argv)
86 if (opts & OPT_STIMER) 105 if (opts & OPT_STIMER)
87 stimer_duration = xatou_sfx(st_arg, suffixes); 106 stimer_duration = xatou_sfx(st_arg, suffixes);
88 107
89 bb_signals(BB_FATAL_SIGS, watchdog_shutdown); 108 bb_signals(BB_FATAL_SIGS, shutdown_on_signal);
90 109
91 /* Use known fd # - avoid needing global 'int fd' */ 110 watchdog_open(argv[argc - 1]);
92 xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
93 111
94 /* WDIOC_SETTIMEOUT takes seconds, not milliseconds */ 112 /* WDIOC_SETTIMEOUT takes seconds, not milliseconds */
95 htimer_duration = htimer_duration / 1000; 113 htimer_duration = htimer_duration / 1000;