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>
This commit is contained in:
parent
1b84f4a22a
commit
31c765081d
@ -42,17 +42,36 @@
|
|||||||
#define OPT_STIMER (1 << 1)
|
#define OPT_STIMER (1 << 1)
|
||||||
#define OPT_HTIMER (1 << 2)
|
#define OPT_HTIMER (1 << 2)
|
||||||
|
|
||||||
static void watchdog_shutdown(int sig UNUSED_PARAM)
|
static void shutdown_watchdog(void)
|
||||||
{
|
{
|
||||||
static const char V = 'V';
|
static const char V = 'V';
|
||||||
|
|
||||||
remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
|
|
||||||
write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
|
write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
close(3);
|
||||||
close(3);
|
}
|
||||||
|
|
||||||
|
static void shutdown_on_signal(int sig UNUSED_PARAM)
|
||||||
|
{
|
||||||
|
remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid");
|
||||||
|
shutdown_watchdog();
|
||||||
_exit(EXIT_SUCCESS);
|
_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) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int watchdog_main(int argc, char **argv)
|
int watchdog_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -86,10 +105,9 @@ int watchdog_main(int argc, char **argv)
|
|||||||
if (opts & OPT_STIMER)
|
if (opts & OPT_STIMER)
|
||||||
stimer_duration = xatou_sfx(st_arg, suffixes);
|
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' */
|
watchdog_open(argv[argc - 1]);
|
||||||
xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
|
|
||||||
|
|
||||||
/* WDIOC_SETTIMEOUT takes seconds, not milliseconds */
|
/* WDIOC_SETTIMEOUT takes seconds, not milliseconds */
|
||||||
htimer_duration = htimer_duration / 1000;
|
htimer_duration = htimer_duration / 1000;
|
||||||
|
Loading…
Reference in New Issue
Block a user