watchdog/0006-Make-IT87-fix-up-autom...

184 lines
6.8 KiB
Diff

From 25fa3156526d2e4e1a9bc84a160bf7850107bf27 Mon Sep 17 00:00:00 2001
From: Paul Crawford <psc@sat.dundee.ac.uk>
Date: Fri, 30 Dec 2016 16:39:16 +0000
Subject: [PATCH 06/10] Make IT87 fix-up automatic by default
- Update 00cf0b0 from Maciej S. Szmigiero proposed making the IT87
style of fix something that is set only by the configuration file,
however, for many users with the buggy IT87 driver this will cause
problems.
- This change make the choice a 3 state one:
NO = never use ioctl-based refresh (old way, and in keeping
with the kernel API guidelines for watchdog use).
YES = always use the ioctl-based refresh (i.e set timer every
time, instead of writing to /dev/watchdog). Might be
useful if another driver module is found to share same
sort of bug as the IT87 module.
AUTO = check for IT87 and use ioctl-based method if found. This
is the same basec behaviour as before update 00cf0b0 but
the choice for yes/no now supported.
---
include/extern.h | 4 ++++
src/configfile.c | 12 ++++++++++--
src/keep_alive.c | 43 ++++++++++++++++++++++++++++++++-----------
watchdog.conf.5 | 8 ++++----
4 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/include/extern.h b/include/extern.h
index cbf97fd..6d4ba5e 100644
--- a/include/extern.h
+++ b/include/extern.h
@@ -59,6 +59,10 @@ struct list {
#define FALSE 0
#endif
+#define ENUM_NO 0
+#define ENUM_YES 1
+#define ENUM_AUTO 2
+
#define TS_SIZE 12
/* === External variables === */
diff --git a/src/configfile.c b/src/configfile.c
index 809e39a..29e3464 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -96,7 +96,7 @@ char *logdir = "/var/log/watchdog";
char *heartbeat = NULL;
int hbstamps = 300;
-int refresh_use_settimeout = FALSE;
+int refresh_use_settimeout = ENUM_AUTO;
int realtime = FALSE;
/* Self-repairing binaries list */
@@ -120,6 +120,13 @@ READ_LIST_ADD("yes", 1)
READ_LIST_END()
};
+static const read_list_t YN_Auto_list[] = {
+READ_LIST_ADD("no", ENUM_NO)
+READ_LIST_ADD("yes", ENUM_YES)
+READ_LIST_ADD("auto", ENUM_AUTO)
+READ_LIST_END()
+};
+
/* Use the macros below to simplify the parsing function. For now we don't use the
* integer range checking (0=0 so not checked), and assume all strings can be blank and
* enumerated choices are Yes/No, but in future we could add such settings to the #define'd
@@ -129,6 +136,7 @@ READ_LIST_END()
#define READ_INT(name, iv) read_int_func( arg, val, name, 0, 0, iv)
#define READ_STRING(name, str) read_string_func( arg, val, name, Read_allow_blank, str)
#define READ_YESNO(name, iv) read_enumerated_func(arg, val, name, Yes_No_list, iv)
+#define READ_YN_AUTO(name, iv) read_enumerated_func(arg, val, name, YN_Auto_list, iv)
#define READ_LIST(name, list) read_list_func( arg, val, name, 0, list)
/*
@@ -208,7 +216,7 @@ void read_config(char *configfile)
} else if (READ_INT(LOGTICK, &logtick) == 0) {
ticker = logtick;
} else if (READ_STRING(DEVICE, &devname) == 0) {
- } else if (READ_YESNO(DEVICE_USE_SETTIMEOUT, &refresh_use_settimeout) == 0) {
+ } else if (READ_YN_AUTO(DEVICE_USE_SETTIMEOUT, &refresh_use_settimeout) == 0) {
} else if (READ_INT(DEVICE_TIMEOUT, &dev_timeout) == 0) {
} else if (READ_LIST(TEMP, &temp_list) == 0) {
} else if (READ_INT(MAXTEMP, &maxtemp) == 0) {
diff --git a/src/keep_alive.c b/src/keep_alive.c
index a57b0b5..6e721d9 100644
--- a/src/keep_alive.c
+++ b/src/keep_alive.c
@@ -29,6 +29,7 @@
static int watchdog_fd = -1;
static int timeout_used = TIMER_MARGIN;
+static int Refresh_using_ioctl = FALSE;
/*
* Open the watchdog timer (if name non-NULL) and set the time-out value (if non-zero).
@@ -67,19 +68,39 @@ int open_watchdog(char *name, int timeout)
/* The IT8728 on Gigabyte motherboard (and similar) would trip due to the normal
* refresh in the device driver failing to reset the timer for no obvious reason
* (though the normal operation used the Consumer IR sender to refresh via an
- * interrupt - also a non-obvious method!) so let's warn users of these
- * watchdogs and direct them to a workaround option.
+ * interrupt - also a non-obvious method!) so this work-around simply sets the
+ * time-out every refresh operation.
*
- * See https://bugs.launchpad.net/ubuntu/+source/linux/+bug/932381 and
- * https://bugzilla.kernel.org/show_bug.cgi?id=42801
+ * See https://bugs.launchpad.net/ubuntu/+source/linux/+bug/932381
+ * Also https://bugzilla.kernel.org/show_bug.cgi?id=42801
*
*/
- if (!refresh_use_settimeout && strcmp("IT87 WDT", (char *)ident.identity) == 0) {
- log_message(LOG_INFO,
- "IT87 watchdog detected, if watchdog trips by itself when the first timeout interval elapses "
- "try updating to the latest kernel");
- log_message(LOG_INFO, "if this does not help please report a kernel bug (not this package bug!) "
- "and try using watchdog-refresh-use-settimeout=yes config option as a workaround");
+
+ Refresh_using_ioctl = FALSE;
+
+ switch (refresh_use_settimeout) {
+ case ENUM_NO:
+ /* Set to "no" so never use ioctl mode. */
+ break;
+
+ case ENUM_YES:
+ /* Set to "yes" so always use ioctl mode. */
+ Refresh_using_ioctl = TRUE;
+ log_message(LOG_INFO, "Running ioctl-based refresh");
+ break;
+
+ case ENUM_AUTO:
+ /* Set to "auto" to decide based on driver identity. */
+ Refresh_using_ioctl = FALSE;
+ if (strcmp("IT87 WDT", (char *)ident.identity) == 0) {
+ Refresh_using_ioctl = TRUE;
+ log_message(LOG_INFO, "Running IT87 module fix-up");
+ }
+ break;
+
+ default:
+ log_message(LOG_ERR, "Unknown ioctl selection mode (%d)", refresh_use_settimeout);
+ break;
}
return rv;
@@ -165,7 +186,7 @@ int keep_alive(void)
if (watchdog_fd == -1)
return (ENOERR);
- if (refresh_use_settimeout) {
+ if (Refresh_using_ioctl) {
int timeout = timeout_used;
if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &timeout) < 0) {
err = errno;
diff --git a/watchdog.conf.5 b/watchdog.conf.5
index 4e5155a..709c36e 100644
--- a/watchdog.conf.5
+++ b/watchdog.conf.5
@@ -64,11 +64,11 @@ Set the watchdog device name, typically /dev/watchdog. Default is to disable
keep alive support. This should be tested by running the daemon from the
command line before configuring it to start automatically on booting.
.TP
-watchdog-refresh-use-settimeout = <yes|no>
+watchdog-refresh-use-settimeout = <auto|yes|no>
Refresh watchdog timer by setting its timeout instead of using a normal watchdog
-refresh operation.
-Might help if your watchdog trips by itself when the first timeout interval
-elapses.
+refresh operation. Might help if your watchdog trips by itself when the first
+timeout interval elapses. Default is 'auto' for IT87 fix-up but this can be
+disabled with 'no' or forced for other modules with 'yes'.
.TP
watchdog-timeout = <timeout>
Set the watchdog device timeout during startup. If not set, a default is used
--
2.20.1