diff options
-rw-r--r-- | sbin/sysctl/sysctl.c | 33 | ||||
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_watchdog.c | 116 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 20 | ||||
-rw-r--r-- | sys/sys/systm.h | 4 |
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 |