diff options
author | Marc Balmer <mbalmer@cvs.openbsd.org> | 2005-08-08 12:08:57 +0000 |
---|---|---|
committer | Marc Balmer <mbalmer@cvs.openbsd.org> | 2005-08-08 12:08:57 +0000 |
commit | a22286a7f69eeaeb793ca17852f88268a6951733 (patch) | |
tree | 23e77c8b25a7690ddd617f2fe448c1467b962fc7 | |
parent | 1e13aa819e750e1a1e169661d868bcc0028def41 (diff) |
Initial import of watchdogd, a daemon to retrigger the watchdog timer
from userland (not yet linked to the build process).
ok henning@
-rw-r--r-- | usr.sbin/watchdogd/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/watchdogd/watchdogd.8 | 47 | ||||
-rw-r--r-- | usr.sbin/watchdogd/watchdogd.c | 157 |
3 files changed, 215 insertions, 0 deletions
diff --git a/usr.sbin/watchdogd/Makefile b/usr.sbin/watchdogd/Makefile new file mode 100644 index 00000000000..e44f1cfea91 --- /dev/null +++ b/usr.sbin/watchdogd/Makefile @@ -0,0 +1,11 @@ +# $OpenBSD: Makefile,v 1.1 2005/08/08 12:08:56 mbalmer Exp $ + +PROG= watchdogd +SRCS= watchdogd.c + +CFLAGS+= -Wall +LINTFLAGS+= -u -z + +MAN= watchdogd.8 + +.include <bsd.prog.mk> diff --git a/usr.sbin/watchdogd/watchdogd.8 b/usr.sbin/watchdogd/watchdogd.8 new file mode 100644 index 00000000000..41e9265cdf4 --- /dev/null +++ b/usr.sbin/watchdogd/watchdogd.8 @@ -0,0 +1,47 @@ +.\" $OpenBSD: watchdogd.8,v 1.1 2005/08/08 12:08:56 mbalmer Exp $ +.\" +.\" Copyright (c) 2005 Marc Balmer <marc@msys.ch> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd July 7, 2005 +.Dt WATCHDOGD 8 +.Os +.Sh NAME +.Nm watchdogd +.Nd watchdog timer retrigger daemon +.Sh SYNOPSIS +.Nm watchdogd +.Op Fl d +.Op Fl i Ar interval +.Op Fl p Ar period +.Sh DESCRIPTION +.Nm +is a daemon to periodically retrigger the watchdog timer device from +userland. The watchdog timeout period and the retrigger +interval can be specified on the command line. The period defaults to +30 seconds. If no interval is specified, the value of the period divided +by three is used. The daemon will detach from the controlling terminal +and run in the background unless the +.Fl d +command line option is set. +.Sh SEE ALSO +.Xr watchdog 4 , +.Xr elansc 4 , +.Xr geodesc 4 +.Sh HISTORY +The +.Nm +program +first appeared in +.Ox 3.8 . diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c new file mode 100644 index 00000000000..3b4478ccfa9 --- /dev/null +++ b/usr.sbin/watchdogd/watchdogd.c @@ -0,0 +1,157 @@ +/* $OpenBSD: watchdogd.c,v 1.1 2005/08/08 12:08:56 mbalmer Exp $ */ + +/* + * Copyright (c) 2005 Marc Balmer <marc@msys.ch> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/sysctl.h> +#include <sys/mman.h> + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +volatile sig_atomic_t quit = 0; + +__dead void +usage(void) +{ + extern char *__progname; + + fprintf(stderr, "usage: %s [-d] [-i interval] [-p period]\n", + __progname); + exit(1); +} + +void +sighdlr(int signum) +{ + quit = 1; +} + +int +main(int argc, char *argv[]) +{ + int ch; + unsigned int interval; + int period, nperiod; + int trigauto; + int sauto, speriod; + size_t len; + int mib[3]; + const char *errstr; + int daemonize; + int retval; + + interval = 0; + period = 30; + daemonize = 1; + retval = 1; + + while ((ch = getopt(argc, argv, "di:p:")) != -1) { + switch (ch) { + case 'd': + daemonize = 0; + break; + case 'i': + interval = (int)strtonum(optarg, 1LL, 86400LL, &errstr); + if (errstr) + errx(1, "interval is %s: %s", errstr, optarg); + break; + case 'p': + period = (int)strtonum(optarg, 2LL, 86400LL, &errstr); + if (errstr) + errx(1, "period is %s: %s", errstr, optarg); + break; + default: + usage(); + /* NOTREACHED */ + } + } + + if (interval == 0) { + interval = period / 3; + if (interval == 0) + interval = 1; + } + + if (period <= interval) + errx(1, "retrigger interval too long"); + + /* save kern.watchdog.period and kern.watchdog.auto for restore */ + + mib[0] = CTL_KERN; + mib[1] = KERN_WATCHDOG; + mib[2] = KERN_WATCHDOG_PERIOD; + + len = sizeof(speriod); + if (sysctl(mib, 3, &speriod, &len, &period, sizeof(period)) == -1) { + if (errno == EOPNOTSUPP) + errx(1, "no watchdog timer available"); + else + err(1, "can't access kern.watchdog.period"); + } + + mib[2] = KERN_WATCHDOG_AUTO; + + len = sizeof(sauto); + trigauto = 0; + + if (sysctl(mib, 3, &sauto, &len, &trigauto, sizeof(trigauto)) == -1) + err(1, "can't access kern.watchdog.auto"); + + /* Double check the timeout period, some devices change the value */ + + mib[2] = KERN_WATCHDOG_PERIOD; + len = sizeof(nperiod); + if (sysctl(mib, 3, &nperiod, &len, NULL, 0) == -1) { + warnx("can't read back kern.watchdog.period, " + "restoring original values"); + goto restore; + } + + if (nperiod != period) + warnx("period adjusted to %d by device", nperiod); + + if (nperiod <= interval) { + warnx("retrigger interval %d too long, " + "restoring original values", interval); + goto restore; + } + + if (daemonize && daemon(0, 0)) { + warn("can't daemonize, restoring original values"); + goto restore; + } + + signal(SIGTERM, sighdlr); + + retval = 0; + while (!quit) { + if (sysctl(mib, 3, NULL, 0, &period, sizeof(period)) == -1) + quit = 1; + sleep(interval); + } + +restore: + sysctl(mib, 3, NULL, 0, &speriod, sizeof(speriod)); + mib[2] = KERN_WATCHDOG_AUTO; + sysctl(mib, 3, NULL, 0, &sauto, sizeof(sauto)); + + return retval; +} |