aboutsummaryrefslogtreecommitdiff
path: root/toys/pending/watchdog.c
diff options
context:
space:
mode:
Diffstat (limited to 'toys/pending/watchdog.c')
-rw-r--r--toys/pending/watchdog.c120
1 files changed, 20 insertions, 100 deletions
diff --git a/toys/pending/watchdog.c b/toys/pending/watchdog.c
index 0813fe69..d1279bd4 100644
--- a/toys/pending/watchdog.c
+++ b/toys/pending/watchdog.c
@@ -1,128 +1,48 @@
/* watchdog - start a watchdog timer with configurable kick frequencies
+ *
+ * Copyright 2019 Chris Sarra <chrissarra@google.com>
+ *
+ * See kernel.org/doc/Documentation/watchdog/watchdog-api.txt
- Author: Chris Sarra, chrissarra@google.com
- Date: 25 July 2019
- Ref: kernel.org/doc/Documentation/watchdog/watchdog-api.txt
-
-USE_WATCHDOG(NEWTOY(watchdog, "Ft#T#", TOYFLAG_NEEDROOT|TOYFLAG_BIN))
+USE_WATCHDOG(NEWTOY(watchdog, "<1>1Ft#=4<1T#=60<1", TOYFLAG_NEEDROOT|TOYFLAG_BIN))
config WATCHDOG
bool "watchdog"
- default y
+ default n
help
usage: watchdog [-F] [-t SW_TIMER_S] [-T HW_TIMER_S] DEV
Start the watchdog timer at DEV with optional timeout parameters.
- -F run in the foreground (do not daemonize)
- -t software timer (in seconds)
- -T hardware timer (in seconds)
+
+ -F run in the foreground (do not daemonize)
+ -t software timer (in seconds)
+ -T hardware timer (in seconds)
*/
#define FOR_watchdog
#include "toys.h"
#include "linux/watchdog.h"
-// Make sure no DEBUG variable is set; change this if you need debug prints!
-#undef WATCHDOG_DEBUG
-
-// Default timeout values in seconds.
-#define WATCHDOG_SW_TIMER_S_DEFAULT (4)
-#define WATCHDOG_HW_TIMER_S_DEFAULT (60)
-
GLOBALS(
- long hw_timer_s;
- long sw_timer_s;
+ long T, t;
+
int fd;
)
-static int intercept_signals(void (*fn)(int)) {
- int rc = 0;
- struct sigaction sigact;
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_handler = fn;
-
- rc = sigaction(SIGTERM, &sigact, NULL);
-#if defined(WATCHDOG_DEBUG)
- if ( rc ) {
- printf("failed to create new sigaction for SIGTERM: %d\n", rc);
- }
-#endif
- return rc;
-}
-
-void safe_shutdown(int __attribute__((unused))ignored) {
+void safe_shutdown(int ignored) {
write(TT.fd, "V", 1);
close(TT.fd);
- TT.fd = -1;
error_exit("safely exited watchdog.");
}
-void watchdog_main(void) {
- int rc = 0;
- long hw_timer_sec = 0;
- char *watchdog_dev = NULL;
-
- if ( toys.optc > 0 ) {
- watchdog_dev = toys.optargs[0];
-#if defined(WATCHDOG_DEBUG)
- printf("using dev @ '%s'\n", watchdog_dev);
-#endif
- } else {
- error_exit("watchdog dev required");
- }
-
- // Set default values for timeouts if no flags
- if (!(toys.optflags & FLAG_t)) {
- TT.sw_timer_s = WATCHDOG_SW_TIMER_S_DEFAULT;
-#if defined(WATCHDOG_DEBUG)
- printf("using default sw_timer_s.\n");
-#endif
- }
-
- if (!(toys.optflags & FLAG_T)) {
- TT.hw_timer_s = WATCHDOG_HW_TIMER_S_DEFAULT;
-#if defined(WATCHDOG_DEBUG)
- printf("using default hw_timer_s.\n");
-#endif
- }
-
-#if defined(WATCHDOG_DEBUG)
- printf("hw timer: %ld seconds\n", TT.hw_timer_s);
- printf("sw timer: %ld seconds\n", TT.sw_timer_s);
-#endif
-
- if (!(toys.optflags & FLAG_F)) {
-#if defined(WATCHDOG_DEBUG)
- printf("daemonizing. so long, foreground!\n");
-#endif
- // Attempt to daemonize
- rc = daemon(1, 1);
- if ( rc ) {
- perror_exit("failed to daemonize: %d", rc);
- }
- }
-
- // Intercept terminating signals so we can call our shutdown routine first.
- if ( intercept_signals(safe_shutdown) ) {
- perror_exit("failed to intercept desired signals: %d", rc);
- }
-#if defined(WATCHDOG_DEBUG)
- printf("Successfully intercepted signals.\n");
-#endif
-
- TT.fd = open(watchdog_dev, O_WRONLY);
- if ( TT.fd == -1 ) {
- perror_exit("failed to open '%s'", watchdog_dev);
- }
-
-#if defined(WDIOC_SETTIMEOUT)
- // SETTIMEOUT takes time value in seconds: s = ms / (1000 ms/s)
- hw_timer_sec = TT.hw_timer_s;
- xioctl(TT.fd, WDIOC_SETTIMEOUT, (void *)&hw_timer_sec);
-#endif // WDIOC_SETTIMEOUT
+void watchdog_main(void)
+{
+ if (!FLAG(F) && daemon(1, 1)) perror_exit("failed to daemonize");
+ xsignal(SIGTERM, safe_shutdown);
+ xioctl(TT.fd = xopen(*toys.optargs, O_WRONLY), WDIOC_SETTIMEOUT, &TT.T);
// Now that we've got the watchdog device open, kick it periodically.
- while (1) {
+ for (;;) {
write(TT.fd, "\0", 1);
- usleep(TT.sw_timer_s * 1000 * 1000);
+ sleep(TT.t);
}
}