Rename the WATCHDOG option to SW_WATCHDOG and make it use the
generic watchdoc(9) interface. Make watchdogd(8) perform as watchdog(8) as well, and make it possible to specify a check command to run, timeout and sleep periods. Update watchdog(4) to talk about the generic interface and add new watchdog(8) page.
This commit is contained in:
parent
2676fbe88c
commit
4103b7652d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=126383
@ -1,4 +1,4 @@
|
|||||||
|
.\" Copyright (c) 2004 Poul-Henning Kamp <phk@FreeBSD.org>
|
||||||
.\" Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org>
|
.\" Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org>
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -26,42 +26,49 @@
|
|||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 25, 2003
|
.Dd June 25, 2003
|
||||||
.Dt WATCHDOG 4
|
.Dt watchdog 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm watchdog
|
.Nm watchdog
|
||||||
.Nd Software watchdog
|
.Nd Hardware and Software watchdog
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Cd options WATCHDOG
|
.Cd options CPU_ELAN
|
||||||
|
.Cd options CPU_GEODE
|
||||||
|
.Cd options SW_WATCHDOG
|
||||||
|
.Pp
|
||||||
|
.In sys/watchdog.h
|
||||||
|
.Bd -literal
|
||||||
|
|
||||||
|
u_int u = WD_ACTIVE | WD_8SEC;
|
||||||
|
int fd = open("/dev/" _PATH_WATCHDOG, O_RDWR);
|
||||||
|
|
||||||
|
ioctl(fd, WDIOCPATPAT, &u);
|
||||||
|
.Ed
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
is a set of checks and routines which allow the implementation of a software
|
is a facility for controlling hardware and software watchdog facilities.
|
||||||
watchdog solution.
|
|
||||||
.Pp
|
.Pp
|
||||||
The user interface for
|
The interface is through a device named "/dev/" _PATH_WATCHDOG which
|
||||||
.Nm
|
responds to a single ioctl call, WDIOCPATPAT.
|
||||||
is implemented via a trio of sysctl OIDs.
|
.Pp
|
||||||
When
|
The ioctl call takes an argument which consists of a timeout value
|
||||||
.Li debug.watchdog.enabled
|
specified an integer power of two nanoseconds.
|
||||||
is set to a positive value,
|
.Pp
|
||||||
.Nm
|
In the flag WD_ACTIVE signals that the watchdog will be kept from
|
||||||
timeout checks are performed.
|
timing out from userland, for instance by the
|
||||||
In order to keep the watchdog from triggering,
|
.Xr watchdogd 8
|
||||||
.Li debug.watchdog.reset
|
daemon.
|
||||||
must be accessed,
|
.Pp
|
||||||
by reading or writing,
|
To disable the watchdogs, use an argument of zero.
|
||||||
within every
|
.Pp
|
||||||
.Li debug.watchdog.timeout
|
The ioctl call will return success if just one of the available
|
||||||
seconds.
|
watchdog implementations support the request.
|
||||||
Failure to keep the
|
If the ioctl fails, for instance if no watchdog supports the timeout
|
||||||
.Nm
|
length, all watchdogs are disabled and must be explicitly reenabled.
|
||||||
updated will result in the kernel outputting interrupt counts,
|
|
||||||
backtraces,
|
|
||||||
and then attempting to enter
|
|
||||||
.Xr ddb 9 .
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr sysctl 8 ,
|
.Xr sysctl 8 ,
|
||||||
.Xr watchdogd 8
|
.Xr watchdogd 8
|
||||||
|
.Xr watchdogd 9
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
@ -70,7 +77,12 @@ code first appeared in
|
|||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An -nosplit
|
.An -nosplit
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm watchdog
|
||||||
|
facility were written by
|
||||||
|
.An Poul-Henning Kamp Aq phk@FreeBSD.org .
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Nm SW_WATCHDOG
|
||||||
code and manual page were written by
|
code and manual page were written by
|
||||||
.An Sean Kelly Aq smkelly@FreeBSD.org .
|
.An Sean Kelly Aq smkelly@FreeBSD.org .
|
||||||
Some contributions were made by
|
Some contributions were made by
|
||||||
|
@ -2089,11 +2089,9 @@ options BOOTP_WIRED_TO=fxp0 # Use interface fxp0 for BOOTP
|
|||||||
options HW_WDOG
|
options HW_WDOG
|
||||||
|
|
||||||
#
|
#
|
||||||
# Add software watchdog routines. This will add some sysctl OIDs that
|
# Add software watchdog routines.
|
||||||
# can be used in combination with an external daemon to create a
|
|
||||||
# software-based watchdog solution.
|
|
||||||
#
|
#
|
||||||
options WATCHDOG
|
options SW_WATCHDOG
|
||||||
|
|
||||||
#
|
#
|
||||||
# Disable swapping of upages and stack pages. This option removes all
|
# Disable swapping of upages and stack pages. This option removes all
|
||||||
|
@ -153,9 +153,9 @@ SHMSEG opt_sysvipc.h
|
|||||||
SYSVMSG opt_sysvipc.h
|
SYSVMSG opt_sysvipc.h
|
||||||
SYSVSEM opt_sysvipc.h
|
SYSVSEM opt_sysvipc.h
|
||||||
SYSVSHM opt_sysvipc.h
|
SYSVSHM opt_sysvipc.h
|
||||||
|
SW_WATCHDOG opt_watchdog.h
|
||||||
TTYHOG opt_tty.h
|
TTYHOG opt_tty.h
|
||||||
VFS_AIO
|
VFS_AIO
|
||||||
WATCHDOG opt_watchdog.h
|
|
||||||
WLCACHE opt_wavelan.h
|
WLCACHE opt_wavelan.h
|
||||||
WLDEBUG opt_wavelan.h
|
WLDEBUG opt_wavelan.h
|
||||||
|
|
||||||
|
@ -90,21 +90,14 @@ long cp_time[CPUSTATES];
|
|||||||
SYSCTL_OPAQUE(_kern, OID_AUTO, cp_time, CTLFLAG_RD, &cp_time, sizeof(cp_time),
|
SYSCTL_OPAQUE(_kern, OID_AUTO, cp_time, CTLFLAG_RD, &cp_time, sizeof(cp_time),
|
||||||
"LU", "CPU time statistics");
|
"LU", "CPU time statistics");
|
||||||
|
|
||||||
#ifdef WATCHDOG
|
#ifdef SW_WATCHDOG
|
||||||
static int sysctl_watchdog_reset(SYSCTL_HANDLER_ARGS);
|
#include <sys/watchdog.h>
|
||||||
static void watchdog_fire(void);
|
|
||||||
|
|
||||||
|
static int watchdog_ticks;
|
||||||
static int watchdog_enabled;
|
static int watchdog_enabled;
|
||||||
static unsigned int watchdog_ticks;
|
static void watchdog_fire(void);
|
||||||
static int watchdog_timeout = 20;
|
static void watchdog_config(void *, u_int, int *);
|
||||||
|
#endif /* SW_WATCHDOG */
|
||||||
SYSCTL_NODE(_debug, OID_AUTO, watchdog, CTLFLAG_RW, 0, "System watchdog");
|
|
||||||
SYSCTL_INT(_debug_watchdog, OID_AUTO, enabled, CTLFLAG_RW, &watchdog_enabled,
|
|
||||||
0, "Enable the watchdog");
|
|
||||||
SYSCTL_INT(_debug_watchdog, OID_AUTO, timeout, CTLFLAG_RW, &watchdog_timeout,
|
|
||||||
0, "Timeout for watchdog checkins");
|
|
||||||
|
|
||||||
#endif /* WATCHDOG */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clock handling routines.
|
* Clock handling routines.
|
||||||
@ -167,6 +160,9 @@ initclocks(dummy)
|
|||||||
if (profhz == 0)
|
if (profhz == 0)
|
||||||
profhz = i;
|
profhz = i;
|
||||||
psratio = profhz / i;
|
psratio = profhz / i;
|
||||||
|
#ifdef SW_WATCHDOG
|
||||||
|
EVENTHANDLER_REGISTER(watchdog_list, watchdog_config, NULL, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -251,11 +247,10 @@ hardclock(frame)
|
|||||||
if (need_softclock)
|
if (need_softclock)
|
||||||
swi_sched(softclock_ih, 0);
|
swi_sched(softclock_ih, 0);
|
||||||
|
|
||||||
#ifdef WATCHDOG
|
#ifdef SW_WATCHDOG
|
||||||
if (watchdog_enabled > 0 &&
|
if (watchdog_enabled > 0 && --watchdog_ticks <= 0)
|
||||||
(int)(ticks - watchdog_ticks) >= (hz * watchdog_timeout))
|
|
||||||
watchdog_fire();
|
watchdog_fire();
|
||||||
#endif /* WATCHDOG */
|
#endif /* SW_WATCHDOG */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -508,24 +503,25 @@ SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD,
|
|||||||
0, 0, sysctl_kern_clockrate, "S,clockinfo",
|
0, 0, sysctl_kern_clockrate, "S,clockinfo",
|
||||||
"Rate and period of various kernel clocks");
|
"Rate and period of various kernel clocks");
|
||||||
|
|
||||||
#ifdef WATCHDOG
|
#ifdef SW_WATCHDOG
|
||||||
/*
|
|
||||||
* Reset the watchdog timer to ticks, thus preventing the watchdog
|
static void
|
||||||
* from firing for another watchdog timeout period.
|
watchdog_config(void *unused __unused, u_int cmd, int *err)
|
||||||
*/
|
|
||||||
static int
|
|
||||||
sysctl_watchdog_reset(SYSCTL_HANDLER_ARGS)
|
|
||||||
{
|
{
|
||||||
int ret;
|
u_int u;
|
||||||
|
|
||||||
ret = 0;
|
if (cmd) {
|
||||||
watchdog_ticks = ticks;
|
u = cmd & WD_INTERVAL;
|
||||||
return sysctl_handle_int(oidp, &ret, 0, req);
|
if (u < WD_TO_1SEC)
|
||||||
|
return;
|
||||||
|
watchdog_ticks = (1 << (u - WD_TO_1SEC)) * hz;
|
||||||
|
watchdog_enabled = 1;
|
||||||
|
*err = 0;
|
||||||
|
} else {
|
||||||
|
watchdog_enabled = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SYSCTL_PROC(_debug_watchdog, OID_AUTO, reset, CTLFLAG_RW, 0, 0,
|
|
||||||
sysctl_watchdog_reset, "I", "Reset the watchdog");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle a watchdog timeout by dumping interrupt information and
|
* Handle a watchdog timeout by dumping interrupt information and
|
||||||
* then either dropping to DDB or panicing.
|
* then either dropping to DDB or panicing.
|
||||||
@ -560,4 +556,4 @@ watchdog_fire(void)
|
|||||||
#endif /* DDB */
|
#endif /* DDB */
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WATCHDOG */
|
#endif /* SW_WATCHDOG */
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
# $FreeBSD$
|
# $FreeBSD$
|
||||||
|
|
||||||
PROG= watchdogd
|
PROG= watchdogd
|
||||||
MAN= watchdogd.8
|
LINKS= ${BINDIR}/watchdogd ${BINDIR}/watchdog
|
||||||
|
MAN= watchdogd.8 watchdog.8
|
||||||
WARNS?= 6
|
WARNS?= 6
|
||||||
|
|
||||||
|
LDADD= -lm
|
||||||
|
DPADD= ${LIBM}
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
||||||
|
test: ${PROG}
|
||||||
|
./${PROG} -t 1.0
|
||||||
|
66
usr.sbin/watchdogd/watchdog.8
Normal file
66
usr.sbin/watchdogd/watchdog.8
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
.\" Copyright (c) 2004 Poul-Henning Kamp <phk@FreeBSD.org>
|
||||||
|
.\" Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org>
|
||||||
|
.\" 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.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||||
|
.\"
|
||||||
|
.\" $FreeBSD$
|
||||||
|
.\"
|
||||||
|
.Dd February 28, 2004
|
||||||
|
.Dt WATCHDOG 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm watchdog
|
||||||
|
.Nd watchdog control program
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Op Fl d
|
||||||
|
.Op Fl t Ar timeout
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility can be used to control the kernels watchdog facility.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl t Ar timeout
|
||||||
|
specifies the desired timeout period in seconds, a value of
|
||||||
|
zero will disable the watchdog.
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr watchdogd 8 ,
|
||||||
|
.Xr watchdog 4 ,
|
||||||
|
.Xr watchdog 9 ,
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility and manual page were written by
|
||||||
|
.An Sean Kelly Aq smkelly@FreeBSD.org
|
||||||
|
and
|
||||||
|
.An Poul-Henning Kamp Aq phk@FreeBSD.org
|
||||||
|
.Pp
|
||||||
|
Some contributions made by
|
||||||
|
.An Jeff Roberson Aq jeff@FreeBSD.org .
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility appeared in
|
||||||
|
.Fx 5.1 .
|
@ -1,3 +1,4 @@
|
|||||||
|
.\" Copyright (c) 2004 Poul-Henning Kamp <phk@FreeBSD.org>
|
||||||
.\" Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org>
|
.\" Copyright (c) 2003 Sean M. Kelly <smkelly@FreeBSD.org>
|
||||||
.\" All rights reserved.
|
.\" All rights reserved.
|
||||||
.\"
|
.\"
|
||||||
@ -29,21 +30,46 @@
|
|||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm watchdogd
|
.Nm watchdogd
|
||||||
.Nd Software watchdog daemon
|
.Nd Watchdog daemon
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl d
|
.Op Fl d
|
||||||
|
.Op Fl e Ar cmd
|
||||||
.Op Fl I Ar file
|
.Op Fl I Ar file
|
||||||
|
.Op Fl s Ar sleep
|
||||||
|
.Op Fl t Ar timeout
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility interfaces with the kernel's software watchdog facility to ensure
|
utility interfaces with the kernel's watchdog facility to ensure
|
||||||
that the system is in a working state.
|
that the system is in a working state.
|
||||||
If
|
If
|
||||||
.Nm
|
.Nm
|
||||||
is unable to interface with the kernel over a specific timeout,
|
is unable to interface with the kernel over a specific timeout,
|
||||||
the kernel will take actions to assist in debugging or restarting the computer.
|
the kernel will take actions to assist in debugging or restarting the computer.
|
||||||
.Pp
|
.Pp
|
||||||
|
If
|
||||||
|
.Fl e Ar cmd
|
||||||
|
is specified,
|
||||||
|
.Nm
|
||||||
|
will attempt to execute this command with
|
||||||
|
.Xr system 3
|
||||||
|
and only if the command returns with a zero exit code will the
|
||||||
|
watchdog be reset.
|
||||||
|
If
|
||||||
|
.Fl e Ar cmd
|
||||||
|
is not specified the daemon will perform a trivial filesystem
|
||||||
|
check instead.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl -s Ar sleep
|
||||||
|
argument can be used to control the sleep period between each execution
|
||||||
|
of the check and defaults to one second.
|
||||||
|
.Pp
|
||||||
|
The
|
||||||
|
.Fl -t Ar timeout
|
||||||
|
specifies the desired timeout period in seconds.
|
||||||
|
.Pp
|
||||||
One possible circumstance which will cause a watchdog timeout is an interrupt
|
One possible circumstance which will cause a watchdog timeout is an interrupt
|
||||||
storm.
|
storm.
|
||||||
If this occurs,
|
If this occurs,
|
||||||
@ -80,13 +106,16 @@ will not fork into the background at startup.
|
|||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr watchdog 4 ,
|
.Xr watchdog 4 ,
|
||||||
.Xr sysctl 8
|
.Xr watchdog 8 ,
|
||||||
|
.Xr watchdog 9 ,
|
||||||
.Sh AUTHORS
|
.Sh AUTHORS
|
||||||
.An -nosplit
|
.An -nosplit
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
utility and manual page were written by
|
utility and manual page were written by
|
||||||
.An Sean Kelly Aq smkelly@FreeBSD.org .
|
.An Sean Kelly Aq smkelly@FreeBSD.org
|
||||||
|
and
|
||||||
|
.An Poul-Henning Kamp Aq phk@FreeBSD.org .
|
||||||
.Pp
|
.Pp
|
||||||
Some contributions made by
|
Some contributions made by
|
||||||
.An Jeff Roberson Aq jeff@FreeBSD.org .
|
.An Jeff Roberson Aq jeff@FreeBSD.org .
|
||||||
|
@ -35,12 +35,17 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/watchdog.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <math.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -49,7 +54,7 @@ static void sighandler(int);
|
|||||||
static void watchdog_loop(void);
|
static void watchdog_loop(void);
|
||||||
static int watchdog_init(void);
|
static int watchdog_init(void);
|
||||||
static int watchdog_onoff(int onoff);
|
static int watchdog_onoff(int onoff);
|
||||||
static int watchdog_tickle(void);
|
static int watchdog_patpat(void);
|
||||||
static void usage(void);
|
static void usage(void);
|
||||||
|
|
||||||
int debugging = 0;
|
int debugging = 0;
|
||||||
@ -57,6 +62,12 @@ int end_program = 0;
|
|||||||
const char *pidfile = _PATH_VARRUN "watchdogd.pid";
|
const char *pidfile = _PATH_VARRUN "watchdogd.pid";
|
||||||
int reset_mib[3];
|
int reset_mib[3];
|
||||||
size_t reset_miblen = 3;
|
size_t reset_miblen = 3;
|
||||||
|
u_int timeout = WD_TO_16SEC;
|
||||||
|
u_int passive = 0;
|
||||||
|
int is_daemon = 0;
|
||||||
|
int fd = -1;
|
||||||
|
int nap = 1;
|
||||||
|
char *test_cmd = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Periodically write to the debug.watchdog.reset sysctl OID
|
* Periodically write to the debug.watchdog.reset sysctl OID
|
||||||
@ -81,30 +92,40 @@ main(int argc, char *argv[])
|
|||||||
if (watchdog_init() == -1)
|
if (watchdog_init() == -1)
|
||||||
errx(EX_SOFTWARE, "unable to initialize watchdog");
|
errx(EX_SOFTWARE, "unable to initialize watchdog");
|
||||||
|
|
||||||
if (watchdog_onoff(1) == -1)
|
if (is_daemon) {
|
||||||
exit(EX_SOFTWARE);
|
if (watchdog_onoff(1) == -1)
|
||||||
|
exit(EX_SOFTWARE);
|
||||||
|
|
||||||
if (debugging == 0 && daemon(0, 0) == -1) {
|
if (debugging == 0 && daemon(0, 0) == -1) {
|
||||||
|
watchdog_onoff(0);
|
||||||
|
err(EX_OSERR, "daemon");
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGHUP, SIG_IGN);
|
||||||
|
signal(SIGINT, sighandler);
|
||||||
|
signal(SIGTERM, sighandler);
|
||||||
|
|
||||||
|
fp = fopen(pidfile, "w");
|
||||||
|
if (fp != NULL) {
|
||||||
|
fprintf(fp, "%d\n", getpid());
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
watchdog_loop();
|
||||||
|
|
||||||
|
/* exiting */
|
||||||
watchdog_onoff(0);
|
watchdog_onoff(0);
|
||||||
err(EX_OSERR, "daemon");
|
unlink(pidfile);
|
||||||
|
return (EX_OK);
|
||||||
|
} else {
|
||||||
|
if (passive)
|
||||||
|
timeout |= WD_PASSIVE;
|
||||||
|
else
|
||||||
|
timeout |= WD_ACTIVE;
|
||||||
|
if (watchdog_patpat() < 0)
|
||||||
|
err(EX_OSERR, "patting the dog");
|
||||||
|
return (EX_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGHUP, SIG_IGN);
|
|
||||||
signal(SIGINT, sighandler);
|
|
||||||
signal(SIGTERM, sighandler);
|
|
||||||
|
|
||||||
fp = fopen(pidfile, "w");
|
|
||||||
if (fp != NULL) {
|
|
||||||
fprintf(fp, "%d\n", getpid());
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
watchdog_loop();
|
|
||||||
|
|
||||||
/* exiting */
|
|
||||||
watchdog_onoff(0);
|
|
||||||
unlink(pidfile);
|
|
||||||
return (EX_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -125,15 +146,12 @@ sighandler(int signum)
|
|||||||
static int
|
static int
|
||||||
watchdog_init()
|
watchdog_init()
|
||||||
{
|
{
|
||||||
int error;
|
|
||||||
|
|
||||||
error = sysctlnametomib("debug.watchdog.reset", reset_mib,
|
fd = open("/dev/" _PATH_WATCHDOG, O_RDWR);
|
||||||
&reset_miblen);
|
if (fd >= 0)
|
||||||
if (error == -1) {
|
return (0);
|
||||||
warn("could not find reset OID");
|
warn("Could not open watchdog device");
|
||||||
return (error);
|
return (-1);
|
||||||
}
|
|
||||||
return watchdog_tickle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -148,11 +166,14 @@ watchdog_loop(void)
|
|||||||
while (end_program == 0) {
|
while (end_program == 0) {
|
||||||
failed = 0;
|
failed = 0;
|
||||||
|
|
||||||
failed = stat("/etc", &sb);
|
if (test_cmd != NULL)
|
||||||
|
failed = system(test_cmd);
|
||||||
|
else
|
||||||
|
failed = stat("/etc", &sb);
|
||||||
|
|
||||||
if (failed == 0)
|
if (failed == 0)
|
||||||
watchdog_tickle();
|
watchdog_patpat();
|
||||||
sleep(1);
|
sleep(nap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,10 +182,10 @@ watchdog_loop(void)
|
|||||||
* to keep the watchdog from firing.
|
* to keep the watchdog from firing.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
watchdog_tickle(void)
|
watchdog_patpat(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
return sysctl(reset_mib, reset_miblen, NULL, NULL, NULL, 0);
|
return ioctl(fd, WDIOCPATPAT, &timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,22 +195,12 @@ watchdog_tickle(void)
|
|||||||
static int
|
static int
|
||||||
watchdog_onoff(int onoff)
|
watchdog_onoff(int onoff)
|
||||||
{
|
{
|
||||||
int mib[3];
|
|
||||||
int error;
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
len = 3;
|
if (onoff)
|
||||||
|
timeout |= WD_ACTIVE;
|
||||||
error = sysctlnametomib("debug.watchdog.enabled", mib, &len);
|
else
|
||||||
if (error == 0)
|
timeout &= ~WD_ACTIVE;
|
||||||
error = sysctl(mib, len, NULL, NULL, &onoff, sizeof(onoff));
|
return watchdog_patpat();
|
||||||
|
|
||||||
if (error == -1) {
|
|
||||||
warn("could not %s watchdog",
|
|
||||||
(onoff > 0) ? "enable" : "disable");
|
|
||||||
return (error);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -198,7 +209,10 @@ watchdog_onoff(int onoff)
|
|||||||
static void
|
static void
|
||||||
usage()
|
usage()
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: watchdogd [-d] [-I file]\n");
|
if (is_daemon)
|
||||||
|
fprintf(stderr, "usage: watchdogd [-d] [-e cmd] [-I file]\n");
|
||||||
|
else
|
||||||
|
fprintf(stderr, "usage: watchdog [-d] [-t]\n");
|
||||||
exit(EX_USAGE);
|
exit(EX_USAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,8 +223,14 @@ static void
|
|||||||
parseargs(int argc, char *argv[])
|
parseargs(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
char *p;
|
||||||
|
double a;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv, "I:d?")) != -1) {
|
c = strlen(argv[0]);
|
||||||
|
if (argv[0][c - 1] == 'd')
|
||||||
|
is_daemon = 1;
|
||||||
|
while ((c = getopt(argc, argv,
|
||||||
|
is_daemon ? "I:de:s:t:?" : "dt:?")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'I':
|
case 'I':
|
||||||
pidfile = optarg;
|
pidfile = optarg;
|
||||||
@ -218,10 +238,43 @@ parseargs(int argc, char *argv[])
|
|||||||
case 'd':
|
case 'd':
|
||||||
debugging = 1;
|
debugging = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'e':
|
||||||
|
test_cmd = strdup(optarg);
|
||||||
|
break;
|
||||||
|
#ifdef notyet
|
||||||
|
case 'p':
|
||||||
|
passive = 1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 's':
|
||||||
|
p = NULL;
|
||||||
|
errno = 0;
|
||||||
|
nap = strtol(optarg, &p, 0);
|
||||||
|
if ((p != NULL && *p != '\0') || errno != 0)
|
||||||
|
errx(EX_USAGE, "-s argument is not a number");
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
p = NULL;
|
||||||
|
errno = 0;
|
||||||
|
a = strtod(optarg, &p);
|
||||||
|
if ((p != NULL && *p != '\0') || errno != 0)
|
||||||
|
errx(EX_USAGE, "-t argument is not a number");
|
||||||
|
if (a < 0)
|
||||||
|
errx(EX_USAGE, "-t argument must be positive");
|
||||||
|
if (a == 0)
|
||||||
|
timeout = WD_TO_NEVER;
|
||||||
|
else
|
||||||
|
timeout = 1.0 + log(a * 1e9) / log(2.0);
|
||||||
|
if (debugging)
|
||||||
|
printf("Timeout is 2^%d nanoseconds\n",
|
||||||
|
timeout);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (is_daemon && timeout < WD_TO_1SEC)
|
||||||
|
errx(EX_USAGE, "-t argument is less than one second.");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user