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