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