xref: /onnv-gate/usr/src/lib/sun_fc/common/FCSyseventBridge.cc (revision 7836:4e95154b5b7a)
1*7836SJohn.Forte@Sun.COM /*
2*7836SJohn.Forte@Sun.COM  * CDDL HEADER START
3*7836SJohn.Forte@Sun.COM  *
4*7836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
5*7836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
6*7836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
7*7836SJohn.Forte@Sun.COM  *
8*7836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
11*7836SJohn.Forte@Sun.COM  * and limitations under the License.
12*7836SJohn.Forte@Sun.COM  *
13*7836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7836SJohn.Forte@Sun.COM  *
19*7836SJohn.Forte@Sun.COM  * CDDL HEADER END
20*7836SJohn.Forte@Sun.COM  */
21*7836SJohn.Forte@Sun.COM /*
22*7836SJohn.Forte@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*7836SJohn.Forte@Sun.COM  * Use is subject to license terms.
24*7836SJohn.Forte@Sun.COM  */
25*7836SJohn.Forte@Sun.COM 
26*7836SJohn.Forte@Sun.COM 
27*7836SJohn.Forte@Sun.COM 
28*7836SJohn.Forte@Sun.COM #include "FCSyseventBridge.h"
29*7836SJohn.Forte@Sun.COM #include "Exceptions.h"
30*7836SJohn.Forte@Sun.COM #include "Trace.h"
31*7836SJohn.Forte@Sun.COM #include "AdapterAddEvent.h"
32*7836SJohn.Forte@Sun.COM #include "AdapterEvent.h"
33*7836SJohn.Forte@Sun.COM #include "AdapterPortEvent.h"
34*7836SJohn.Forte@Sun.COM #include "AdapterDeviceEvent.h"
35*7836SJohn.Forte@Sun.COM #include "TargetEvent.h"
36*7836SJohn.Forte@Sun.COM #include "sun_fc.h"
37*7836SJohn.Forte@Sun.COM #include <libnvpair.h>
38*7836SJohn.Forte@Sun.COM #include <iostream>
39*7836SJohn.Forte@Sun.COM 
40*7836SJohn.Forte@Sun.COM using namespace std;
41*7836SJohn.Forte@Sun.COM 
42*7836SJohn.Forte@Sun.COM FCSyseventBridge* FCSyseventBridge::_instance = NULL;
43*7836SJohn.Forte@Sun.COM 
getInstance()44*7836SJohn.Forte@Sun.COM FCSyseventBridge* FCSyseventBridge::getInstance() {
45*7836SJohn.Forte@Sun.COM     Trace log("FCSyseventBridge::getInstance");
46*7836SJohn.Forte@Sun.COM     if (_instance == NULL) {
47*7836SJohn.Forte@Sun.COM 	_instance = new FCSyseventBridge();
48*7836SJohn.Forte@Sun.COM     }
49*7836SJohn.Forte@Sun.COM     return (_instance);
50*7836SJohn.Forte@Sun.COM 
51*7836SJohn.Forte@Sun.COM }
52*7836SJohn.Forte@Sun.COM 
53*7836SJohn.Forte@Sun.COM 
addListener(AdapterAddEventListener * listener)54*7836SJohn.Forte@Sun.COM void FCSyseventBridge::addListener(AdapterAddEventListener *listener) {
55*7836SJohn.Forte@Sun.COM     lock();
56*7836SJohn.Forte@Sun.COM     try {
57*7836SJohn.Forte@Sun.COM 	adapterAddEventListeners.insert(adapterAddEventListeners.begin(),
58*7836SJohn.Forte@Sun.COM 		listener);
59*7836SJohn.Forte@Sun.COM 	validateRegistration();
60*7836SJohn.Forte@Sun.COM 	unlock();
61*7836SJohn.Forte@Sun.COM     } catch (...) {
62*7836SJohn.Forte@Sun.COM 	unlock();
63*7836SJohn.Forte@Sun.COM 	throw;
64*7836SJohn.Forte@Sun.COM     }
65*7836SJohn.Forte@Sun.COM }
addListener(AdapterEventListener * listener,HBA * hba)66*7836SJohn.Forte@Sun.COM void FCSyseventBridge::addListener(AdapterEventListener *listener, HBA *hba) {
67*7836SJohn.Forte@Sun.COM     lock();
68*7836SJohn.Forte@Sun.COM     try {
69*7836SJohn.Forte@Sun.COM 	adapterEventListeners.insert(adapterEventListeners.begin(), listener);
70*7836SJohn.Forte@Sun.COM 	validateRegistration();
71*7836SJohn.Forte@Sun.COM 	unlock();
72*7836SJohn.Forte@Sun.COM     } catch (...) {
73*7836SJohn.Forte@Sun.COM 	unlock();
74*7836SJohn.Forte@Sun.COM 	throw;
75*7836SJohn.Forte@Sun.COM     }
76*7836SJohn.Forte@Sun.COM }
addListener(AdapterPortEventListener * listener,HBAPort * port)77*7836SJohn.Forte@Sun.COM void FCSyseventBridge::addListener(AdapterPortEventListener *listener,
78*7836SJohn.Forte@Sun.COM 	    HBAPort *port) {
79*7836SJohn.Forte@Sun.COM     lock();
80*7836SJohn.Forte@Sun.COM     try {
81*7836SJohn.Forte@Sun.COM 	adapterPortEventListeners.insert(adapterPortEventListeners.begin(),
82*7836SJohn.Forte@Sun.COM 		listener);
83*7836SJohn.Forte@Sun.COM 	validateRegistration();
84*7836SJohn.Forte@Sun.COM 	unlock();
85*7836SJohn.Forte@Sun.COM     } catch (...) {
86*7836SJohn.Forte@Sun.COM 	unlock();
87*7836SJohn.Forte@Sun.COM 	throw;
88*7836SJohn.Forte@Sun.COM     }
89*7836SJohn.Forte@Sun.COM }
addListener(AdapterDeviceEventListener * listener,HBAPort * port)90*7836SJohn.Forte@Sun.COM void FCSyseventBridge::addListener(AdapterDeviceEventListener *listener,
91*7836SJohn.Forte@Sun.COM     HBAPort *port) {
92*7836SJohn.Forte@Sun.COM 	lock();
93*7836SJohn.Forte@Sun.COM 	try {
94*7836SJohn.Forte@Sun.COM 		adapterDeviceEventListeners.insert(adapterDeviceEventListeners.begin(),
95*7836SJohn.Forte@Sun.COM 		    listener);
96*7836SJohn.Forte@Sun.COM 		validateRegistration();
97*7836SJohn.Forte@Sun.COM 		unlock();
98*7836SJohn.Forte@Sun.COM 	} catch (...) {
99*7836SJohn.Forte@Sun.COM 		unlock();
100*7836SJohn.Forte@Sun.COM 		throw;
101*7836SJohn.Forte@Sun.COM 	}
102*7836SJohn.Forte@Sun.COM }
addListener(TargetEventListener * listener,HBAPort * port,uint64_t targetWWN,bool filter)103*7836SJohn.Forte@Sun.COM void FCSyseventBridge::addListener(TargetEventListener *listener,
104*7836SJohn.Forte@Sun.COM 	    HBAPort *port, uint64_t targetWWN, bool filter) {
105*7836SJohn.Forte@Sun.COM     lock();
106*7836SJohn.Forte@Sun.COM     try {
107*7836SJohn.Forte@Sun.COM 	targetEventListeners.insert(targetEventListeners.begin(), listener);
108*7836SJohn.Forte@Sun.COM 	validateRegistration();
109*7836SJohn.Forte@Sun.COM 	unlock();
110*7836SJohn.Forte@Sun.COM     } catch (...) {
111*7836SJohn.Forte@Sun.COM 	unlock();
112*7836SJohn.Forte@Sun.COM 	throw;
113*7836SJohn.Forte@Sun.COM     }
114*7836SJohn.Forte@Sun.COM }
115*7836SJohn.Forte@Sun.COM 
removeListener(AdapterAddEventListener * listener)116*7836SJohn.Forte@Sun.COM void FCSyseventBridge::removeListener(AdapterAddEventListener *listener) {
117*7836SJohn.Forte@Sun.COM     lock();
118*7836SJohn.Forte@Sun.COM     try {
119*7836SJohn.Forte@Sun.COM 	typedef vector<AdapterAddEventListener *>::iterator Iter;
120*7836SJohn.Forte@Sun.COM 	for (Iter tmp = adapterAddEventListeners.begin();
121*7836SJohn.Forte@Sun.COM 		tmp != adapterAddEventListeners.end(); tmp++) {
122*7836SJohn.Forte@Sun.COM 	    if (*tmp == listener) {
123*7836SJohn.Forte@Sun.COM 		adapterAddEventListeners.erase(tmp);
124*7836SJohn.Forte@Sun.COM 		unlock();
125*7836SJohn.Forte@Sun.COM 		return;
126*7836SJohn.Forte@Sun.COM 	    }
127*7836SJohn.Forte@Sun.COM 	}
128*7836SJohn.Forte@Sun.COM 	throw InvalidHandleException();
129*7836SJohn.Forte@Sun.COM     } catch (...) {
130*7836SJohn.Forte@Sun.COM 	unlock();
131*7836SJohn.Forte@Sun.COM 	throw;
132*7836SJohn.Forte@Sun.COM     }
133*7836SJohn.Forte@Sun.COM }
134*7836SJohn.Forte@Sun.COM 
removeListener(AdapterEventListener * listener)135*7836SJohn.Forte@Sun.COM void FCSyseventBridge::removeListener(AdapterEventListener *listener) {
136*7836SJohn.Forte@Sun.COM     lock();
137*7836SJohn.Forte@Sun.COM     try {
138*7836SJohn.Forte@Sun.COM 	typedef vector<AdapterEventListener *>::iterator Iter;
139*7836SJohn.Forte@Sun.COM 	for (Iter tmp = adapterEventListeners.begin();
140*7836SJohn.Forte@Sun.COM 		tmp != adapterEventListeners.end(); tmp++) {
141*7836SJohn.Forte@Sun.COM 	    if (*tmp == listener) {
142*7836SJohn.Forte@Sun.COM 		adapterEventListeners.erase(tmp);
143*7836SJohn.Forte@Sun.COM 		unlock();
144*7836SJohn.Forte@Sun.COM 		return;
145*7836SJohn.Forte@Sun.COM 	    }
146*7836SJohn.Forte@Sun.COM 	}
147*7836SJohn.Forte@Sun.COM 	throw InvalidHandleException();
148*7836SJohn.Forte@Sun.COM     } catch (...) {
149*7836SJohn.Forte@Sun.COM 	unlock();
150*7836SJohn.Forte@Sun.COM 	throw;
151*7836SJohn.Forte@Sun.COM     }
152*7836SJohn.Forte@Sun.COM }
153*7836SJohn.Forte@Sun.COM 
removeListener(AdapterPortEventListener * listener)154*7836SJohn.Forte@Sun.COM void FCSyseventBridge::removeListener(AdapterPortEventListener *listener) {
155*7836SJohn.Forte@Sun.COM     lock();
156*7836SJohn.Forte@Sun.COM     try {
157*7836SJohn.Forte@Sun.COM 	typedef vector<AdapterPortEventListener *>::iterator Iter;
158*7836SJohn.Forte@Sun.COM 	for (Iter tmp = adapterPortEventListeners.begin();
159*7836SJohn.Forte@Sun.COM 		tmp != adapterPortEventListeners.end(); tmp++) {
160*7836SJohn.Forte@Sun.COM 	    if (*tmp == listener) {
161*7836SJohn.Forte@Sun.COM 		adapterPortEventListeners.erase(tmp);
162*7836SJohn.Forte@Sun.COM 		unlock();
163*7836SJohn.Forte@Sun.COM 		return;
164*7836SJohn.Forte@Sun.COM 	    }
165*7836SJohn.Forte@Sun.COM 	}
166*7836SJohn.Forte@Sun.COM 	throw InvalidHandleException();
167*7836SJohn.Forte@Sun.COM     } catch (...) {
168*7836SJohn.Forte@Sun.COM 	unlock();
169*7836SJohn.Forte@Sun.COM 	throw;
170*7836SJohn.Forte@Sun.COM     }
171*7836SJohn.Forte@Sun.COM }
172*7836SJohn.Forte@Sun.COM 
removeListener(AdapterDeviceEventListener * listener)173*7836SJohn.Forte@Sun.COM void FCSyseventBridge::removeListener(AdapterDeviceEventListener *listener) {
174*7836SJohn.Forte@Sun.COM 	lock();
175*7836SJohn.Forte@Sun.COM 	try {
176*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterDeviceEventListener *>::iterator Iter;
177*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterDeviceEventListeners.begin();
178*7836SJohn.Forte@Sun.COM 		    tmp != adapterDeviceEventListeners.end(); tmp++) {
179*7836SJohn.Forte@Sun.COM 			if (*tmp == listener) {
180*7836SJohn.Forte@Sun.COM 				adapterDeviceEventListeners.erase(tmp);
181*7836SJohn.Forte@Sun.COM 				unlock();
182*7836SJohn.Forte@Sun.COM 				return;
183*7836SJohn.Forte@Sun.COM 			}
184*7836SJohn.Forte@Sun.COM 		}
185*7836SJohn.Forte@Sun.COM 		throw InvalidHandleException();
186*7836SJohn.Forte@Sun.COM 	} catch (...) {
187*7836SJohn.Forte@Sun.COM 		unlock();
188*7836SJohn.Forte@Sun.COM 		throw;
189*7836SJohn.Forte@Sun.COM 	}
190*7836SJohn.Forte@Sun.COM }
191*7836SJohn.Forte@Sun.COM 
removeListener(TargetEventListener * listener)192*7836SJohn.Forte@Sun.COM void FCSyseventBridge::removeListener(TargetEventListener *listener) {
193*7836SJohn.Forte@Sun.COM     lock();
194*7836SJohn.Forte@Sun.COM     try {
195*7836SJohn.Forte@Sun.COM 	typedef vector<TargetEventListener *>::iterator Iter;
196*7836SJohn.Forte@Sun.COM 	for (Iter tmp = targetEventListeners.begin();
197*7836SJohn.Forte@Sun.COM 		tmp != targetEventListeners.end(); tmp++) {
198*7836SJohn.Forte@Sun.COM 	    if (*tmp == listener) {
199*7836SJohn.Forte@Sun.COM 		targetEventListeners.erase(tmp);
200*7836SJohn.Forte@Sun.COM 		unlock();
201*7836SJohn.Forte@Sun.COM 		return;
202*7836SJohn.Forte@Sun.COM 	    }
203*7836SJohn.Forte@Sun.COM 	}
204*7836SJohn.Forte@Sun.COM 	throw InvalidHandleException();
205*7836SJohn.Forte@Sun.COM     } catch (...) {
206*7836SJohn.Forte@Sun.COM 	unlock();
207*7836SJohn.Forte@Sun.COM 	throw;
208*7836SJohn.Forte@Sun.COM     }
209*7836SJohn.Forte@Sun.COM }
210*7836SJohn.Forte@Sun.COM 
static_dispatch(sysevent_t * ev)211*7836SJohn.Forte@Sun.COM extern "C" void static_dispatch(sysevent_t *ev) {
212*7836SJohn.Forte@Sun.COM     Trace log("static_dispatch");
213*7836SJohn.Forte@Sun.COM     FCSyseventBridge::getInstance()->dispatch(ev);
214*7836SJohn.Forte@Sun.COM }
215*7836SJohn.Forte@Sun.COM 
dispatch(sysevent_t * ev)216*7836SJohn.Forte@Sun.COM void FCSyseventBridge::dispatch(sysevent_t *ev) {
217*7836SJohn.Forte@Sun.COM     Trace log("FCSyseventBridge::dispatch");
218*7836SJohn.Forte@Sun.COM     nvlist_t		    *list = NULL;
219*7836SJohn.Forte@Sun.COM     hrtime_t			when;
220*7836SJohn.Forte@Sun.COM 
221*7836SJohn.Forte@Sun.COM     if (ev == NULL) {
222*7836SJohn.Forte@Sun.COM 	log.debug("Null event.");
223*7836SJohn.Forte@Sun.COM 	return;
224*7836SJohn.Forte@Sun.COM     }
225*7836SJohn.Forte@Sun.COM 
226*7836SJohn.Forte@Sun.COM     if (sysevent_get_attr_list(ev, &list) || list == NULL) {
227*7836SJohn.Forte@Sun.COM 	log.debug("Empty event.");
228*7836SJohn.Forte@Sun.COM 	return;
229*7836SJohn.Forte@Sun.COM     }
230*7836SJohn.Forte@Sun.COM 
231*7836SJohn.Forte@Sun.COM     string eventVendor = sysevent_get_vendor_name(ev);
232*7836SJohn.Forte@Sun.COM     string eventPublisher = sysevent_get_pub_name(ev);
233*7836SJohn.Forte@Sun.COM     string eventClass = sysevent_get_class_name(ev);
234*7836SJohn.Forte@Sun.COM     string eventSubClass = sysevent_get_subclass_name(ev);
235*7836SJohn.Forte@Sun.COM 
236*7836SJohn.Forte@Sun.COM     sysevent_get_time(ev, &when);
237*7836SJohn.Forte@Sun.COM 
238*7836SJohn.Forte@Sun.COM     // Now that we know what type of event it is, handle it accordingly
239*7836SJohn.Forte@Sun.COM     if (eventClass == "EC_sunfc") {
240*7836SJohn.Forte@Sun.COM 
241*7836SJohn.Forte@Sun.COM 	// All events of this class type have instance and port-wwn for
242*7836SJohn.Forte@Sun.COM 	// the HBA port.
243*7836SJohn.Forte@Sun.COM 	uint32_t	instance;
244*7836SJohn.Forte@Sun.COM 	if (nvlist_lookup_uint32(list, (char *)"instance",
245*7836SJohn.Forte@Sun.COM 		&instance)) {
246*7836SJohn.Forte@Sun.COM 	    log.genericIOError(
247*7836SJohn.Forte@Sun.COM 		"Improperly formed event: no instance field.");
248*7836SJohn.Forte@Sun.COM 	    nvlist_free(list);
249*7836SJohn.Forte@Sun.COM 	    return;
250*7836SJohn.Forte@Sun.COM 	}
251*7836SJohn.Forte@Sun.COM 	uchar_t		*rawPortWWN;
252*7836SJohn.Forte@Sun.COM 	uint32_t	rawPortWWNLength;
253*7836SJohn.Forte@Sun.COM 
254*7836SJohn.Forte@Sun.COM 	if (nvlist_lookup_byte_array(list, (char *)"port-wwn",
255*7836SJohn.Forte@Sun.COM 		&rawPortWWN, &rawPortWWNLength)) {
256*7836SJohn.Forte@Sun.COM 	    log.genericIOError(
257*7836SJohn.Forte@Sun.COM 		"Improperly formed event: no port-wwn field.");
258*7836SJohn.Forte@Sun.COM 	    nvlist_free(list);
259*7836SJohn.Forte@Sun.COM 	    return;
260*7836SJohn.Forte@Sun.COM 	}
261*7836SJohn.Forte@Sun.COM 
262*7836SJohn.Forte@Sun.COM 	// Now deal with the specific details of each subclass type
263*7836SJohn.Forte@Sun.COM 	if (eventSubClass == "ESC_sunfc_port_offline") {
264*7836SJohn.Forte@Sun.COM 
265*7836SJohn.Forte@Sun.COM 	    // Create event instance
266*7836SJohn.Forte@Sun.COM 	    AdapterPortEvent event(
267*7836SJohn.Forte@Sun.COM 		wwnConversion(rawPortWWN),
268*7836SJohn.Forte@Sun.COM 		AdapterPortEvent::OFFLINE,
269*7836SJohn.Forte@Sun.COM 		0);
270*7836SJohn.Forte@Sun.COM 
271*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
272*7836SJohn.Forte@Sun.COM 	    lock();
273*7836SJohn.Forte@Sun.COM 	    try {
274*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterPortEventListener *>::iterator Iter;
275*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterPortEventListeners.begin();
276*7836SJohn.Forte@Sun.COM 			tmp != adapterPortEventListeners.end(); tmp++) {
277*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
278*7836SJohn.Forte@Sun.COM 		}
279*7836SJohn.Forte@Sun.COM 	    } catch (...) {
280*7836SJohn.Forte@Sun.COM 		unlock();
281*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
282*7836SJohn.Forte@Sun.COM 		throw;
283*7836SJohn.Forte@Sun.COM 	    }
284*7836SJohn.Forte@Sun.COM 	    unlock();
285*7836SJohn.Forte@Sun.COM 
286*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_port_online") {
287*7836SJohn.Forte@Sun.COM 
288*7836SJohn.Forte@Sun.COM 	    // Create event instance
289*7836SJohn.Forte@Sun.COM 	    AdapterPortEvent event(
290*7836SJohn.Forte@Sun.COM 		wwnConversion(rawPortWWN),
291*7836SJohn.Forte@Sun.COM 		AdapterPortEvent::ONLINE,
292*7836SJohn.Forte@Sun.COM 		0);
293*7836SJohn.Forte@Sun.COM 
294*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
295*7836SJohn.Forte@Sun.COM 	    lock();
296*7836SJohn.Forte@Sun.COM 	    try {
297*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterPortEventListener *>::iterator Iter;
298*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterPortEventListeners.begin();
299*7836SJohn.Forte@Sun.COM 			tmp != adapterPortEventListeners.end(); tmp++) {
300*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
301*7836SJohn.Forte@Sun.COM 		}
302*7836SJohn.Forte@Sun.COM 	    } catch (...) {
303*7836SJohn.Forte@Sun.COM 		unlock();
304*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
305*7836SJohn.Forte@Sun.COM 		throw;
306*7836SJohn.Forte@Sun.COM 	    }
307*7836SJohn.Forte@Sun.COM 	    unlock();
308*7836SJohn.Forte@Sun.COM 
309*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_device_online") {
310*7836SJohn.Forte@Sun.COM 		AdapterDeviceEvent event(
311*7836SJohn.Forte@Sun.COM 		    wwnConversion(rawPortWWN),
312*7836SJohn.Forte@Sun.COM 		    AdapterDeviceEvent::ONLINE,
313*7836SJohn.Forte@Sun.COM 		    0);
314*7836SJohn.Forte@Sun.COM 		lock();
315*7836SJohn.Forte@Sun.COM 		try {
316*7836SJohn.Forte@Sun.COM 			typedef vector<AdapterDeviceEventListener *>::iterator Iter;
317*7836SJohn.Forte@Sun.COM 			for (Iter tmp = adapterDeviceEventListeners.begin();
318*7836SJohn.Forte@Sun.COM 			    tmp != adapterDeviceEventListeners.end(); tmp++) {
319*7836SJohn.Forte@Sun.COM 				(*tmp)->dispatch(event);
320*7836SJohn.Forte@Sun.COM 			}
321*7836SJohn.Forte@Sun.COM 		} catch (...) {
322*7836SJohn.Forte@Sun.COM 			unlock();
323*7836SJohn.Forte@Sun.COM 			nvlist_free(list);
324*7836SJohn.Forte@Sun.COM 			throw;
325*7836SJohn.Forte@Sun.COM 		}
326*7836SJohn.Forte@Sun.COM 		unlock();
327*7836SJohn.Forte@Sun.COM 
328*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_device_offline") {
329*7836SJohn.Forte@Sun.COM 		AdapterDeviceEvent event(
330*7836SJohn.Forte@Sun.COM 		    wwnConversion(rawPortWWN),
331*7836SJohn.Forte@Sun.COM 		    AdapterDeviceEvent::OFFLINE,
332*7836SJohn.Forte@Sun.COM 		    0);
333*7836SJohn.Forte@Sun.COM 		lock();
334*7836SJohn.Forte@Sun.COM 		try {
335*7836SJohn.Forte@Sun.COM 			typedef vector<AdapterDeviceEventListener *>::iterator Iter;
336*7836SJohn.Forte@Sun.COM 			for (Iter tmp = adapterDeviceEventListeners.begin();
337*7836SJohn.Forte@Sun.COM 			    tmp != adapterDeviceEventListeners.end(); tmp++) {
338*7836SJohn.Forte@Sun.COM 				(*tmp)->dispatch(event);
339*7836SJohn.Forte@Sun.COM 			}
340*7836SJohn.Forte@Sun.COM 		} catch (...) {
341*7836SJohn.Forte@Sun.COM 			unlock();
342*7836SJohn.Forte@Sun.COM 			nvlist_free(list);
343*7836SJohn.Forte@Sun.COM 			throw;
344*7836SJohn.Forte@Sun.COM 		}
345*7836SJohn.Forte@Sun.COM 		unlock();
346*7836SJohn.Forte@Sun.COM 
347*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_port_rscn") {
348*7836SJohn.Forte@Sun.COM 	    /*
349*7836SJohn.Forte@Sun.COM 	     * RSCNs are a little tricky.  There can be multiple
350*7836SJohn.Forte@Sun.COM 	     * affected page properties, each numbered.  To make sure
351*7836SJohn.Forte@Sun.COM 	     * we get them all, we loop through all properties
352*7836SJohn.Forte@Sun.COM 	     * in the nvlist and if their name begins with "affected_page_"
353*7836SJohn.Forte@Sun.COM 	     * then we send an event for them.
354*7836SJohn.Forte@Sun.COM 	     */
355*7836SJohn.Forte@Sun.COM 	    uint32_t	affected_page;
356*7836SJohn.Forte@Sun.COM 	    nvpair_t    *attr = NULL;
357*7836SJohn.Forte@Sun.COM 	    for (attr = nvlist_next_nvpair(list, NULL);
358*7836SJohn.Forte@Sun.COM 		    attr != NULL;
359*7836SJohn.Forte@Sun.COM 		    attr = nvlist_next_nvpair(list, attr)) {
360*7836SJohn.Forte@Sun.COM 		string name = nvpair_name(attr);
361*7836SJohn.Forte@Sun.COM 		if (name.find("affected_page_") != name.npos) {
362*7836SJohn.Forte@Sun.COM 
363*7836SJohn.Forte@Sun.COM 		    if (nvpair_value_uint32(attr, &affected_page)) {
364*7836SJohn.Forte@Sun.COM 			log.genericIOError(
365*7836SJohn.Forte@Sun.COM 			    "Improperly formed event: "
366*7836SJohn.Forte@Sun.COM 			    "corrupt affected_page field");
367*7836SJohn.Forte@Sun.COM 			continue;
368*7836SJohn.Forte@Sun.COM 		    }
369*7836SJohn.Forte@Sun.COM 		    // Create event instance
370*7836SJohn.Forte@Sun.COM 		    AdapterPortEvent event(
371*7836SJohn.Forte@Sun.COM 			wwnConversion(rawPortWWN),
372*7836SJohn.Forte@Sun.COM 			AdapterPortEvent::FABRIC,
373*7836SJohn.Forte@Sun.COM 			affected_page);
374*7836SJohn.Forte@Sun.COM 
375*7836SJohn.Forte@Sun.COM 		    // Dispatch to interested parties.
376*7836SJohn.Forte@Sun.COM 		    lock();
377*7836SJohn.Forte@Sun.COM 		    typedef vector<AdapterPortEventListener *>::iterator Iter;
378*7836SJohn.Forte@Sun.COM 		    try {
379*7836SJohn.Forte@Sun.COM 			for (Iter tmp = adapterPortEventListeners.begin();
380*7836SJohn.Forte@Sun.COM 				tmp != adapterPortEventListeners.end(); tmp++) {
381*7836SJohn.Forte@Sun.COM 			    (*tmp)->dispatch(event);
382*7836SJohn.Forte@Sun.COM 			}
383*7836SJohn.Forte@Sun.COM 		    } catch (...) {
384*7836SJohn.Forte@Sun.COM 			unlock();
385*7836SJohn.Forte@Sun.COM 			nvlist_free(list);
386*7836SJohn.Forte@Sun.COM 			throw;
387*7836SJohn.Forte@Sun.COM 		    }
388*7836SJohn.Forte@Sun.COM 		    unlock();
389*7836SJohn.Forte@Sun.COM 		}
390*7836SJohn.Forte@Sun.COM 	    }
391*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_target_add") {
392*7836SJohn.Forte@Sun.COM 	    uchar_t	*rawTargetPortWWN;
393*7836SJohn.Forte@Sun.COM 	    uint32_t	rawTargetPortWWNLength;
394*7836SJohn.Forte@Sun.COM 
395*7836SJohn.Forte@Sun.COM 	    if (nvlist_lookup_byte_array(list, (char *)"target-port-wwn",
396*7836SJohn.Forte@Sun.COM 		    &rawTargetPortWWN, &rawTargetPortWWNLength)) {
397*7836SJohn.Forte@Sun.COM 		log.genericIOError(
398*7836SJohn.Forte@Sun.COM 		    "Improperly formed event: no target-port-wwn field.");
399*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
400*7836SJohn.Forte@Sun.COM 		return;
401*7836SJohn.Forte@Sun.COM 	    }
402*7836SJohn.Forte@Sun.COM 
403*7836SJohn.Forte@Sun.COM 	    // Create event instance
404*7836SJohn.Forte@Sun.COM 	    AdapterPortEvent event(
405*7836SJohn.Forte@Sun.COM 		wwnConversion(rawPortWWN),
406*7836SJohn.Forte@Sun.COM 		AdapterPortEvent::NEW_TARGETS,
407*7836SJohn.Forte@Sun.COM 		0);
408*7836SJohn.Forte@Sun.COM 
409*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
410*7836SJohn.Forte@Sun.COM 	    lock();
411*7836SJohn.Forte@Sun.COM 	    try {
412*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterPortEventListener *>::iterator Iter;
413*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterPortEventListeners.begin();
414*7836SJohn.Forte@Sun.COM 			tmp != adapterPortEventListeners.end(); tmp++) {
415*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
416*7836SJohn.Forte@Sun.COM 		}
417*7836SJohn.Forte@Sun.COM 	    } catch (...) {
418*7836SJohn.Forte@Sun.COM 		unlock();
419*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
420*7836SJohn.Forte@Sun.COM 		throw;
421*7836SJohn.Forte@Sun.COM 	    }
422*7836SJohn.Forte@Sun.COM 	    unlock();
423*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_target_remove") {
424*7836SJohn.Forte@Sun.COM 	    uchar_t	*rawTargetPortWWN;
425*7836SJohn.Forte@Sun.COM 	    uint32_t	rawTargetPortWWNLength;
426*7836SJohn.Forte@Sun.COM 
427*7836SJohn.Forte@Sun.COM 	    if (nvlist_lookup_byte_array(list, (char *)"target-port-wwn",
428*7836SJohn.Forte@Sun.COM 		    &rawTargetPortWWN, &rawTargetPortWWNLength)) {
429*7836SJohn.Forte@Sun.COM 		log.genericIOError(
430*7836SJohn.Forte@Sun.COM 		    "Improperly formed event: no target-port-wwn field.");
431*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
432*7836SJohn.Forte@Sun.COM 		return;
433*7836SJohn.Forte@Sun.COM 	    }
434*7836SJohn.Forte@Sun.COM 	    // Create event instance
435*7836SJohn.Forte@Sun.COM 	    TargetEvent event(
436*7836SJohn.Forte@Sun.COM 		wwnConversion(rawPortWWN),
437*7836SJohn.Forte@Sun.COM 		wwnConversion(rawTargetPortWWN),
438*7836SJohn.Forte@Sun.COM 		TargetEvent::REMOVED);
439*7836SJohn.Forte@Sun.COM 
440*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
441*7836SJohn.Forte@Sun.COM 	    lock();
442*7836SJohn.Forte@Sun.COM 	    try {
443*7836SJohn.Forte@Sun.COM 		typedef vector<TargetEventListener *>::iterator Iter;
444*7836SJohn.Forte@Sun.COM 		for (Iter tmp = targetEventListeners.begin();
445*7836SJohn.Forte@Sun.COM 			tmp != targetEventListeners.end(); tmp++) {
446*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
447*7836SJohn.Forte@Sun.COM 		}
448*7836SJohn.Forte@Sun.COM 	    } catch (...) {
449*7836SJohn.Forte@Sun.COM 		unlock();
450*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
451*7836SJohn.Forte@Sun.COM 		throw;
452*7836SJohn.Forte@Sun.COM 	    }
453*7836SJohn.Forte@Sun.COM 	    unlock();
454*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_port_attach") {
455*7836SJohn.Forte@Sun.COM 	    // Create event instance
456*7836SJohn.Forte@Sun.COM 	    AdapterAddEvent event(wwnConversion(rawPortWWN));
457*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
458*7836SJohn.Forte@Sun.COM 	    lock();
459*7836SJohn.Forte@Sun.COM 	    try {
460*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterAddEventListener *>::iterator Iter;
461*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterAddEventListeners.begin();
462*7836SJohn.Forte@Sun.COM 			tmp != adapterAddEventListeners.end(); tmp++) {
463*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
464*7836SJohn.Forte@Sun.COM 		}
465*7836SJohn.Forte@Sun.COM 	    } catch (...) {
466*7836SJohn.Forte@Sun.COM 		unlock();
467*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
468*7836SJohn.Forte@Sun.COM 		throw;
469*7836SJohn.Forte@Sun.COM 	    }
470*7836SJohn.Forte@Sun.COM 	    unlock();
471*7836SJohn.Forte@Sun.COM 	} else if (eventSubClass == "ESC_sunfc_port_detach") {
472*7836SJohn.Forte@Sun.COM 	    // Technically, we should probably try to coalesce
473*7836SJohn.Forte@Sun.COM 	    // all detach events for the same multi-ported adapter
474*7836SJohn.Forte@Sun.COM 	    // and only send one event to the client, but for now,
475*7836SJohn.Forte@Sun.COM 	    // we'll just blindly send duplicates.
476*7836SJohn.Forte@Sun.COM 
477*7836SJohn.Forte@Sun.COM 	    // Create event instance
478*7836SJohn.Forte@Sun.COM 	    AdapterEvent event(
479*7836SJohn.Forte@Sun.COM 		wwnConversion(rawPortWWN),
480*7836SJohn.Forte@Sun.COM 		AdapterEvent::REMOVE);
481*7836SJohn.Forte@Sun.COM 
482*7836SJohn.Forte@Sun.COM 	    // Dispatch to interested parties.
483*7836SJohn.Forte@Sun.COM 	    lock();
484*7836SJohn.Forte@Sun.COM 	    try {
485*7836SJohn.Forte@Sun.COM 		typedef vector<AdapterEventListener *>::iterator Iter;
486*7836SJohn.Forte@Sun.COM 		for (Iter tmp = adapterEventListeners.begin();
487*7836SJohn.Forte@Sun.COM 			tmp != adapterEventListeners.end(); tmp++) {
488*7836SJohn.Forte@Sun.COM 		    (*tmp)->dispatch(event);
489*7836SJohn.Forte@Sun.COM 		}
490*7836SJohn.Forte@Sun.COM 	    } catch (...) {
491*7836SJohn.Forte@Sun.COM 		unlock();
492*7836SJohn.Forte@Sun.COM 		nvlist_free(list);
493*7836SJohn.Forte@Sun.COM 		throw;
494*7836SJohn.Forte@Sun.COM 	    }
495*7836SJohn.Forte@Sun.COM 	    unlock();
496*7836SJohn.Forte@Sun.COM 
497*7836SJohn.Forte@Sun.COM 	} else {
498*7836SJohn.Forte@Sun.COM 	    log.genericIOError(
499*7836SJohn.Forte@Sun.COM 		    "Unrecognized subclass \"%s\": Ignoring event",
500*7836SJohn.Forte@Sun.COM 		    eventSubClass.c_str());
501*7836SJohn.Forte@Sun.COM 	}
502*7836SJohn.Forte@Sun.COM     } else {
503*7836SJohn.Forte@Sun.COM 	// This should not happen, as we only asked for specific classes.
504*7836SJohn.Forte@Sun.COM 	log.genericIOError(
505*7836SJohn.Forte@Sun.COM 		"Unrecognized class \"%s\": Ignoring event",
506*7836SJohn.Forte@Sun.COM 		eventClass.c_str());
507*7836SJohn.Forte@Sun.COM     }
508*7836SJohn.Forte@Sun.COM     nvlist_free(list);
509*7836SJohn.Forte@Sun.COM }
510*7836SJohn.Forte@Sun.COM 
validateRegistration()511*7836SJohn.Forte@Sun.COM void FCSyseventBridge::validateRegistration() {
512*7836SJohn.Forte@Sun.COM     Trace log("FCSyseventBridge::validateRegistration");
513*7836SJohn.Forte@Sun.COM     uint64_t count = 0;
514*7836SJohn.Forte@Sun.COM     count = adapterAddEventListeners.size() +
515*7836SJohn.Forte@Sun.COM 	    adapterEventListeners.size() +
516*7836SJohn.Forte@Sun.COM 	    adapterPortEventListeners.size() +
517*7836SJohn.Forte@Sun.COM 	    targetEventListeners.size();
518*7836SJohn.Forte@Sun.COM     if (count == 1) {
519*7836SJohn.Forte@Sun.COM 	handle = sysevent_bind_handle(static_dispatch);
520*7836SJohn.Forte@Sun.COM 	if (handle == NULL) {
521*7836SJohn.Forte@Sun.COM 	    log.genericIOError(
522*7836SJohn.Forte@Sun.COM 		"Unable to bind sysevent handle.");
523*7836SJohn.Forte@Sun.COM 	    return;
524*7836SJohn.Forte@Sun.COM 	}
525*7836SJohn.Forte@Sun.COM 	const char *subclass_list[9] = {
526*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_port_attach",
527*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_port_detach",
528*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_port_offline",
529*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_port_online",
530*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_port_rscn",
531*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_target_add",
532*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_target_remove",
533*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_device_online",
534*7836SJohn.Forte@Sun.COM 		"ESC_sunfc_device_offline"
535*7836SJohn.Forte@Sun.COM 	    };
536*7836SJohn.Forte@Sun.COM 	if (sysevent_subscribe_event(handle,
537*7836SJohn.Forte@Sun.COM 		"EC_sunfc", (const char **)subclass_list, 9)) {
538*7836SJohn.Forte@Sun.COM 	    log.genericIOError(
539*7836SJohn.Forte@Sun.COM 		"Unable to subscribe to sun_fc events.");
540*7836SJohn.Forte@Sun.COM 	    sysevent_unbind_handle(handle);
541*7836SJohn.Forte@Sun.COM 	    handle = NULL;
542*7836SJohn.Forte@Sun.COM 	}
543*7836SJohn.Forte@Sun.COM     } else if (count == 0 && handle != NULL) {
544*7836SJohn.Forte@Sun.COM 	// Remove subscription
545*7836SJohn.Forte@Sun.COM 	sysevent_unbind_handle(handle);
546*7836SJohn.Forte@Sun.COM 	handle == NULL;
547*7836SJohn.Forte@Sun.COM     } // Else do nothing
548*7836SJohn.Forte@Sun.COM }
549*7836SJohn.Forte@Sun.COM 
getMaxListener()550*7836SJohn.Forte@Sun.COM int32_t FCSyseventBridge::getMaxListener() {
551*7836SJohn.Forte@Sun.COM     return (INT_MAX);
552*7836SJohn.Forte@Sun.COM }
553