1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * FMD Dynamic Reconfiguration (DR) Event Handling 31 * 32 * Fault manager scheme plug-ins must track characteristics of individual 33 * pieces of hardware. As these components can be added or removed by a DR 34 * operation, we need to provide a means by which plug-ins can determine when 35 * they need to re-examine the current configuration. We provide a simple 36 * mechanism whereby this task can be implemented using lazy evaluation: a 37 * simple 64-bit generation counter is maintained and incremented on *any* DR. 38 * Schemes can store the generation number in scheme-specific data structures, 39 * and then revalidate their contents if the current generation number has 40 * changed since the resource information was cached. This method saves time, 41 * avoids the complexity of direct participation in DR, avoids the need for 42 * resource-specific processing of DR events, and is relatively easy to port 43 * to other systems that support dynamic reconfiguration. 44 */ 45 46 #include <sys/types.h> 47 #include <sys/sysevent/dr.h> 48 #include <sys/sysevent/eventdefs.h> 49 50 #include <stdio.h> 51 #include <libsysevent.h> 52 53 #undef MUTEX_HELD 54 #undef RW_READ_HELD 55 #undef RW_WRITE_HELD 56 57 #include <fmd_error.h> 58 #include <fmd_subr.h> 59 #include <fmd.h> 60 61 static void 62 fmd_dr_event(sysevent_t *sep) 63 { 64 uint64_t gen; 65 66 (void) pthread_mutex_lock(&fmd.d_stats_lock); 67 gen = fmd.d_stats->ds_dr_gen.fmds_value.ui64++; 68 (void) pthread_mutex_unlock(&fmd.d_stats_lock); 69 70 TRACE((FMD_DBG_XPRT, "dr event %p, gen=%llu", (void *)sep, gen)); 71 } 72 73 /* 74 * Initialize DR event subscription. Note: sysevent_bind_handle() calls 75 * door_create() internally. Door servers in fmd must be setup as fmd threads, 76 * and fmd_transport_init() already calls door_server_create() for us. We 77 * therefore rely on fmd_transport_init() being called before fmd_dr_init(). 78 */ 79 void 80 fmd_dr_init(void) 81 { 82 const char *subclass = ESC_DR_AP_STATE_CHANGE; 83 84 ASSERT(fmd.d_xprt_chan != NULL); /* fmd_transport_init() has happened */ 85 86 if ((fmd.d_dr_hdl = sysevent_bind_handle(fmd_dr_event)) == NULL) 87 fmd_error(EFMD_EXIT, "failed to bind handle for DR sysevent"); 88 89 if (sysevent_subscribe_event(fmd.d_dr_hdl, EC_DR, &subclass, 1) == -1) 90 fmd_error(EFMD_EXIT, "failed to subscribe for DR sysevent"); 91 } 92 93 void 94 fmd_dr_fini(void) 95 { 96 if (fmd.d_dr_hdl != NULL) { 97 sysevent_unsubscribe_event(fmd.d_dr_hdl, EC_DR); 98 sysevent_unbind_handle(fmd.d_dr_hdl); 99 } 100 } 101