summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sbin/sysctl/sysctl.c33
-rw-r--r--sys/conf/files3
-rw-r--r--sys/kern/kern_sysctl.c6
-rw-r--r--sys/kern/kern_watchdog.c116
-rw-r--r--sys/sys/sysctl.h20
-rw-r--r--sys/sys/systm.h4
6 files changed, 175 insertions, 7 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 114c7d1d21c..1b1266a9385 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.c,v 1.85 2002/12/17 23:11:32 millert Exp $ */
+/* $OpenBSD: sysctl.c,v 1.86 2003/01/21 16:59:23 markus Exp $ */
/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */
/*
@@ -44,7 +44,7 @@ static const char copyright[] =
#if 0
static const char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95";
#else
-static char *rcsid = "$OpenBSD: sysctl.c,v 1.85 2002/12/17 23:11:32 millert Exp $";
+static char *rcsid = "$OpenBSD: sysctl.c,v 1.86 2003/01/21 16:59:23 markus Exp $";
#endif
#endif /* not lint */
@@ -132,6 +132,7 @@ struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
struct ctlname ttyname[] = CTL_KERN_TTY_NAMES;
struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
+struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
struct ctlname *vfsname;
#ifdef CTL_MACHDEP_NAMES
struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
@@ -205,6 +206,7 @@ int sysctl_nchstats(char *, char **, int *, int, int *);
int sysctl_malloc(char *, char **, int *, int, int *);
int sysctl_seminfo(char *, char **, int *, int, int *);
int sysctl_shminfo(char *, char **, int *, int, int *);
+int sysctl_watchdog(char *, char **, int *, int, int *);
#ifdef CPU_CHIPSET
int sysctl_chipset(char *, char **, int *, int, int *);
#endif
@@ -419,6 +421,12 @@ parse(char *string, int flags)
if (len < 0)
return;
break;
+ case KERN_WATCHDOG:
+ len = sysctl_watchdog(string, &bufp, mib, flags,
+ &type);
+ if (len < 0)
+ return;
+ break;
}
break;
@@ -1337,6 +1345,7 @@ struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID };
struct list ttylist = { ttyname, KERN_TTY_MAXID };
struct list semlist = { semname, KERN_SEMINFO_MAXID };
struct list shmlist = { shmname, KERN_SHMINFO_MAXID };
+struct list watchdoglist = { watchdogname, KERN_WATCHDOG_MAXID };
/*
* handle vfs namei cache statistics
@@ -1851,6 +1860,26 @@ sysctl_shminfo(string, bufpp, mib, flags, typep)
}
/*
+ * Handle watchdog support
+ */
+int
+sysctl_watchdog(char *string, char **bufpp, int mib[], int flags,
+ int *typep)
+{
+ int indx;
+
+ if (*bufpp == NULL) {
+ listall(string, &watchdoglist);
+ return(-1);
+ }
+ if ((indx = findname(string, "third", bufpp, &watchdoglist)) == -1)
+ return(-1);
+ mib[2] = indx;
+ *typep = watchdoglist.list[indx].ctl_type;
+ return(3);
+}
+
+/*
* Scan a list of names searching for a particular name.
*/
int
diff --git a/sys/conf/files b/sys/conf/files
index b2decf384d7..1dbb8e28dfd 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1,4 +1,4 @@
-# $OpenBSD: files,v 1.266 2003/01/08 05:20:35 mickey Exp $
+# $OpenBSD: files,v 1.267 2003/01/21 16:59:23 markus Exp $
# $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
@@ -520,6 +520,7 @@ file kern/kern_sysctl.c
file kern/kern_synch.c
file kern/kern_time.c
file kern/kern_timeout.c
+file kern/kern_watchdog.c
file kern/kern_xxx.c
file kern/kgdb_stub.c kgdb
file kern/subr_autoconf.c
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 49b128dec3a..977d730a384 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.78 2003/01/15 23:41:56 millert Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.79 2003/01/21 16:59:23 markus Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -269,6 +269,7 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
case KERN_SEMINFO:
case KERN_SHMINFO:
case KERN_INTRCNT:
+ case KERN_WATCHDOG:
break;
default:
return (ENOTDIR); /* overloaded */
@@ -480,6 +481,9 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
#endif
case KERN_INTRCNT:
return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp));
+ case KERN_WATCHDOG:
+ return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp,
+ newp, newlen));
default:
return (EOPNOTSUPP);
}
diff --git a/sys/kern/kern_watchdog.c b/sys/kern/kern_watchdog.c
new file mode 100644
index 00000000000..8ace7b27c57
--- /dev/null
+++ b/sys/kern/kern_watchdog.c
@@ -0,0 +1,116 @@
+/* $OpenBSD: kern_watchdog.c,v 1.1 2003/01/21 16:59:23 markus Exp $ */
+
+/*
+ * Copyright (c) 2003 Markus Friedl. 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 AUTHOR ``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 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/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/time.h>
+
+void wdog_init(void);
+void wdog_tickle(void *arg);
+void wdog_shutdown(void *arg);
+int (*wdog_ctl_cb)(void *, int) = NULL;
+void *wdog_ctl_cb_arg = NULL;
+int wdog_period = 0;
+int wdog_auto = 1;
+struct timeout wdog_timeout;
+
+void
+wdog_init(void)
+{
+ timeout_set(&wdog_timeout, wdog_tickle, NULL);
+ shutdownhook_establish(wdog_shutdown, NULL);
+}
+
+void
+wdog_register(void *cb_arg, int (*cb)(void *, int))
+{
+ if (wdog_ctl_cb != NULL)
+ return;
+ wdog_init();
+ wdog_ctl_cb = cb;
+ wdog_ctl_cb_arg = cb_arg;
+}
+
+void
+wdog_tickle(void *arg)
+{
+ if (wdog_ctl_cb == NULL)
+ return;
+ (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
+ timeout_add(&wdog_timeout, wdog_period * hz / 2);
+}
+
+void
+wdog_shutdown(void *arg)
+{
+ if (wdog_ctl_cb == NULL)
+ return;
+ timeout_del(&wdog_timeout);
+ (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, 0);
+}
+
+int
+sysctl_wdog(name, namelen, oldp, oldlenp, newp, newlen)
+ int *name;
+ u_int namelen;
+ void *oldp;
+ size_t *oldlenp;
+ void *newp;
+ size_t newlen;
+{
+ int error, period;
+
+ if (wdog_ctl_cb == NULL)
+ return (EOPNOTSUPP);
+
+ switch (name[0]) {
+ case KERN_WATCHDOG_PERIOD:
+ period = wdog_period;
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &period);
+ if (error)
+ return (error);
+ if (newp) {
+ timeout_del(&wdog_timeout);
+ wdog_period = (*wdog_ctl_cb)(wdog_ctl_cb_arg, period);
+ }
+ break;
+ case KERN_WATCHDOG_AUTO:
+ error = sysctl_int(oldp, oldlenp, newp, newlen, &wdog_auto);
+ if (error)
+ return (error);
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ timeout_del(&wdog_timeout);
+ if (wdog_auto && wdog_period > 0) {
+ (void) (*wdog_ctl_cb)(wdog_ctl_cb_arg, wdog_period);
+ timeout_add(&wdog_timeout, wdog_period * hz / 2);
+ }
+ return (error);
+}
diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h
index 609767bb855..502d3b71b5d 100644
--- a/sys/sys/sysctl.h
+++ b/sys/sys/sysctl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysctl.h,v 1.61 2003/01/13 06:04:16 art Exp $ */
+/* $OpenBSD: sysctl.h,v 1.62 2003/01/21 16:59:23 markus Exp $ */
/* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */
/*
@@ -180,7 +180,8 @@ struct ctlname {
#define KERN_SEMINFO 61 /* struct: SysV struct seminfo */
#define KERN_SHMINFO 62 /* struct: SysV struct shminfo */
#define KERN_INTRCNT 63 /* node: interrupt counters */
-#define KERN_MAXID 64 /* number of valid kern ids */
+#define KERN_WATCHDOG 64 /* node: watchdog */
+#define KERN_MAXID 65 /* number of valid kern ids */
#define CTL_KERN_NAMES { \
{ 0, 0 }, \
@@ -247,6 +248,7 @@ struct ctlname {
{ "seminfo", CTLTYPE_STRUCT }, \
{ "shminfo", CTLTYPE_STRUCT }, \
{ "intrcnt", CTLTYPE_NODE }, \
+ { "watchdog", CTLTYPE_NODE }, \
}
/*
@@ -327,6 +329,19 @@ struct kinfo_proc {
}
/*
+ * KERN_WATCHDOG
+ */
+#define KERN_WATCHDOG_PERIOD 1 /* int: watchdog period */
+#define KERN_WATCHDOG_AUTO 2 /* int: automatic tickle */
+#define KERN_WATCHDOG_MAXID 3
+
+#define CTL_KERN_WATCHDOG_NAMES { \
+ { 0, 0 }, \
+ { "period", CTLTYPE_INT }, \
+ { "auto", CTLTYPE_INT }, \
+}
+
+/*
* CTL_FS identifiers
*/
#define FS_POSIX 1 /* POSIX flags */
@@ -518,6 +533,7 @@ int cpu_sysctl(int *, u_int, void *, size_t *, void *, size_t,
int vfs_sysctl(int *, u_int, void *, size_t *, void *, size_t,
struct proc *);
int sysctl_sysvipc(int *, u_int, void *, size_t *);
+int sysctl_wdog(int *, u_int, void *, size_t *, void *, size_t);
void sysctl_init(void);
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index c287bac9cba..62d3dc32665 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: systm.h,v 1.53 2003/01/09 22:27:12 miod Exp $ */
+/* $OpenBSD: systm.h,v 1.54 2003/01/21 16:59:23 markus Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
@@ -222,6 +222,8 @@ void startprofclock(struct proc *);
void stopprofclock(struct proc *);
void setstatclockrate(int);
+void wdog_register(void *, int (*)(void *, int));
+
/*
* Startup/shutdown hooks. Startup hooks are functions running after
* the scheduler has started but before any threads have been created