1dd84a43cSPoul-Henning Kamp /*- 2dd84a43cSPoul-Henning Kamp * Copyright (c) 2002 Poul-Henning Kamp 3dd84a43cSPoul-Henning Kamp * Copyright (c) 2002 Networks Associates Technology, Inc. 4dd84a43cSPoul-Henning Kamp * All rights reserved. 5dd84a43cSPoul-Henning Kamp * 6dd84a43cSPoul-Henning Kamp * This software was developed for the FreeBSD Project by Poul-Henning Kamp 7dd84a43cSPoul-Henning Kamp * and NAI Labs, the Security Research Division of Network Associates, Inc. 8dd84a43cSPoul-Henning Kamp * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 9dd84a43cSPoul-Henning Kamp * DARPA CHATS research program. 10dd84a43cSPoul-Henning Kamp * 11dd84a43cSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 12dd84a43cSPoul-Henning Kamp * modification, are permitted provided that the following conditions 13dd84a43cSPoul-Henning Kamp * are met: 14dd84a43cSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 15dd84a43cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 16dd84a43cSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 17dd84a43cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 18dd84a43cSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 19dd84a43cSPoul-Henning Kamp * 3. The names of the authors may not be used to endorse or promote 20dd84a43cSPoul-Henning Kamp * products derived from this software without specific prior written 21dd84a43cSPoul-Henning Kamp * permission. 22dd84a43cSPoul-Henning Kamp * 23dd84a43cSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24dd84a43cSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25dd84a43cSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26dd84a43cSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27dd84a43cSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28dd84a43cSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29dd84a43cSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30dd84a43cSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31dd84a43cSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32dd84a43cSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33dd84a43cSPoul-Henning Kamp * SUCH DAMAGE. 34dd84a43cSPoul-Henning Kamp * 35dd84a43cSPoul-Henning Kamp * $FreeBSD$ 36dd84a43cSPoul-Henning Kamp */ 37dd84a43cSPoul-Henning Kamp 38dd84a43cSPoul-Henning Kamp /* 39dd84a43cSPoul-Henning Kamp * XXX: How do we in general know that objects referenced in events 40dd84a43cSPoul-Henning Kamp * have not been destroyed before we get around to handle the event ? 41dd84a43cSPoul-Henning Kamp */ 42dd84a43cSPoul-Henning Kamp 43dd84a43cSPoul-Henning Kamp #include <sys/param.h> 44dd84a43cSPoul-Henning Kamp #ifndef _KERNEL 45dd84a43cSPoul-Henning Kamp #include <stdio.h> 46dd84a43cSPoul-Henning Kamp #include <unistd.h> 47dd84a43cSPoul-Henning Kamp #include <string.h> 48dd84a43cSPoul-Henning Kamp #include <stdlib.h> 49dd84a43cSPoul-Henning Kamp #include <signal.h> 50dd84a43cSPoul-Henning Kamp #include <err.h> 51dd84a43cSPoul-Henning Kamp #else 52dd84a43cSPoul-Henning Kamp #include <sys/malloc.h> 53dd84a43cSPoul-Henning Kamp #include <sys/systm.h> 54dd84a43cSPoul-Henning Kamp #include <sys/kernel.h> 55dd84a43cSPoul-Henning Kamp #include <sys/lock.h> 56dd84a43cSPoul-Henning Kamp #include <sys/mutex.h> 57ed0ff8e5SPoul-Henning Kamp #include <sys/eventhandler.h> 58dd84a43cSPoul-Henning Kamp #endif 59dd84a43cSPoul-Henning Kamp #include <sys/errno.h> 60dd84a43cSPoul-Henning Kamp #include <sys/time.h> 61dd84a43cSPoul-Henning Kamp #include <geom/geom.h> 62b1876192SPoul-Henning Kamp #include <geom/geom_int.h> 63dd84a43cSPoul-Henning Kamp 64dd84a43cSPoul-Henning Kamp static struct event_tailq_head g_events = TAILQ_HEAD_INITIALIZER(g_events); 65abb50a48SPoul-Henning Kamp static u_int g_pending_events; 66b1876192SPoul-Henning Kamp static void g_do_event(struct g_event *ep); 67dd84a43cSPoul-Henning Kamp static TAILQ_HEAD(,g_provider) g_doorstep = TAILQ_HEAD_INITIALIZER(g_doorstep); 68903e43feSPoul-Henning Kamp static struct mtx g_eventlock; 69ed0ff8e5SPoul-Henning Kamp static int g_shutdown; 70dd84a43cSPoul-Henning Kamp 71dd84a43cSPoul-Henning Kamp void 72503abe45SPoul-Henning Kamp g_waitidle(void) 73dd84a43cSPoul-Henning Kamp { 74dd84a43cSPoul-Henning Kamp 75dd84a43cSPoul-Henning Kamp while (g_pending_events) 76503abe45SPoul-Henning Kamp tsleep(&g_pending_events, PPAUSE, "g_waitidle", hz/5); 77dd84a43cSPoul-Henning Kamp } 78dd84a43cSPoul-Henning Kamp 79dd84a43cSPoul-Henning Kamp void 80dd84a43cSPoul-Henning Kamp g_orphan_provider(struct g_provider *pp, int error) 81dd84a43cSPoul-Henning Kamp { 82dd84a43cSPoul-Henning Kamp 83dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "g_orphan_provider(%p(%s), %d)", 84dd84a43cSPoul-Henning Kamp pp, pp->name, error); 85dd84a43cSPoul-Henning Kamp KASSERT(error != 0, 86dd84a43cSPoul-Henning Kamp ("g_orphan_provider(%p(%s), 0) error must be non-zero\n", 87dd84a43cSPoul-Henning Kamp pp, pp->name)); 88dd84a43cSPoul-Henning Kamp pp->error = error; 89903e43feSPoul-Henning Kamp mtx_lock(&g_eventlock); 90dd84a43cSPoul-Henning Kamp TAILQ_INSERT_TAIL(&g_doorstep, pp, orphan); 91903e43feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 92dd84a43cSPoul-Henning Kamp wakeup(&g_wait_event); 93dd84a43cSPoul-Henning Kamp } 94dd84a43cSPoul-Henning Kamp 95dd84a43cSPoul-Henning Kamp /* 96dd84a43cSPoul-Henning Kamp * This function is called once on each provider which the event handler 97dd84a43cSPoul-Henning Kamp * finds on its g_doorstep. 98dd84a43cSPoul-Henning Kamp */ 99dd84a43cSPoul-Henning Kamp 100dd84a43cSPoul-Henning Kamp static void 101b1876192SPoul-Henning Kamp g_orphan_register(struct g_provider *pp) 102dd84a43cSPoul-Henning Kamp { 103dd84a43cSPoul-Henning Kamp struct g_consumer *cp, *cp2; 104dd84a43cSPoul-Henning Kamp 105dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "g_orphan_register(%s)", pp->name); 106dd84a43cSPoul-Henning Kamp g_topology_assert(); 107dd84a43cSPoul-Henning Kamp 108dd84a43cSPoul-Henning Kamp /* 109dd84a43cSPoul-Henning Kamp * Tell all consumers the bad news. 110f48b8819SPoul-Henning Kamp * Don't be surprised if they self-destruct. 111dd84a43cSPoul-Henning Kamp */ 112dd84a43cSPoul-Henning Kamp cp = LIST_FIRST(&pp->consumers); 113dd84a43cSPoul-Henning Kamp while (cp != NULL) { 114dd84a43cSPoul-Henning Kamp cp2 = LIST_NEXT(cp, consumers); 11507d77fc6SPoul-Henning Kamp KASSERT(cp->geom->orphan != NULL, 11607d77fc6SPoul-Henning Kamp ("geom %s has no orphan, class %s", 11707d77fc6SPoul-Henning Kamp cp->geom->name, cp->geom->class->name)); 11807d77fc6SPoul-Henning Kamp cp->geom->orphan(cp); 119dd84a43cSPoul-Henning Kamp cp = cp2; 120dd84a43cSPoul-Henning Kamp } 121dd84a43cSPoul-Henning Kamp } 122dd84a43cSPoul-Henning Kamp 123dd84a43cSPoul-Henning Kamp static void 124dd84a43cSPoul-Henning Kamp g_destroy_event(struct g_event *ep) 125dd84a43cSPoul-Henning Kamp { 126dd84a43cSPoul-Henning Kamp 127dd84a43cSPoul-Henning Kamp g_free(ep); 128dd84a43cSPoul-Henning Kamp } 129dd84a43cSPoul-Henning Kamp 130dd84a43cSPoul-Henning Kamp static void 131b1876192SPoul-Henning Kamp g_do_event(struct g_event *ep) 132dd84a43cSPoul-Henning Kamp { 133e805e8f0SPoul-Henning Kamp struct g_class *mp, *mp2; 134dd84a43cSPoul-Henning Kamp struct g_geom *gp; 135dd84a43cSPoul-Henning Kamp struct g_consumer *cp, *cp2; 136dd84a43cSPoul-Henning Kamp struct g_provider *pp; 137dd84a43cSPoul-Henning Kamp int i; 138dd84a43cSPoul-Henning Kamp 139dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "g_do_event(%p) %d m:%p g:%p p:%p c:%p - ", 140e805e8f0SPoul-Henning Kamp ep, ep->event, ep->class, ep->geom, ep->provider, ep->consumer); 141dd84a43cSPoul-Henning Kamp g_topology_assert(); 142dd84a43cSPoul-Henning Kamp switch (ep->event) { 143346cd5feSPoul-Henning Kamp case EV_CALL_ME: 144346cd5feSPoul-Henning Kamp ep->func(ep->arg); 145cd4f50fbSPoul-Henning Kamp g_topology_assert(); 146346cd5feSPoul-Henning Kamp break; 147e805e8f0SPoul-Henning Kamp case EV_NEW_CLASS: 148e805e8f0SPoul-Henning Kamp mp2 = ep->class; 149346cd5feSPoul-Henning Kamp if (g_shutdown) 150346cd5feSPoul-Henning Kamp break; 151dd84a43cSPoul-Henning Kamp if (mp2->taste == NULL) 152dd84a43cSPoul-Henning Kamp break; 153e615b0fdSPoul-Henning Kamp if (g_shutdown) 154e615b0fdSPoul-Henning Kamp break; 1552654e1fcSPoul-Henning Kamp LIST_FOREACH(mp, &g_classes, class) { 156dd84a43cSPoul-Henning Kamp if (mp2 == mp) 157dd84a43cSPoul-Henning Kamp continue; 158dd84a43cSPoul-Henning Kamp LIST_FOREACH(gp, &mp->geom, geom) { 159dd84a43cSPoul-Henning Kamp LIST_FOREACH(pp, &gp->provider, provider) { 160b1876192SPoul-Henning Kamp mp2->taste(ep->class, pp, 0); 161dd84a43cSPoul-Henning Kamp g_topology_assert(); 162dd84a43cSPoul-Henning Kamp } 163dd84a43cSPoul-Henning Kamp } 164dd84a43cSPoul-Henning Kamp } 165dd84a43cSPoul-Henning Kamp break; 166dd84a43cSPoul-Henning Kamp case EV_NEW_PROVIDER: 167e615b0fdSPoul-Henning Kamp if (g_shutdown) 168e615b0fdSPoul-Henning Kamp break; 169dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "EV_NEW_PROVIDER(%s)", 170dd84a43cSPoul-Henning Kamp ep->provider->name); 1712654e1fcSPoul-Henning Kamp LIST_FOREACH(mp, &g_classes, class) { 172dd84a43cSPoul-Henning Kamp if (mp->taste == NULL) 173dd84a43cSPoul-Henning Kamp continue; 174a9ed5e11SPoul-Henning Kamp if (!strcmp(ep->provider->name, "geom.ctl") && 175a9ed5e11SPoul-Henning Kamp strcmp(mp->name, "DEV")) 176a9ed5e11SPoul-Henning Kamp continue; 177dd84a43cSPoul-Henning Kamp i = 1; 178dd84a43cSPoul-Henning Kamp LIST_FOREACH(cp, &ep->provider->consumers, consumers) 179e805e8f0SPoul-Henning Kamp if(cp->geom->class == mp) 180dd84a43cSPoul-Henning Kamp i = 0; 181dd84a43cSPoul-Henning Kamp if (i) { 182b1876192SPoul-Henning Kamp mp->taste(mp, ep->provider, 0); 183dd84a43cSPoul-Henning Kamp g_topology_assert(); 184dd84a43cSPoul-Henning Kamp } 185dd84a43cSPoul-Henning Kamp } 186dd84a43cSPoul-Henning Kamp break; 187dd84a43cSPoul-Henning Kamp case EV_SPOILED: 188dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "EV_SPOILED(%p(%s),%p)", 189dd84a43cSPoul-Henning Kamp ep->provider, ep->provider->name, ep->consumer); 190dd84a43cSPoul-Henning Kamp cp = LIST_FIRST(&ep->provider->consumers); 191dd84a43cSPoul-Henning Kamp while (cp != NULL) { 192dd84a43cSPoul-Henning Kamp cp2 = LIST_NEXT(cp, consumers); 193dd84a43cSPoul-Henning Kamp if (cp->spoiled) { 194dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "spoiling %p (%s) (%p)", 195dd84a43cSPoul-Henning Kamp cp, cp->geom->name, cp->geom->spoiled); 196dd84a43cSPoul-Henning Kamp if (cp->geom->spoiled != NULL) 197dd84a43cSPoul-Henning Kamp cp->geom->spoiled(cp); 198855f8b26SPoul-Henning Kamp else 199dd84a43cSPoul-Henning Kamp cp->spoiled = 0; 200dd84a43cSPoul-Henning Kamp } 201dd84a43cSPoul-Henning Kamp cp = cp2; 202dd84a43cSPoul-Henning Kamp } 203dd84a43cSPoul-Henning Kamp break; 204dd84a43cSPoul-Henning Kamp case EV_LAST: 205dd84a43cSPoul-Henning Kamp default: 206dd84a43cSPoul-Henning Kamp KASSERT(1 == 0, ("Unknown event %d", ep->event)); 207dd84a43cSPoul-Henning Kamp } 208dd84a43cSPoul-Henning Kamp } 209dd84a43cSPoul-Henning Kamp 210dd84a43cSPoul-Henning Kamp static int 211b1876192SPoul-Henning Kamp one_event(void) 212dd84a43cSPoul-Henning Kamp { 213dd84a43cSPoul-Henning Kamp struct g_event *ep; 214dd84a43cSPoul-Henning Kamp struct g_provider *pp; 215dd84a43cSPoul-Henning Kamp 216dd84a43cSPoul-Henning Kamp g_topology_lock(); 217dd84a43cSPoul-Henning Kamp for (;;) { 218903e43feSPoul-Henning Kamp mtx_lock(&g_eventlock); 219dd84a43cSPoul-Henning Kamp pp = TAILQ_FIRST(&g_doorstep); 220dd84a43cSPoul-Henning Kamp if (pp != NULL) 221dd84a43cSPoul-Henning Kamp TAILQ_REMOVE(&g_doorstep, pp, orphan); 222903e43feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 223dd84a43cSPoul-Henning Kamp if (pp == NULL) 224dd84a43cSPoul-Henning Kamp break; 225b1876192SPoul-Henning Kamp g_orphan_register(pp); 226dd84a43cSPoul-Henning Kamp } 227346cd5feSPoul-Henning Kamp mtx_lock(&g_eventlock); 228dd84a43cSPoul-Henning Kamp ep = TAILQ_FIRST(&g_events); 229dd84a43cSPoul-Henning Kamp if (ep == NULL) { 230346cd5feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 231dd84a43cSPoul-Henning Kamp g_topology_unlock(); 232dd84a43cSPoul-Henning Kamp return (0); 233dd84a43cSPoul-Henning Kamp } 234dd84a43cSPoul-Henning Kamp TAILQ_REMOVE(&g_events, ep, events); 235346cd5feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 236e805e8f0SPoul-Henning Kamp if (ep->class != NULL) 237e805e8f0SPoul-Henning Kamp ep->class->event = NULL; 238dd84a43cSPoul-Henning Kamp if (ep->geom != NULL) 239dd84a43cSPoul-Henning Kamp ep->geom->event = NULL; 240dd84a43cSPoul-Henning Kamp if (ep->provider != NULL) 241dd84a43cSPoul-Henning Kamp ep->provider->event = NULL; 242dd84a43cSPoul-Henning Kamp if (ep->consumer != NULL) 243dd84a43cSPoul-Henning Kamp ep->consumer->event = NULL; 244b1876192SPoul-Henning Kamp g_do_event(ep); 245dd84a43cSPoul-Henning Kamp g_destroy_event(ep); 246a9ed5e11SPoul-Henning Kamp g_pending_events--; 247a9ed5e11SPoul-Henning Kamp if (g_pending_events == 0) 248a9ed5e11SPoul-Henning Kamp wakeup(&g_pending_events); 249a9ed5e11SPoul-Henning Kamp g_topology_unlock(); 250dd84a43cSPoul-Henning Kamp return (1); 251dd84a43cSPoul-Henning Kamp } 252dd84a43cSPoul-Henning Kamp 253dd84a43cSPoul-Henning Kamp void 254b1876192SPoul-Henning Kamp g_run_events() 255dd84a43cSPoul-Henning Kamp { 256dd84a43cSPoul-Henning Kamp 257b1876192SPoul-Henning Kamp while (one_event()) 258dd84a43cSPoul-Henning Kamp ; 259dd84a43cSPoul-Henning Kamp } 260dd84a43cSPoul-Henning Kamp 261dd84a43cSPoul-Henning Kamp void 262e805e8f0SPoul-Henning Kamp g_post_event(enum g_events ev, struct g_class *mp, struct g_geom *gp, struct g_provider *pp, struct g_consumer *cp) 263dd84a43cSPoul-Henning Kamp { 264dd84a43cSPoul-Henning Kamp struct g_event *ep; 265dd84a43cSPoul-Henning Kamp 266dd84a43cSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "g_post_event(%d, %p, %p, %p, %p)", 267dd84a43cSPoul-Henning Kamp ev, mp, gp, pp, cp); 268dd84a43cSPoul-Henning Kamp g_topology_assert(); 269a163d034SWarner Losh ep = g_malloc(sizeof *ep, M_WAITOK | M_ZERO); 270dd84a43cSPoul-Henning Kamp ep->event = ev; 271dd84a43cSPoul-Henning Kamp if (mp != NULL) { 272e805e8f0SPoul-Henning Kamp ep->class = mp; 273a9ed5e11SPoul-Henning Kamp KASSERT(mp->event == NULL, ("Double event on class %d %d", 274a9ed5e11SPoul-Henning Kamp ep->event, mp->event->event)); 275dd84a43cSPoul-Henning Kamp mp->event = ep; 276dd84a43cSPoul-Henning Kamp } 277dd84a43cSPoul-Henning Kamp if (gp != NULL) { 278dd84a43cSPoul-Henning Kamp ep->geom = gp; 279a9ed5e11SPoul-Henning Kamp KASSERT(gp->event == NULL, ("Double event on geom %d %d", 280a9ed5e11SPoul-Henning Kamp ep->event, gp->event->event)); 281dd84a43cSPoul-Henning Kamp gp->event = ep; 282dd84a43cSPoul-Henning Kamp } 283dd84a43cSPoul-Henning Kamp if (pp != NULL) { 284dd84a43cSPoul-Henning Kamp ep->provider = pp; 285a9ed5e11SPoul-Henning Kamp KASSERT(pp->event == NULL, ("Double event on provider %s %d %d", 286a9ed5e11SPoul-Henning Kamp pp->name, ep->event, pp->event->event)); 287dd84a43cSPoul-Henning Kamp pp->event = ep; 288dd84a43cSPoul-Henning Kamp } 289dd84a43cSPoul-Henning Kamp if (cp != NULL) { 290dd84a43cSPoul-Henning Kamp ep->consumer = cp; 291a9ed5e11SPoul-Henning Kamp KASSERT(cp->event == NULL, ("Double event on consumer %d %d", 292a9ed5e11SPoul-Henning Kamp ep->event, cp->event->event)); 293dd84a43cSPoul-Henning Kamp cp->event = ep; 294dd84a43cSPoul-Henning Kamp } 295346cd5feSPoul-Henning Kamp mtx_lock(&g_eventlock); 296dd84a43cSPoul-Henning Kamp g_pending_events++; 297dd84a43cSPoul-Henning Kamp TAILQ_INSERT_TAIL(&g_events, ep, events); 298346cd5feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 299dd84a43cSPoul-Henning Kamp wakeup(&g_wait_event); 300dd84a43cSPoul-Henning Kamp } 301dd84a43cSPoul-Henning Kamp 302346cd5feSPoul-Henning Kamp int 303346cd5feSPoul-Henning Kamp g_call_me(g_call_me_t *func, void *arg) 304346cd5feSPoul-Henning Kamp { 305346cd5feSPoul-Henning Kamp struct g_event *ep; 306346cd5feSPoul-Henning Kamp 307346cd5feSPoul-Henning Kamp g_trace(G_T_TOPOLOGY, "g_call_me(%p, %p", func, arg); 308346cd5feSPoul-Henning Kamp ep = g_malloc(sizeof *ep, M_NOWAIT | M_ZERO); 309346cd5feSPoul-Henning Kamp if (ep == NULL) 310346cd5feSPoul-Henning Kamp return (ENOMEM); 311346cd5feSPoul-Henning Kamp ep->event = EV_CALL_ME; 312346cd5feSPoul-Henning Kamp ep->func = func; 313346cd5feSPoul-Henning Kamp ep->arg = arg; 314346cd5feSPoul-Henning Kamp mtx_lock(&g_eventlock); 315346cd5feSPoul-Henning Kamp g_pending_events++; 316346cd5feSPoul-Henning Kamp TAILQ_INSERT_TAIL(&g_events, ep, events); 317346cd5feSPoul-Henning Kamp mtx_unlock(&g_eventlock); 318346cd5feSPoul-Henning Kamp wakeup(&g_wait_event); 319346cd5feSPoul-Henning Kamp return (0); 320346cd5feSPoul-Henning Kamp } 321346cd5feSPoul-Henning Kamp 322ed0ff8e5SPoul-Henning Kamp #ifdef _KERNEL 323ed0ff8e5SPoul-Henning Kamp static void 324ed0ff8e5SPoul-Henning Kamp geom_shutdown(void *foo __unused) 325ed0ff8e5SPoul-Henning Kamp { 326ed0ff8e5SPoul-Henning Kamp 327ed0ff8e5SPoul-Henning Kamp g_shutdown = 1; 328ed0ff8e5SPoul-Henning Kamp } 329ed0ff8e5SPoul-Henning Kamp #endif 330ed0ff8e5SPoul-Henning Kamp 331dd84a43cSPoul-Henning Kamp void 332dd84a43cSPoul-Henning Kamp g_event_init() 333dd84a43cSPoul-Henning Kamp { 334dd84a43cSPoul-Henning Kamp 335ed0ff8e5SPoul-Henning Kamp #ifdef _KERNEL 336ed0ff8e5SPoul-Henning Kamp 337ed0ff8e5SPoul-Henning Kamp EVENTHANDLER_REGISTER(shutdown_pre_sync, geom_shutdown, NULL, 338ed0ff8e5SPoul-Henning Kamp SHUTDOWN_PRI_FIRST); 339ed0ff8e5SPoul-Henning Kamp #endif 340903e43feSPoul-Henning Kamp mtx_init(&g_eventlock, "GEOM orphanage", NULL, MTX_DEF); 341dd84a43cSPoul-Henning Kamp } 342