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@.
This commit is contained in:
parent
f26774eaee
commit
ddd2ade252
|
@ -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
|
||||
|
|
|
@ -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 @@ something must refresh the timer to prevent it from expiring.
|
|||
.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 @@ Note that user tickle mode must be used with caution;
|
|||
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 @@ in kernel tickle mode.
|
|||
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 @@ Note that not all watchdog timers can be disabled once armed.
|
|||
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
|
||||
|
|
|
@ -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 @@ __RCSID("$NetBSD: wdogctl.c,v 1.10 2004/01/05 23:23:34 jmmv Exp $");
|
|||
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 @@ main(int argc, char *argv[])
|
|||
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 != 1)
|
||||
usage();
|
||||
enable_user(argv[0], period);
|
||||
} else if (dflag) {
|
||||
if (argc != 0)
|
||||
usage();
|
||||
disable();
|
||||
} else
|
||||
list_timers();
|
||||
}
|
||||
else {
|
||||
if (argc != 1)
|
||||
usage();
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -154,6 +200,26 @@ enable_kernel(const char *name, u_int period)
|
|||
err(1, "WDOGIOC_SMODE");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
if (ioctl(fd, WDOGIOC_TICKLE) == -1)
|
||||
syslog(LOG_EMERG, "unable to tickle watchdog timer %s: %m",
|
||||
wm.wm_name);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
enable_user(const char *name, u_int period)
|
||||
{
|
||||
|
@ -162,14 +228,7 @@ enable_user(const char *name, u_int period)
|
|||
pid_t tickler;
|
||||
int fd, rv;
|
||||
|
||||
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_UTICKLE;
|
||||
wm.wm_period = period;
|
||||
|
||||
if (Aflag)
|
||||
wm.wm_mode |= WDOG_FEATURE_ALARM;
|
||||
prep_wmode(&wm, WDOG_MODE_UTICKLE, name, period);
|
||||
|
||||
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
|
||||
if (fd == -1)
|
||||
|
@ -243,6 +302,18 @@ enable_user(const char *name, u_int period)
|
|||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
void
|
||||
tickle_ext()
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(_PATH_WATCHDOG, O_RDWR, 0644);
|
||||
if (fd == -1)
|
||||
err(1, "open %s", _PATH_WATCHDOG);
|
||||
if (ioctl(fd, WDOGIOC_TICKLE) == -1)
|
||||
fprintf(stderr, "Cannot tickle timer\n");
|
||||
}
|
||||
|
||||
void
|
||||
disable(void)
|
||||
{
|
||||
|
@ -332,12 +403,19 @@ list_timers(void)
|
|||
|
||||
printf("\t%s, %u second period", cp, wm.wm_period);
|
||||
if (wm.wm_mode != WDOG_MODE_DISARMED) {
|
||||
printf(" [armed, %s tickle",
|
||||
wm.wm_mode == WDOG_MODE_KTICKLE ?
|
||||
"kernel" : "user");
|
||||
if (wm.wm_mode == WDOG_MODE_UTICKLE &&
|
||||
tickler != (pid_t) -1)
|
||||
printf(", pid %d", tickler);
|
||||
switch(wm.wm_mode) {
|
||||
case WDOG_MODE_KTICKLE:
|
||||
printf(" [armed, kernel tickle");
|
||||
break;
|
||||
case WDOG_MODE_UTICKLE:
|
||||
printf(" [armed, user tickle");
|
||||
if (tickler != (pid_t) -1)
|
||||
printf(", pid %d", tickler);
|
||||
break;
|
||||
case WDOG_MODE_ETICKLE:
|
||||
printf(" [armed, external tickle");
|
||||
break;
|
||||
}
|
||||
printf("]");
|
||||
}
|
||||
printf("\n");
|
||||
|
@ -350,10 +428,13 @@ void
|
|||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s\n", getprogname());
|
||||
fprintf(stderr, " %s -e [-A] [-p seconds] timer\n",
|
||||
getprogname());
|
||||
fprintf(stderr, " %s -k [-A] [-p seconds] timer\n",
|
||||
getprogname());
|
||||
fprintf(stderr, " %s -u [-A] [-p seconds] timer\n",
|
||||
getprogname());
|
||||
fprintf(stderr, " %s -t\n", getprogname());
|
||||
fprintf(stderr, " %s -d\n", getprogname());
|
||||
|
||||
exit(1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.343 2005/01/08 22:29:38 cube Exp $
|
||||
# $NetBSD: Makefile,v 1.344 2005/01/09 22:51:32 smb Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
|
||||
MAN= aac.4 acardide.4 aceride.4 acphy.4 adc.4 adv.4 \
|
||||
|
@ -33,8 +33,8 @@ MAN= aac.4 acardide.4 aceride.4 acphy.4 adc.4 adv.4 \
|
|||
raid.4 ray.4 rcons.4 re.4 rnd.4 route.4 rtk.4 satalink.4 \
|
||||
sbus.4 scc.4 scsi.4 sd.4 se.4 ses.4 sf.4 sfb.4 shb.4 \
|
||||
siop.4 sip.4 siside.4 sk.4 sl.4 slide.4 \
|
||||
sm.4 spc.4 speaker.4 spif.4 spp.4 sqphy.4 \
|
||||
ss.4 st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 systrace.4 \
|
||||
sm.4 spc.4 speaker.4 spif.4 spp.4 sqphy.4 ss.4 \
|
||||
st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 swwdog.4 systrace.4 \
|
||||
tap.4 tb.4 tc.4 tcds.4 tcp.4 termios.4 tfb.4 ti.4 \
|
||||
tl.4 tlp.4 tlphy.4 tp.4 tr.4 trm.4 tty.4 tun.4 \
|
||||
tqphy.4 twe.4 txp.4 ubsec.4 udp.4 uep.4 uha.4 uk.4 ukphy.4 \
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
.\" $NetBSD: swwdog.4,v 1.1 2005/01/09 22:51:32 smb Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2004, 2005 Steven M. Bellovin
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the NetBSD
|
||||
.\" Foundation, Inc. and its contributors.
|
||||
.\" 4. Neither the name of the author nor the names of its
|
||||
.\" contributors may be used to endorse or promote products derived
|
||||
.\" from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd 6 January 2005
|
||||
.\" Written by Steven M. Bellovin
|
||||
.Dt SWDOG 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm swwdog
|
||||
.Nd software watchdog timer
|
||||
.Sh SYNOPSIS
|
||||
.Cd "pseudo-device cgd" Op Ar count
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
driver provides a software watchdog timer that works with
|
||||
.Xr wdogctl 8 .
|
||||
If the timer expires, the system reboots unless the variable
|
||||
.Va swwdog_panic
|
||||
is non-zero; if it is, the system will panic instead.
|
||||
.Pp
|
||||
The default period of
|
||||
.Nm
|
||||
is 60 seconds.
|
||||
.Sh SEE ALSO
|
||||
.Xr wdogctl 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver was written by Steven M. Bellovin
|
||||
.Sh BUGS
|
||||
Although more than one
|
||||
.Nm
|
||||
timer can be configured, it's a pointless thing to do, since only
|
||||
one watchdog timer can be active at any given time. Arguably, this
|
||||
is a bug in the watchdog timer framework.
|
||||
.Pp
|
||||
Kernel tickle mode is useless with
|
||||
.Nm
|
||||
and arguably should be rejected, since both it and
|
||||
this driver rely on the same callout mechanism; if one is
|
||||
blocked, almost certainly the other is as well.
|
||||
.Pp
|
||||
The alarm option to
|
||||
.Xr wdogctl 8
|
||||
isn't implemented.
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.sysmon,v 1.3 2003/04/20 20:20:35 thorpej Exp $
|
||||
# $NetBSD: files.sysmon,v 1.4 2005/01/09 22:51:32 smb Exp $
|
||||
|
||||
define sysmon_envsys
|
||||
file dev/sysmon/sysmon_envsys.c sysmon_envsys needs-flag
|
||||
|
@ -14,3 +14,7 @@ file dev/sysmon/sysmon.c sysmon_envsys | sysmon_wdog |
|
|||
|
||||
define sysmon_taskq
|
||||
file dev/sysmon/sysmon_taskq.c sysmon_taskq
|
||||
|
||||
defpseudo swwdog: sysmon_wdog
|
||||
file dev/sysmon/swwdog.c swwdog needs-count
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
/* $NetBSD: swwdog.c,v 1.1 2005/01/09 22:51:32 smb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Steven M. Bellovin
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Steven M. Bellovin
|
||||
* 4. The name of the author contributors may not be used to endorse or
|
||||
* promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: swwdog.c,v 1.1 2005/01/09 22:51:32 smb Exp $");
|
||||
|
||||
/*
|
||||
*
|
||||
* Software watchdog timer
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/callout.h>
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/wdog.h>
|
||||
#include <dev/sysmon/sysmonvar.h>
|
||||
|
||||
#include "swwdog.h"
|
||||
|
||||
struct swwdog_softc {
|
||||
struct sysmon_wdog sc_smw;
|
||||
struct callout sc_c;
|
||||
char sc_name[20];
|
||||
int sc_wdog_armed;
|
||||
} sc_wdog[NSWWDOG];
|
||||
|
||||
void swwdogattach(int);
|
||||
|
||||
static int swwdog_setmode(struct sysmon_wdog *);
|
||||
static int swwdog_tickle(struct sysmon_wdog *);
|
||||
|
||||
static int swwdog_arm(struct swwdog_softc *);
|
||||
static int swwdog_disarm(struct swwdog_softc *);
|
||||
|
||||
static void swwdog_panic(void *);
|
||||
|
||||
int swwdog_reboot = 0; /* set for panic instead of reboot */
|
||||
|
||||
#define SWDOG_DEFAULT 60 /* 60-second default period */
|
||||
|
||||
void
|
||||
swwdogattach(int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NSWWDOG; i++) {
|
||||
struct swwdog_softc *sc = &sc_wdog[i];
|
||||
|
||||
snprintf(sc->sc_name, sizeof sc->sc_name, "swwdog%d", i);
|
||||
printf("%s: ", sc->sc_name);
|
||||
sc->sc_smw.smw_name = sc->sc_name;
|
||||
sc->sc_smw.smw_cookie = sc;
|
||||
sc->sc_smw.smw_setmode = swwdog_setmode;
|
||||
sc->sc_smw.smw_tickle = swwdog_tickle;
|
||||
sc->sc_smw.smw_period = SWDOG_DEFAULT;
|
||||
callout_init(&sc->sc_c);
|
||||
callout_setfunc(&sc->sc_c, swwdog_panic, sc);
|
||||
|
||||
if (sysmon_wdog_register(&sc->sc_smw) == 0)
|
||||
printf("software watchdog initialized\n");
|
||||
else printf("unable to register software watchdog "
|
||||
"with sysmon\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
swwdog_setmode(struct sysmon_wdog *smw)
|
||||
{
|
||||
struct swwdog_softc *sc = smw->smw_cookie;
|
||||
int error = 0;
|
||||
|
||||
if ((smw->smw_mode & WDOG_MODE_MASK) == WDOG_MODE_DISARMED) {
|
||||
error = swwdog_disarm(sc);
|
||||
} else {
|
||||
if (smw->smw_period == 0)
|
||||
return EINVAL;
|
||||
else if (smw->smw_period == WDOG_PERIOD_DEFAULT)
|
||||
sc->sc_smw.smw_period = SWDOG_DEFAULT;
|
||||
else sc->sc_smw.smw_period = smw->smw_period;
|
||||
error = swwdog_arm(sc);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
swwdog_tickle(struct sysmon_wdog *smw)
|
||||
{
|
||||
|
||||
return swwdog_arm(smw->smw_cookie);
|
||||
}
|
||||
|
||||
static int
|
||||
swwdog_arm(struct swwdog_softc *sc)
|
||||
{
|
||||
|
||||
callout_schedule(&sc->sc_c, sc->sc_smw.smw_period * hz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
swwdog_disarm(struct swwdog_softc *sc)
|
||||
{
|
||||
|
||||
callout_stop(&sc->sc_c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
swwdog_panic(void *vsc)
|
||||
{
|
||||
struct swwdog_softc *sc = vsc;
|
||||
int do_panic;
|
||||
|
||||
do_panic = swwdog_reboot;
|
||||
swwdog_reboot = 1;
|
||||
callout_schedule(&sc->sc_c, 60 * hz); /* deliberate double-panic */
|
||||
|
||||
printf("%s: %d second timer expired", sc->sc_name,
|
||||
sc->sc_smw.smw_period);
|
||||
|
||||
if (do_panic)
|
||||
panic("watchdog timer expired");
|
||||
else cpu_reboot(0, NULL);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sysmon_wdog.c,v 1.9 2003/10/30 01:58:18 simonb Exp $ */
|
||||
/* $NetBSD: sysmon_wdog.c,v 1.10 2005/01/09 22:51:32 smb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
|
@ -41,7 +41,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.9 2003/10/30 01:58:18 simonb Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: sysmon_wdog.c,v 1.10 2005/01/09 22:51:32 smb Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -382,6 +382,7 @@ sysmon_wdog_setmode(struct sysmon_wdog *smw, int mode, u_int period)
|
|||
|
||||
case WDOG_MODE_KTICKLE:
|
||||
case WDOG_MODE_UTICKLE:
|
||||
case WDOG_MODE_ETICKLE:
|
||||
if (sysmon_armed_wdog != NULL) {
|
||||
error = EBUSY;
|
||||
goto out;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdog.h,v 1.1 2000/11/04 18:33:33 thorpej Exp $ */
|
||||
/* $NetBSD: wdog.h,v 1.2 2005/01/09 22:55:35 smb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 Zembu Labs, Inc.
|
||||
|
@ -93,6 +93,7 @@ struct wdog_conf {
|
|||
#define WDOG_MODE_DISARMED 0 /* watchdog is disarmed */
|
||||
#define WDOG_MODE_KTICKLE 1 /* kernel tickles watchdog */
|
||||
#define WDOG_MODE_UTICKLE 2 /* user tickles watchdog */
|
||||
#define WDOG_MODE_ETICKLE 3 /* external program tickles watchdog */
|
||||
|
||||
#define WDOG_MODE_MASK 0x03
|
||||
|
||||
|
|
Loading…
Reference in New Issue