summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Balmer <mbalmer@cvs.openbsd.org>2005-08-08 12:08:57 +0000
committerMarc Balmer <mbalmer@cvs.openbsd.org>2005-08-08 12:08:57 +0000
commita22286a7f69eeaeb793ca17852f88268a6951733 (patch)
tree23e77c8b25a7690ddd617f2fe448c1467b962fc7
parent1e13aa819e750e1a1e169661d868bcc0028def41 (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/Makefile11
-rw-r--r--usr.sbin/watchdogd/watchdogd.847
-rw-r--r--usr.sbin/watchdogd/watchdogd.c157
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;
+}