Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Place *hook implementations in kern_hook.c instead of th...
details: https://anonhg.NetBSD.org/src/rev/9b926bcdc12d
branches: trunk
changeset: 751276:9b926bcdc12d
user: pooka <pooka%NetBSD.org@localhost>
date: Sun Jan 31 01:38:48 2010 +0000
description:
Place *hook implementations in kern_hook.c instead of them floating
around in the kern_subr.c gruel. Arrrrr.
diffstat:
sys/conf/files | 3 +-
sys/kern/kern_hook.c | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++
sys/kern/kern_subr.c | 329 +---------------------------------------------
3 files changed, 368 insertions(+), 328 deletions(-)
diffs (truncated from 747 to 300 lines):
diff -r 553e22575976 -r 9b926bcdc12d sys/conf/files
--- a/sys/conf/files Sun Jan 31 00:54:22 2010 +0000
+++ b/sys/conf/files Sun Jan 31 01:38:48 2010 +0000
@@ -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
diff -r 553e22575976 -r 9b926bcdc12d sys/kern/kern_hook.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/kern/kern_hook.c Sun Jan 31 01:38:48 2010 +0000
@@ -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);
+ }
+}
Home |
Main Index |
Thread Index |
Old Index