Module Name: src Committed By: pooka Date: Sun Jan 31 01:38:48 UTC 2010
Modified Files: src/sys/conf: files src/sys/kern: kern_subr.c Added Files: src/sys/kern: kern_hook.c Log Message: Place *hook implementations in kern_hook.c instead of them floating around in the kern_subr.c gruel. Arrrrr. To generate a diff of this commit: cvs rdiff -u -r1.972 -r1.973 src/sys/conf/files cvs rdiff -u -r0 -r1.1 src/sys/kern/kern_hook.c cvs rdiff -u -r1.205 -r1.206 src/sys/kern/kern_subr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/conf/files diff -u src/sys/conf/files:1.972 src/sys/conf/files:1.973 --- src/sys/conf/files:1.972 Sat Jan 30 23:19:55 2010 +++ src/sys/conf/files Sun Jan 31 01:38:48 2010 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.972 2010/01/30 23:19:55 pooka Exp $ +# $NetBSD: files,v 1.973 2010/01/31 01:38:48 pooka Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20090313 @@ -1428,6 +1428,7 @@ file kern/kern_exit.c file kern/kern_fork.c file kern/kern_idle.c +file kern/kern_hook.c file kern/kern_kthread.c file kern/kern_ktrace.c ktrace file kern/kern_ksyms.c ksyms | ddb | modular needs-flag Index: src/sys/kern/kern_subr.c diff -u src/sys/kern/kern_subr.c:1.205 src/sys/kern/kern_subr.c:1.206 --- src/sys/kern/kern_subr.c:1.205 Sun Jan 31 00:48:07 2010 +++ src/sys/kern/kern_subr.c Sun Jan 31 01:38:48 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_subr.c,v 1.205 2010/01/31 00:48:07 pooka Exp $ */ +/* $NetBSD: kern_subr.c,v 1.206 2010/01/31 01:38:48 pooka Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -79,7 +79,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.205 2010/01/31 00:48:07 pooka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_subr.c,v 1.206 2010/01/31 01:38:48 pooka Exp $"); #include "opt_ddb.h" #include "opt_md.h" @@ -91,7 +91,6 @@ #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> -#include <sys/malloc.h> #include <sys/mount.h> #include <sys/device.h> #include <sys/reboot.h> @@ -120,335 +119,11 @@ static device_t parsedisk(char *, int, int, dev_t *); static const char *getwedgename(const char *, int); -/* - * A generic linear hook. - */ -struct hook_desc { - LIST_ENTRY(hook_desc) hk_list; - void (*hk_fn)(void *); - void *hk_arg; -}; -typedef LIST_HEAD(, hook_desc) hook_list_t; - #ifdef TFTPROOT int tftproot_dhcpboot(device_t); #endif dev_t dumpcdev; /* for savecore */ -int powerhook_debug = 0; - -static void * -hook_establish(hook_list_t *list, void (*fn)(void *), void *arg) -{ - struct hook_desc *hd; - - hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT); - if (hd == NULL) - return (NULL); - - hd->hk_fn = fn; - hd->hk_arg = arg; - LIST_INSERT_HEAD(list, hd, hk_list); - - return (hd); -} - -static void -hook_disestablish(hook_list_t *list, void *vhook) -{ -#ifdef DIAGNOSTIC - struct hook_desc *hd; - - LIST_FOREACH(hd, list, hk_list) { - if (hd == vhook) - break; - } - - if (hd == NULL) - panic("hook_disestablish: hook %p not established", vhook); -#endif - LIST_REMOVE((struct hook_desc *)vhook, hk_list); - free(vhook, M_DEVBUF); -} - -static void -hook_destroy(hook_list_t *list) -{ - struct hook_desc *hd; - - while ((hd = LIST_FIRST(list)) != NULL) { - LIST_REMOVE(hd, hk_list); - free(hd, M_DEVBUF); - } -} - -static void -hook_proc_run(hook_list_t *list, struct proc *p) -{ - struct hook_desc *hd; - - LIST_FOREACH(hd, list, hk_list) - ((void (*)(struct proc *, void *))*hd->hk_fn)(p, hd->hk_arg); -} - -/* - * "Shutdown hook" types, functions, and variables. - * - * Should be invoked immediately before the - * system is halted or rebooted, i.e. after file systems unmounted, - * after crash dump done, etc. - * - * Each shutdown hook is removed from the list before it's run, so that - * it won't be run again. - */ - -static hook_list_t shutdownhook_list = LIST_HEAD_INITIALIZER(shutdownhook_list); - -void * -shutdownhook_establish(void (*fn)(void *), void *arg) -{ - return hook_establish(&shutdownhook_list, fn, arg); -} - -void -shutdownhook_disestablish(void *vhook) -{ - hook_disestablish(&shutdownhook_list, vhook); -} - -/* - * Run shutdown hooks. Should be invoked immediately before the - * system is halted or rebooted, i.e. after file systems unmounted, - * after crash dump done, etc. - * - * Each shutdown hook is removed from the list before it's run, so that - * it won't be run again. - */ -void -doshutdownhooks(void) -{ - struct hook_desc *dp; - - while ((dp = LIST_FIRST(&shutdownhook_list)) != NULL) { - LIST_REMOVE(dp, hk_list); - (*dp->hk_fn)(dp->hk_arg); -#if 0 - /* - * Don't bother freeing the hook structure,, since we may - * be rebooting because of a memory corruption problem, - * and this might only make things worse. It doesn't - * matter, anyway, since the system is just about to - * reboot. - */ - free(dp, M_DEVBUF); -#endif - } -} - -/* - * "Mountroot hook" types, functions, and variables. - */ - -static hook_list_t mountroothook_list=LIST_HEAD_INITIALIZER(mountroothook_list); - -void * -mountroothook_establish(void (*fn)(device_t), device_t dev) -{ - return hook_establish(&mountroothook_list, (void (*)(void *))fn, dev); -} - -void -mountroothook_disestablish(void *vhook) -{ - hook_disestablish(&mountroothook_list, vhook); -} - -void -mountroothook_destroy(void) -{ - hook_destroy(&mountroothook_list); -} - -void -domountroothook(void) -{ - struct hook_desc *hd; - - LIST_FOREACH(hd, &mountroothook_list, hk_list) { - if (hd->hk_arg == (void *)root_device) { - (*hd->hk_fn)(hd->hk_arg); - return; - } - } -} - -static hook_list_t exechook_list = LIST_HEAD_INITIALIZER(exechook_list); - -void * -exechook_establish(void (*fn)(struct proc *, void *), void *arg) -{ - return hook_establish(&exechook_list, (void (*)(void *))fn, arg); -} - -void -exechook_disestablish(void *vhook) -{ - hook_disestablish(&exechook_list, vhook); -} - -/* - * Run exec hooks. - */ -void -doexechooks(struct proc *p) -{ - hook_proc_run(&exechook_list, p); -} - -static hook_list_t exithook_list = LIST_HEAD_INITIALIZER(exithook_list); -extern krwlock_t exec_lock; - -void * -exithook_establish(void (*fn)(struct proc *, void *), void *arg) -{ - void *rv; - - rw_enter(&exec_lock, RW_WRITER); - rv = hook_establish(&exithook_list, (void (*)(void *))fn, arg); - rw_exit(&exec_lock); - return rv; -} - -void -exithook_disestablish(void *vhook) -{ - - rw_enter(&exec_lock, RW_WRITER); - hook_disestablish(&exithook_list, vhook); - rw_exit(&exec_lock); -} - -/* - * Run exit hooks. - */ -void -doexithooks(struct proc *p) -{ - hook_proc_run(&exithook_list, p); -} - -static hook_list_t forkhook_list = LIST_HEAD_INITIALIZER(forkhook_list); - -void * -forkhook_establish(void (*fn)(struct proc *, struct proc *)) -{ - return hook_establish(&forkhook_list, (void (*)(void *))fn, NULL); -} - -void -forkhook_disestablish(void *vhook) -{ - hook_disestablish(&forkhook_list, vhook); -} - -/* - * Run fork hooks. - */ -void -doforkhooks(struct proc *p2, struct proc *p1) -{ - struct hook_desc *hd; - - LIST_FOREACH(hd, &forkhook_list, hk_list) { - ((void (*)(struct proc *, struct proc *))*hd->hk_fn) - (p2, p1); - } -} - -/* - * "Power hook" types, functions, and variables. - * The list of power hooks is kept ordered with the last registered hook - * first. - * When running the hooks on power down the hooks are called in reverse - * registration order, when powering up in registration order. - */ -struct powerhook_desc { - CIRCLEQ_ENTRY(powerhook_desc) sfd_list; - void (*sfd_fn)(int, void *); - void *sfd_arg; - char sfd_name[16]; -}; - -static CIRCLEQ_HEAD(, powerhook_desc) powerhook_list = - CIRCLEQ_HEAD_INITIALIZER(powerhook_list); - -void * -powerhook_establish(const char *name, void (*fn)(int, void *), void *arg) -{ - struct powerhook_desc *ndp; - - ndp = (struct powerhook_desc *) - malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT); - if (ndp == NULL) - return (NULL); - - ndp->sfd_fn = fn; - ndp->sfd_arg = arg; - strlcpy(ndp->sfd_name, name, sizeof(ndp->sfd_name)); - CIRCLEQ_INSERT_HEAD(&powerhook_list, ndp, sfd_list); - - aprint_error("%s: WARNING: powerhook_establish is deprecated\n", name); - return (ndp); -} - -void -powerhook_disestablish(void *vhook) -{ -#ifdef DIAGNOSTIC - struct powerhook_desc *dp; - - CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list) - if (dp == vhook) - goto found; - panic("powerhook_disestablish: hook %p not established", vhook); - found: -#endif - - CIRCLEQ_REMOVE(&powerhook_list, (struct powerhook_desc *)vhook, - sfd_list); - free(vhook, M_DEVBUF); -} - -/* - * Run power hooks. - */ -void -dopowerhooks(int why) -{ - struct powerhook_desc *dp; - const char *why_name; - static const char * pwr_names[] = {PWR_NAMES}; - why_name = why < __arraycount(pwr_names) ? pwr_names[why] : "???"; - - if (why == PWR_RESUME || why == PWR_SOFTRESUME) { - CIRCLEQ_FOREACH_REVERSE(dp, &powerhook_list, sfd_list) { - if (powerhook_debug) - printf("dopowerhooks %s: %s (%p)\n", - why_name, dp->sfd_name, dp); - (*dp->sfd_fn)(why, dp->sfd_arg); - } - } else { - CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list) { - if (powerhook_debug) - printf("dopowerhooks %s: %s (%p)\n", - why_name, dp->sfd_name, dp); - (*dp->sfd_fn)(why, dp->sfd_arg); - } - } - - if (powerhook_debug) - printf("dopowerhooks: %s done\n", why_name); -} static int isswap(device_t dv) Added files: Index: src/sys/kern/kern_hook.c diff -u /dev/null src/sys/kern/kern_hook.c:1.1 --- /dev/null Sun Jan 31 01:38:48 2010 +++ src/sys/kern/kern_hook.c Sun Jan 31 01:38:48 2010 @@ -0,0 +1,364 @@ +/* $NetBSD: kern_hook.c,v 1.1 2010/01/31 01:38:48 pooka Exp $ */ + +/*- + * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, + * NASA Ames Research Center, and by Luke Mewburn. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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: kern_hook.c,v 1.1 2010/01/31 01:38:48 pooka Exp $"); + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/rwlock.h> +#include <sys/systm.h> + +/* + * A generic linear hook. + */ +struct hook_desc { + LIST_ENTRY(hook_desc) hk_list; + void (*hk_fn)(void *); + void *hk_arg; +}; +typedef LIST_HEAD(, hook_desc) hook_list_t; + +int powerhook_debug = 0; + +static void * +hook_establish(hook_list_t *list, void (*fn)(void *), void *arg) +{ + struct hook_desc *hd; + + hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT); + if (hd == NULL) + return (NULL); + + hd->hk_fn = fn; + hd->hk_arg = arg; + LIST_INSERT_HEAD(list, hd, hk_list); + + return (hd); +} + +static void +hook_disestablish(hook_list_t *list, void *vhook) +{ +#ifdef DIAGNOSTIC + struct hook_desc *hd; + + LIST_FOREACH(hd, list, hk_list) { + if (hd == vhook) + break; + } + + if (hd == NULL) + panic("hook_disestablish: hook %p not established", vhook); +#endif + LIST_REMOVE((struct hook_desc *)vhook, hk_list); + free(vhook, M_DEVBUF); +} + +static void +hook_destroy(hook_list_t *list) +{ + struct hook_desc *hd; + + while ((hd = LIST_FIRST(list)) != NULL) { + LIST_REMOVE(hd, hk_list); + free(hd, M_DEVBUF); + } +} + +static void +hook_proc_run(hook_list_t *list, struct proc *p) +{ + struct hook_desc *hd; + + LIST_FOREACH(hd, list, hk_list) + ((void (*)(struct proc *, void *))*hd->hk_fn)(p, hd->hk_arg); +} + +/* + * "Shutdown hook" types, functions, and variables. + * + * Should be invoked immediately before the + * system is halted or rebooted, i.e. after file systems unmounted, + * after crash dump done, etc. + * + * Each shutdown hook is removed from the list before it's run, so that + * it won't be run again. + */ + +static hook_list_t shutdownhook_list = LIST_HEAD_INITIALIZER(shutdownhook_list); + +void * +shutdownhook_establish(void (*fn)(void *), void *arg) +{ + return hook_establish(&shutdownhook_list, fn, arg); +} + +void +shutdownhook_disestablish(void *vhook) +{ + hook_disestablish(&shutdownhook_list, vhook); +} + +/* + * Run shutdown hooks. Should be invoked immediately before the + * system is halted or rebooted, i.e. after file systems unmounted, + * after crash dump done, etc. + * + * Each shutdown hook is removed from the list before it's run, so that + * it won't be run again. + */ +void +doshutdownhooks(void) +{ + struct hook_desc *dp; + + while ((dp = LIST_FIRST(&shutdownhook_list)) != NULL) { + LIST_REMOVE(dp, hk_list); + (*dp->hk_fn)(dp->hk_arg); +#if 0 + /* + * Don't bother freeing the hook structure,, since we may + * be rebooting because of a memory corruption problem, + * and this might only make things worse. It doesn't + * matter, anyway, since the system is just about to + * reboot. + */ + free(dp, M_DEVBUF); +#endif + } +} + +/* + * "Mountroot hook" types, functions, and variables. + */ + +static hook_list_t mountroothook_list=LIST_HEAD_INITIALIZER(mountroothook_list); + +void * +mountroothook_establish(void (*fn)(device_t), device_t dev) +{ + return hook_establish(&mountroothook_list, (void (*)(void *))fn, dev); +} + +void +mountroothook_disestablish(void *vhook) +{ + hook_disestablish(&mountroothook_list, vhook); +} + +void +mountroothook_destroy(void) +{ + hook_destroy(&mountroothook_list); +} + +void +domountroothook(void) +{ + struct hook_desc *hd; + + LIST_FOREACH(hd, &mountroothook_list, hk_list) { + if (hd->hk_arg == (void *)root_device) { + (*hd->hk_fn)(hd->hk_arg); + return; + } + } +} + +static hook_list_t exechook_list = LIST_HEAD_INITIALIZER(exechook_list); + +void * +exechook_establish(void (*fn)(struct proc *, void *), void *arg) +{ + return hook_establish(&exechook_list, (void (*)(void *))fn, arg); +} + +void +exechook_disestablish(void *vhook) +{ + hook_disestablish(&exechook_list, vhook); +} + +/* + * Run exec hooks. + */ +void +doexechooks(struct proc *p) +{ + hook_proc_run(&exechook_list, p); +} + +static hook_list_t exithook_list = LIST_HEAD_INITIALIZER(exithook_list); +extern krwlock_t exec_lock; + +void * +exithook_establish(void (*fn)(struct proc *, void *), void *arg) +{ + void *rv; + + rw_enter(&exec_lock, RW_WRITER); + rv = hook_establish(&exithook_list, (void (*)(void *))fn, arg); + rw_exit(&exec_lock); + return rv; +} + +void +exithook_disestablish(void *vhook) +{ + + rw_enter(&exec_lock, RW_WRITER); + hook_disestablish(&exithook_list, vhook); + rw_exit(&exec_lock); +} + +/* + * Run exit hooks. + */ +void +doexithooks(struct proc *p) +{ + hook_proc_run(&exithook_list, p); +} + +static hook_list_t forkhook_list = LIST_HEAD_INITIALIZER(forkhook_list); + +void * +forkhook_establish(void (*fn)(struct proc *, struct proc *)) +{ + return hook_establish(&forkhook_list, (void (*)(void *))fn, NULL); +} + +void +forkhook_disestablish(void *vhook) +{ + hook_disestablish(&forkhook_list, vhook); +} + +/* + * Run fork hooks. + */ +void +doforkhooks(struct proc *p2, struct proc *p1) +{ + struct hook_desc *hd; + + LIST_FOREACH(hd, &forkhook_list, hk_list) { + ((void (*)(struct proc *, struct proc *))*hd->hk_fn) + (p2, p1); + } +} + +/* + * "Power hook" types, functions, and variables. + * The list of power hooks is kept ordered with the last registered hook + * first. + * When running the hooks on power down the hooks are called in reverse + * registration order, when powering up in registration order. + */ +struct powerhook_desc { + CIRCLEQ_ENTRY(powerhook_desc) sfd_list; + void (*sfd_fn)(int, void *); + void *sfd_arg; + char sfd_name[16]; +}; + +static CIRCLEQ_HEAD(, powerhook_desc) powerhook_list = + CIRCLEQ_HEAD_INITIALIZER(powerhook_list); + +void * +powerhook_establish(const char *name, void (*fn)(int, void *), void *arg) +{ + struct powerhook_desc *ndp; + + ndp = (struct powerhook_desc *) + malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT); + if (ndp == NULL) + return (NULL); + + ndp->sfd_fn = fn; + ndp->sfd_arg = arg; + strlcpy(ndp->sfd_name, name, sizeof(ndp->sfd_name)); + CIRCLEQ_INSERT_HEAD(&powerhook_list, ndp, sfd_list); + + aprint_error("%s: WARNING: powerhook_establish is deprecated\n", name); + return (ndp); +} + +void +powerhook_disestablish(void *vhook) +{ +#ifdef DIAGNOSTIC + struct powerhook_desc *dp; + + CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list) + if (dp == vhook) + goto found; + panic("powerhook_disestablish: hook %p not established", vhook); + found: +#endif + + CIRCLEQ_REMOVE(&powerhook_list, (struct powerhook_desc *)vhook, + sfd_list); + free(vhook, M_DEVBUF); +} + +/* + * Run power hooks. + */ +void +dopowerhooks(int why) +{ + struct powerhook_desc *dp; + const char *why_name; + static const char * pwr_names[] = {PWR_NAMES}; + why_name = why < __arraycount(pwr_names) ? pwr_names[why] : "???"; + + if (why == PWR_RESUME || why == PWR_SOFTRESUME) { + CIRCLEQ_FOREACH_REVERSE(dp, &powerhook_list, sfd_list) { + if (powerhook_debug) + printf("dopowerhooks %s: %s (%p)\n", + why_name, dp->sfd_name, dp); + (*dp->sfd_fn)(why, dp->sfd_arg); + } + } else { + CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list) { + if (powerhook_debug) + printf("dopowerhooks %s: %s (%p)\n", + why_name, dp->sfd_name, dp); + (*dp->sfd_fn)(why, dp->sfd_arg); + } + } + + if (powerhook_debug) + printf("dopowerhooks: %s done\n", why_name); +}