@@ -177,6 +177,37 @@ and queried::
Note that the pretimeout governor that reads data is not compatible with
the NMI preaction. The NMI preaction can only do nothing or panic.
+Pretimeout Governors
+====================
+
+When a pretimeout occurs and the pretimeout framework is compiled in
+to the kernel, the pretimeout framework will generally be called.
+(The exception is that NMI pretimeouts do not call the pretimeout
+framework because they need special handling.) Several pretimeout
+governers can be registered::
+
+ noop - Don't do anything on a pretimeout
+ panic - Issue a panic when a pretimeout occurs. This is generally the
+ default
+ read_data - Provide one byte of data on the read interface to the
+ watchdog timer. This way a userland program can handle
+ the pretimeout.
+
+If the CONFING_WATCHDOG_SYSFS is enabled, the pretimeout governor can
+be set by writing the value to the
+/sys/class/watchdog/watchdog<n>/pretimeout_governor sysfs file.
+
+The pretimeout governor can also be set through the ioctl interface with::
+
+ char governor[WATCHDOG_GOV_NAME_MAXLEN] = "panic";
+ ioctl(fd, WDIOC_SETPREGOV, gov);
+
+and can be queried with::
+
+ char governor[WATCHDOG_GOV_NAME_MAXLEN];
+ ioctl(fd, WDIOC_GETPREGOV, gov);
+ printf("The governor is %s\n", gov);
+
Get the number of seconds before reboot
=======================================
@@ -762,6 +762,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
int __user *p = argp;
unsigned int val;
int err;
+ char gov[WATCHDOG_GOV_NAME_MAXLEN];
mutex_lock(&wd_data->lock);
@@ -866,6 +867,19 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
case WDIOC_GETPREACTION:
err = put_user(wdd->preaction, p);
break;
+ case WDIOC_SETPREGOV:
+ err = strncpy_from_user(gov, argp, sizeof(gov));
+ if (err >= 0)
+ err = watchdog_pretimeout_governor_set(wdd, gov);
+ break;
+ case WDIOC_GETPREGOV:
+ err = 0;
+ val = watchdog_pretimeout_governor_get(wdd, gov);
+ if (val == 0)
+ err = -ENOENT;
+ if (copy_to_user(argp, gov, val + 1))
+ err = -EFAULT;
+ break;
default:
err = -ENOTTY;
break;
@@ -2,7 +2,7 @@
#ifndef __WATCHDOG_PRETIMEOUT_H
#define __WATCHDOG_PRETIMEOUT_H
-#define WATCHDOG_GOV_NAME_MAXLEN 20
+#include <uapi/linux/watchdog.h>
struct watchdog_device;
@@ -36,10 +36,18 @@ struct watchdog_info {
#define WDIOC_GETACTION _IOR(WATCHDOG_IOCTL_BASE, 12, int)
#define WDIOC_SETPREACTION _IOWR(WATCHDOG_IOCTL_BASE, 13, int)
#define WDIOC_GETPREACTION _IOR(WATCHDOG_IOCTL_BASE, 14, int)
+#define WDIOC_SETPREGOV _IOWR(WATCHDOG_IOCTL_BASE, 15, char)
+#define WDIOC_GETPREGOV _IOR(WATCHDOG_IOCTL_BASE, 16, char)
#define WDIOF_UNKNOWN -1 /* Unknown flag error */
#define WDIOS_UNKNOWN -1 /* Unknown status error */
+/*
+ * Buffer for WDIOC_GETPREGOV must be at least this big. WDIOC_SETPRGOV
+ * will take at max this many bytes - 1, excess will be ignored.
+ */
+#define WATCHDOG_GOV_NAME_MAXLEN 20
+
#define WDIOF_OVERHEAT 0x0001 /* Reset due to CPU overheat */
#define WDIOF_FANFAULT 0x0002 /* Fan failed */
#define WDIOF_EXTERN1 0x0004 /* External relay 1 */