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 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 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 } 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 } 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 } 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 } 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 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 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 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 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 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 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 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 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 549fcf3ce44SJohn Forte int32_t FCSyseventBridge::getMaxListener() { 550fcf3ce44SJohn Forte return (INT_MAX); 551fcf3ce44SJohn Forte } 552