/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include "FCSyseventBridge.h"
#include "Exceptions.h"
#include "Trace.h"
#include "AdapterAddEvent.h"
#include "AdapterEvent.h"
#include "AdapterPortEvent.h"
#include "AdapterDeviceEvent.h"
#include "TargetEvent.h"
#include "sun_fc.h"
#include <libnvpair.h>
#include <iostream>
#include <climits>
using namespace std;
_instance = new FCSyseventBridge();
}
return (_instance);
}
lock();
try {
listener);
unlock();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
listener);
unlock();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
listener);
unlock();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
return;
}
}
throw InvalidHandleException();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
return;
}
}
throw InvalidHandleException();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
return;
}
}
throw InvalidHandleException();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
return;
}
}
throw InvalidHandleException();
} catch (...) {
unlock();
throw;
}
}
lock();
try {
unlock();
return;
}
}
throw InvalidHandleException();
} catch (...) {
unlock();
throw;
}
}
}
return;
}
return;
}
// Now that we know what type of event it is, handle it accordingly
if (eventClass == "EC_sunfc") {
// All events of this class type have instance and port-wwn for
// the HBA port.
&instance)) {
"Improperly formed event: no instance field.");
return;
}
&rawPortWWN, &rawPortWWNLength)) {
"Improperly formed event: no port-wwn field.");
return;
}
// Now deal with the specific details of each subclass type
if (eventSubClass == "ESC_sunfc_port_offline") {
// Create event instance
0);
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_port_online") {
// Create event instance
0);
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_device_online") {
0);
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_device_offline") {
0);
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_port_rscn") {
/*
* RSCNs are a little tricky. There can be multiple
* affected page properties, each numbered. To make sure
* we get them all, we loop through all properties
* in the nvlist and if their name begins with "affected_page_"
* then we send an event for them.
*/
"Improperly formed event: "
"corrupt affected_page field");
continue;
}
// Create event instance
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
}
}
} else if (eventSubClass == "ESC_sunfc_target_add") {
"Improperly formed event: no target-port-wwn field.");
return;
}
// Create event instance
0);
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_target_remove") {
"Improperly formed event: no target-port-wwn field.");
return;
}
// Create event instance
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_port_attach") {
// Create event instance
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else if (eventSubClass == "ESC_sunfc_port_detach") {
// Technically, we should probably try to coalesce
// all detach events for the same multi-ported adapter
// and only send one event to the client, but for now,
// we'll just blindly send duplicates.
// Create event instance
// Dispatch to interested parties.
lock();
try {
}
} catch (...) {
unlock();
throw;
}
unlock();
} else {
"Unrecognized subclass \"%s\": Ignoring event",
eventSubClass.c_str());
}
} else {
// This should not happen, as we only asked for specific classes.
"Unrecognized class \"%s\": Ignoring event",
eventClass.c_str());
}
}
if (count == 1) {
"Unable to bind sysevent handle.");
return;
}
"ESC_sunfc_port_attach",
"ESC_sunfc_port_detach",
"ESC_sunfc_port_offline",
"ESC_sunfc_port_online",
"ESC_sunfc_port_rscn",
"ESC_sunfc_target_add",
"ESC_sunfc_target_remove",
"ESC_sunfc_device_online",
"ESC_sunfc_device_offline"
};
"Unable to subscribe to sun_fc events.");
}
// Remove subscription
} // Else do nothing
}
return (INT_MAX);
}