Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Add a software watchdog timer facility. Because this slightly
details: https://anonhg.NetBSD.org/src/rev/0378484a60d5
branches: trunk
changeset: 572658:0378484a60d5
user: smb <smb%NetBSD.org@localhost>
date: Sun Jan 09 22:51:32 2005 +0000
description:
Add a software watchdog timer facility. Because this slightly
changes the "tickle" model of wdogctl(8), it was modified as well;
while I was in there, I cleaned up the argument parsing.
The code was reviewed by simonb@.
diffstat:
distrib/sets/lists/man/mi | 4 +-
sbin/wdogctl/wdogctl.8 | 28 +++++-
sbin/wdogctl/wdogctl.c | 181 +++++++++++++++++++++++++++++++-----------
share/man/man4/Makefile | 6 +-
share/man/man4/swwdog.4 | 76 ++++++++++++++++++
sys/dev/sysmon/files.sysmon | 6 +-
sys/dev/sysmon/swwdog.c | 159 +++++++++++++++++++++++++++++++++++++
sys/dev/sysmon/sysmon_wdog.c | 5 +-
sys/sys/wdog.h | 3 +-
9 files changed, 406 insertions(+), 62 deletions(-)
diffs (truncated from 709 to 300 lines):
diff -r 62e801bfb0a9 -r 0378484a60d5 distrib/sets/lists/man/mi
--- a/distrib/sets/lists/man/mi Sun Jan 09 22:24:04 2005 +0000
+++ b/distrib/sets/lists/man/mi Sun Jan 09 22:51:32 2005 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.748 2005/01/09 05:53:16 snj Exp $
+# $NetBSD: mi,v 1.749 2005/01/09 22:51:32 smb Exp $
./etc/mtree/set.man man-sys-root
./usr/share/info/am-utils.info man-amd-info info
./usr/share/info/as.info man-computil-info bfd,info
@@ -1227,6 +1227,7 @@
./usr/share/man/cat4/sun3/ms.0 man-sys-catman .cat
./usr/share/man/cat4/sv.0 man-sys-catman .cat
./usr/share/man/cat4/sw.0 man-sys-catman .cat
+./usr/share/man/cat4/swwdog.0 man-sys-catman .cat
./usr/share/man/cat4/sysbeep.0 man-sys-catman .cat
./usr/share/man/cat4/systrace.0 man-sys-catman .cat
./usr/share/man/cat4/tap.0 man-sys-catman .cat
@@ -3411,6 +3412,7 @@
./usr/share/man/man4/sun3/ms.4 man-sys-man .man
./usr/share/man/man4/sv.4 man-sys-man .man
./usr/share/man/man4/sw.4 man-sys-man .man
+./usr/share/man/man4/swwdog.4 man-sys-man .man
./usr/share/man/man4/sysbeep.4 man-sys-man .man
./usr/share/man/man4/systrace.4 man-sys-man .man
./usr/share/man/man4/tap.4 man-sys-man .man
diff -r 62e801bfb0a9 -r 0378484a60d5 sbin/wdogctl/wdogctl.8
--- a/sbin/wdogctl/wdogctl.8 Sun Jan 09 22:24:04 2005 +0000
+++ b/sbin/wdogctl/wdogctl.8 Sun Jan 09 22:51:32 2005 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: wdogctl.8,v 1.8 2003/02/25 10:35:12 wiz Exp $
+.\" $NetBSD: wdogctl.8,v 1.9 2005/01/09 22:51:32 smb Exp $
.\"
.\" Copyright (c) 2000 Zembu Labs, Inc.
.\" All rights reserved.
@@ -50,6 +50,13 @@
.Op Fl p Ar seconds
.Ar timer
.Nm
+.Fl e
+.Op Fl A
+.Op Fl p Ar seconds
+.Ar timer
+.Nm
+.Fl t
+.Nm
.Fl d
.Sh DESCRIPTION
.Nm
@@ -67,8 +74,8 @@
.Pp
The
.Nx
-kernel provides two basic modes in which watchdog timers may
-operate: kernel tickle mode and user tickle mode.
+kernel provides three basic modes in which watchdog timers may
+operate: kernel tickle mode, user tickle mode, and external tickle mode.
In kernel tickle mode, a timer in the kernel refreshes the watchdog timer.
In user tickle mode,
.Nm
@@ -80,8 +87,15 @@
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.
.Pp
-In both modes, an attempt is made to refresh the watchdog timer
+External-mode watchdogs are similar to user-mode watchdogs, except
+that the tickle must be done explicitly by a separate invocation of
+the program with the
+.Fl t
+option.
+.Pp
+In the first two modes, an attempt is made to refresh the watchdog timer
in one half the timer's configured period.
That is, if the watchdog timer has a period of 30 seconds, a refresh attempt
is made every 15 seconds.
@@ -107,6 +121,10 @@
Arm
.Ar timer
in user tickle mode.
+.It Fl e
+Arm
+.Ar timer
+in external tickle mode.
.It Fl A
When arming a timer, this flag indicates that an audible alarm is
to sound when the watchdog timer expires and resets the system.
@@ -124,6 +142,8 @@
If the selected timer can not be disabled,
an error message will be displayed and the
timer will remain armed.
+.It Fl t
+This flag tickles an external mode timer.
.El
.Sh FILES
.Pa /dev/watchdog
diff -r 62e801bfb0a9 -r 0378484a60d5 sbin/wdogctl/wdogctl.c
--- a/sbin/wdogctl/wdogctl.c Sun Jan 09 22:24:04 2005 +0000
+++ b/sbin/wdogctl/wdogctl.c Sun Jan 09 22:51:32 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $ */
+/* $NetBSD: wdogctl.c,v 1.11 2005/01/09 22:51:32 smb Exp $ */
/*-
* Copyright (c) 2000 Zembu Labs, Inc.
@@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $");
+__RCSID("$NetBSD: wdogctl.c,v 1.11 2005/01/09 22:51:32 smb Exp $");
#endif
@@ -59,47 +59,74 @@
int main(int, char *[]);
void enable_kernel(const char *, u_int);
void enable_user(const char *, u_int);
+void enable_ext(const char *, u_int);
+void tickle_ext(void);
void disable(void);
+void prep_wmode(struct wdog_mode *, int, const char *, u_int);
void list_timers(void);
void usage(void);
int Aflag;
+/* Caution -- ordered list; entries >= CMD_EXT_TICKLE set timers */
+enum cmd {
+ CMD_NONE, /* No verb given */
+ CMD_DISABLE,
+ CMD_DOTICKLE,
+ CMD_EXT_TICKLE,
+ CMD_KERN_TICKLE,
+ CMD_USER_TICKLE
+};
+
int
main(int argc, char *argv[])
{
- int cmds = 0, kflag = 0, uflag = 0, dflag = 0, ch;
+ enum cmd command = CMD_NONE;
+ int period_flag = 0;
+ int ch;
u_int period = WDOG_PERIOD_DEFAULT;
- while ((ch = getopt(argc, argv, "Adkp:u")) != -1) {
+ while ((ch = getopt(argc, argv, "Adekp:ut")) != -1) {
switch (ch) {
case 'A':
- if (cmds == 0 || dflag)
- usage();
Aflag = 1;
break;
case 'd':
- dflag = 1;
- cmds++;
+ if (command != CMD_NONE)
+ usage();
+ command = CMD_DISABLE;
+ break;
+
+ case 'e':
+ if (command != CMD_NONE)
+ usage();
+ command = CMD_EXT_TICKLE;
break;
case 'k':
- kflag = 1;
- cmds++;
+ if (command != CMD_NONE)
+ usage();
+ command = CMD_KERN_TICKLE;
+ break;
+
+ case 't':
+ if (command != CMD_NONE)
+ usage();
+ command = CMD_DOTICKLE;
break;
case 'p':
- if (cmds == 0 || dflag)
- usage();
+ period_flag = 1;
period = atoi(optarg);
if (period == -1)
usage();
break;
case 'u':
- uflag = 1;
- cmds++;
+ if (command != CMD_NONE)
+ usage();
+ command = CMD_USER_TICKLE;
break;
default:
@@ -110,41 +137,60 @@
argc -= optind;
argv += optind;
- if (cmds > 1)
- usage();
-
- if (kflag) {
- if (argc != 1)
+ if (command < CMD_EXT_TICKLE) {
+ if (Aflag || period_flag)
usage();
- enable_kernel(argv[0], period);
- } else if (uflag) {
+ if (argc != 0)
+ usage();
+ }
+ else {
if (argc != 1)
usage();
- enable_user(argv[0], period);
- } else if (dflag) {
- if (argc != 0)
- usage();
- disable();
- } else
- list_timers();
+ }
+ switch (command) {
+ case CMD_NONE:
+ list_timers();
+ break;
+ case CMD_DISABLE:
+ disable();
+ break;
+ case CMD_DOTICKLE:
+ tickle_ext();
+ break;
+ case CMD_EXT_TICKLE:
+ enable_ext(argv[0], period);
+ break;
+ case CMD_KERN_TICKLE:
+ enable_kernel(argv[0], period);
+ break;
+ case CMD_USER_TICKLE:
+ enable_user(argv[0], period);
+ break;
+ }
exit(0);
}
void
+prep_wmode(struct wdog_mode *wp, int mode, const char *name, u_int period)
+{
+ if (strlen(name) >= WDOG_NAMESIZE)
+ errx(1, "invalid watchdog timer name: %s", name);
+
+ strlcpy(wp->wm_name, name, sizeof(wp->wm_name));
+ wp->wm_mode = mode;
+ wp->wm_period = period;
+ if (Aflag)
+ wp->wm_mode |= WDOG_FEATURE_ALARM;
+}
+
+void
enable_kernel(const char *name, u_int period)
{
struct wdog_mode wm;
int fd;
- if (strlen(name) >= WDOG_NAMESIZE)
- errx(1, "invalid watchdog timer name: %s", name);
- strlcpy(wm.wm_name, name, sizeof(wm.wm_name));
- wm.wm_mode = WDOG_MODE_KTICKLE;
- wm.wm_period = period;
-
- if (Aflag)
- wm.wm_mode |= WDOG_FEATURE_ALARM;
+ prep_wmode(&wm, WDOG_MODE_KTICKLE, name, period);
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
if (fd == -1)
@@ -155,6 +201,26 @@
}
void
+enable_ext(const char *name, u_int period)
+{
+ struct wdog_mode wm;
+ int fd;
+
+ prep_wmode(&wm, WDOG_MODE_ETICKLE, name, period);
+
+ fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
+ if (fd == -1)
+ err(1, "open %s", _PATH_WATCHDOG);
+ if (ioctl(fd, WDOGIOC_SMODE, &wm) == -1) {
+ err(1, "WDOGIOC_SMODE");
Home |
Main Index |
Thread Index |
Old Index