summaryrefslogtreecommitdiff
path: root/sys/dev/sysmon
diff options
context:
space:
mode:
authorsmb <smb@NetBSD.org>2005-01-09 22:51:32 +0000
committersmb <smb@NetBSD.org>2005-01-09 22:51:32 +0000
commitddd2ade2528218b42daf6738ea763c1fa597b7d4 (patch)
treed41c40da0fe7ef805436955367d51bf27dbbcbae /sys/dev/sysmon
parentf26774eaee0426c4d5dcae8310be6364bfdad376 (diff)
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 (limited to 'sys/dev/sysmon')
-rw-r--r--sys/dev/sysmon/files.sysmon6
-rw-r--r--sys/dev/sysmon/swwdog.c159
-rw-r--r--sys/dev/sysmon/sysmon_wdog.c5
3 files changed, 167 insertions, 3 deletions
diff --git a/sys/dev/sysmon/files.sysmon b/sys/dev/sysmon/files.sysmon
index 565923425ee..5171957ba07 100644
--- a/sys/dev/sysmon/files.sysmon
+++ b/sys/dev/sysmon/files.sysmon
@@ -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
+
diff --git a/sys/dev/sysmon/swwdog.c b/sys/dev/sysmon/swwdog.c
new file mode 100644
index 00000000000..a8e0e7667c0
--- /dev/null
+++ b/sys/dev/sysmon/swwdog.c
@@ -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);
+}
diff --git a/sys/dev/sysmon/sysmon_wdog.c b/sys/dev/sysmon/sysmon_wdog.c
index 2af05eadc7d..e91a4a32af7 100644
--- a/sys/dev/sysmon/sysmon_wdog.c
+++ b/sys/dev/sysmon/sysmon_wdog.c
@@ -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;