Subject: rfc: an alternate user-tickle mode for wdogctl(8)
To: None <tech-userlevel@netbsd.org>
From: David Young <dyoung@pobox.com>
List: tech-userlevel
Date: 08/06/2006 14:18:11
--d6Gm4EdcadzBjdND
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I have added a flag to wdogctl(8), -x, that activates a user-mode timer
that is NOT disarmed when wdogctl closes the watchdog device. See the
attached patch. The -x mode protects against the case where the kernel
kills wdogctl, sshd, and other essential userland programs are killed
due to, say, memory exhaustion, lobotomizing a mission-critical NetBSD
system and necessitating an operator visit to reboot it. If there are
no objections, I will commit this on Wednesday.
Dave
--
David Young OJC Technologies
dyoung@ojctech.com Urbana, IL * (217) 278-3933
--d6Gm4EdcadzBjdND
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="wdogctl.patch"
Index: sbin/wdogctl/wdogctl.8
===================================================================
RCS file: /cvsroot/src/sbin/wdogctl/wdogctl.8,v
retrieving revision 1.12
diff -u -p -u -p -r1.12 wdogctl.8
--- sbin/wdogctl/wdogctl.8 21 Jan 2005 10:40:01 -0000 1.12
+++ sbin/wdogctl/wdogctl.8 6 Aug 2006 18:49:25 -0000
@@ -58,6 +58,11 @@
.Op Fl A
.Op Fl p Ar seconds
.Ar timer
+.Nm
+.Fl x
+.Op Fl A
+.Op Fl p Ar seconds
+.Ar timer
.Sh DESCRIPTION
.Nm
is used to manipulate watchdog timers.
@@ -87,7 +92,10 @@ Note that user tickle mode must be used
on a heavily loaded system, the timer may
expire accidentally, even though user programs may be making
(very slow) progress.
-A user-mode timer is disarmed (if possible) when the device is closed.
+A user-mode timer is disarmed (if possible) when the device is closed,
+unless the timer is activated with the
+.Fl x
+option.
.Pp
External-mode watchdogs are similar to user-mode watchdogs, except
that the tickle must be done explicitly by a separate invocation of
@@ -144,6 +152,11 @@ This flag tickles an external mode timer
Arm
.Ar timer
in user tickle mode.
+.It Fl x
+Arm
+.Ar timer
+in a modified user tickle mode: closing the device will not disarm
+the timer.
.El
.Sh FILES
.Pa /dev/watchdog
Index: sbin/wdogctl/wdogctl.c
===================================================================
RCS file: /cvsroot/src/sbin/wdogctl/wdogctl.c,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 wdogctl.c
--- sbin/wdogctl/wdogctl.c 31 Aug 2005 18:28:58 -0000 1.15
+++ sbin/wdogctl/wdogctl.c 6 Aug 2006 18:49:25 -0000
@@ -58,7 +58,7 @@ __RCSID("$NetBSD: wdogctl.c,v 1.15 2005/
int main(int, char *[]);
void enable_kernel(const char *, u_int);
-void enable_user(const char *, u_int);
+void enable_user(const char *, u_int, int);
void enable_ext(const char *, u_int);
void tickle_ext(void);
void disable(void);
@@ -75,6 +75,7 @@ enum cmd {
CMD_DOTICKLE,
CMD_EXT_TICKLE,
CMD_KERN_TICKLE,
+ CMD_NOCANCEL_TICKLE,
CMD_USER_TICKLE
};
@@ -86,7 +87,7 @@ main(int argc, char *argv[])
int ch;
u_int period = WDOG_PERIOD_DEFAULT;
- while ((ch = getopt(argc, argv, "Adekp:ut")) != -1) {
+ while ((ch = getopt(argc, argv, "Adekp:utx")) != -1) {
switch (ch) {
case 'A':
Aflag = 1;
@@ -123,10 +124,12 @@ main(int argc, char *argv[])
usage();
break;
+ case 'x':
case 'u':
if (command != CMD_NONE)
usage();
- command = CMD_USER_TICKLE;
+ command =
+ (ch == 'u') ? CMD_USER_TICKLE : CMD_NOCANCEL_TICKLE;
break;
default:
@@ -161,8 +164,9 @@ main(int argc, char *argv[])
case CMD_KERN_TICKLE:
enable_kernel(argv[0], period);
break;
+ case CMD_NOCANCEL_TICKLE:
case CMD_USER_TICKLE:
- enable_user(argv[0], period);
+ enable_user(argv[0], period, command == CMD_USER_TICKLE);
break;
}
exit(EXIT_SUCCESS);
@@ -218,14 +222,16 @@ enable_ext(const char *name, u_int perio
}
void
-enable_user(const char *name, u_int period)
+enable_user(const char *name, u_int period, int cancel_on_close)
{
struct wdog_mode wm;
struct timespec ts;
pid_t tickler;
int fd, rv;
- prep_wmode(&wm, WDOG_MODE_UTICKLE, name, period);
+ prep_wmode(&wm,
+ (cancel_on_close) ? WDOG_MODE_UTICKLE : WDOG_MODE_ETICKLE, name,
+ period);
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
--d6Gm4EdcadzBjdND--