static int sysev_evc_handler(sysevent_t *ev, void *cookie) { char *name, *zonename, *oldstate, *newstate; nvlist_t *nvlist; nvpair_t *curr, *next; cookie = cookie; // SILENCE! if (sysevent_get_attr_list(ev, &nvlist) != 0) { // XXX Error return (1); } // loop through event nvpairs to get our interesting values curr = nvlist_next_nvpair(nvlist, NULL); while (curr != NULL) { // all fields we're interested in are strings if (nvpair_type(curr) == DATA_TYPE_STRING) { name = nvpair_name(curr); if (strcmp(name, ZONE_CB_NAME) == 0) { nvpair_value_string(curr, &zonename); } else if (strcmp(name, ZONE_CB_NEWSTATE) == 0) { nvpair_value_string(curr, &newstate); } else if (strcmp(name, ZONE_CB_OLDSTATE) == 0) { nvpair_value_string(curr, &oldstate); } } next = nvlist_next_nvpair(nvlist, curr); curr = next; } // if it is a boot into running we need to enable the gate if (strcmp(oldstate, ZONE_EVENT_READY) == 0 && strcmp(newstate, ZONE_EVENT_RUNNING) == 0) { gate_attach(zonename); } // ignore multiple shutting_down -> shutting_down transitions if (strcmp(oldstate, newstate) != 0) { char zonebrand[MAXNAMELEN]; // get brand for zone if (zone_get_brand(zonename, zonebrand, sizeof (zonebrand)) == Z_OK) { request_send_state_event(zonename, zonebrand, oldstate, newstate); } else { request_send_state_event(zonename, NULL, oldstate, newstate); } } return (0); }
static int probe_event(sysevent_t *ev, void *arg) { nvlist_t *nvl; uint32_t state; uint32_t version; ipmpstat_probe_state_t *psp = arg; if (strcmp(sysevent_get_subclass_name(ev), ESC_IPMP_PROBE_STATE) != 0) return (0); if (sysevent_get_attr_list(ev, &nvl) != 0) { warn("sysevent_get_attr_list failed; dropping event"); return (0); } if (nvlist_lookup_uint32(nvl, IPMP_EVENT_VERSION, &version) != 0) { warn("dropped event with no IPMP_EVENT_VERSION\n"); goto out; } if (version != IPMP_EVENT_CUR_VERSION) { warn("dropped event with unsupported IPMP_EVENT_VERSION %d\n", version); goto out; } if (nvlist_lookup_uint32(nvl, IPMP_PROBE_STATE, &state) != 0) { warn("dropped event with no IPMP_PROBE_STATE\n"); goto out; } if (state == IPMP_PROBE_ACKED || state == IPMP_PROBE_LOST) ofmt_output(psp->ps_ofmt, psp->ps_ih, nvl); out: nvlist_free(nvl); return (0); }
/* Calls the client callback function, if one is registered */ static void notifyClient(sysevent_t *ev) { nvlist_t *attr_list = NULL; uint64_t *val = NULL; int32_t *instance = NULL; int32_t *major = NULL; int valAllocated = 0; uint_t nelem = 0; int i = 0; int eventType = 0; int index = -1; void *pCallerData = NULL; char subClassName[256]; MP_BOOL becomingVisible = MP_FALSE; MP_OID_LIST *oidList = NULL; log(LOG_INFO, "notifyClient()", "- enter"); (void) strncpy(subClassName, sysevent_get_subclass_name(ev), 256); if (strstr(subClassName, "change")) { eventType = PROP_CHANGE; log(LOG_INFO, "notifyClient()", "- got a change event"); log(LOG_INFO, "notifyClient()", ": [%s]", subClassName); if (strncmp(subClassName, ESC_SUN_MP_PLUGIN_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_PLUGIN; } else if (strncmp(subClassName, ESC_SUN_MP_LU_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_MULTIPATH_LU; } else if (strncmp(subClassName, ESC_SUN_MP_PATH_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_PATH_LU; } else if (strncmp(subClassName, ESC_SUN_MP_INIT_PORT_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_INITIATOR_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_TPG_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_CHANGE, 255) == 0) { index = MP_OBJECT_TYPE_DEVICE_PRODUCT; } } else if ((strstr(subClassName, "add")) || (strstr(subClassName, "initiator_register"))) { eventType = VISA_CHANGE; becomingVisible = MP_TRUE; log(LOG_INFO, "notifyClient()", "- got a visibility" " add event"); log(LOG_INFO, "notifyClient()", ": [%s]", subClassName); if (strncmp(subClassName, ESC_SUN_MP_LU_ADD, 255) == 0) { index = MP_OBJECT_TYPE_MULTIPATH_LU; } else if (strncmp(subClassName, ESC_SUN_MP_PATH_ADD, 255) == 0) { index = MP_OBJECT_TYPE_PATH_LU; } else if (strncmp(subClassName, ESC_DDI_INITIATOR_REGISTER, 244) == 0) { index = MP_OBJECT_TYPE_INITIATOR_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_TPG_ADD, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_ADD, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_ADD, 255) == 0) { index = MP_OBJECT_TYPE_DEVICE_PRODUCT; } } else if ((strstr(subClassName, "remove")) || (strstr(subClassName, "initiator_unregister"))) { eventType = VISA_CHANGE; becomingVisible = MP_FALSE; log(LOG_INFO, "notifyClient()", "- got a visibility" " remove event"); log(LOG_INFO, "notifyClient()", ": [%s]", subClassName); if (strncmp(subClassName, ESC_SUN_MP_LU_REMOVE, 255) == 0) { index = MP_OBJECT_TYPE_MULTIPATH_LU; } else if (strncmp(subClassName, ESC_SUN_MP_PATH_REMOVE, 255) == 0) { index = MP_OBJECT_TYPE_PATH_LU; } else if (strncmp(subClassName, ESC_DDI_INITIATOR_UNREGISTER, 255) == 0) { index = MP_OBJECT_TYPE_INITIATOR_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_TPG_REMOVE, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT_GROUP; } else if (strncmp(subClassName, ESC_SUN_MP_TARGET_PORT_REMOVE, 255) == 0) { index = MP_OBJECT_TYPE_TARGET_PORT; } else if (strncmp(subClassName, ESC_SUN_MP_DEV_PROD_REMOVE, 255) == 0) { index = MP_OBJECT_TYPE_DEVICE_PRODUCT; } } else { log(LOG_INFO, "notifyClient()", "- got an unsupported event"); return; } if (index < 0) { log(LOG_INFO, "notifyClient()", "- index is less than zero"); return; } if (eventType == VISA_CHANGE) { (void) pthread_mutex_lock(&g_visa_mutex); if (NULL == g_Visibility_Callback_List[index].pClientFn) { log(LOG_INFO, "notifyClient()", "- no visibility change callback to notify"); (void) pthread_mutex_unlock(&g_visa_mutex); return; } (void) pthread_mutex_unlock(&g_visa_mutex); } if (eventType == PROP_CHANGE) { (void) pthread_mutex_lock(&g_prop_mutex); if (NULL == g_Property_Callback_List[index].pClientFn) { log(LOG_INFO, "notifyClient()", "- no property change callback to notify"); (void) pthread_mutex_unlock(&g_prop_mutex); return; } (void) pthread_mutex_unlock(&g_prop_mutex); } (void) sysevent_get_attr_list(ev, &attr_list); if (NULL != attr_list) { if ((VISA_CHANGE == eventType) && (MP_OBJECT_TYPE_PLUGIN == index)) { val = (uint64_t *)malloc(sizeof (uint64_t)); valAllocated = 1; /* * We have no well-defined way to determine our OSN. * Currently the common library uses 0 as OSN for every * plugin, so just use 0. If the OSN assigned by the * common library changed, this code would have to be * updated. */ *val = 0; nelem = 1; } else if ((VISA_CHANGE == eventType) && (MP_OBJECT_TYPE_INITIATOR_PORT == index)) { (void) nvlist_lookup_int32_array(attr_list, DDI_INSTANCE, &instance, &nelem); log(LOG_INFO, "notifyClient()", "- event (PHCI_INSTANCE) has [%d] elements", nelem); (void) nvlist_lookup_int32_array(attr_list, DDI_DRIVER_MAJOR, &major, &nelem); log(LOG_INFO, "notifyClient()", "- event (PHCI_DRIVER_MAJOR) has [%d] elements", nelem); if ((NULL != instance) & (NULL != major)) { val = (uint64_t *)malloc(sizeof (uint64_t)); valAllocated = 1; *val = 0; *val = MP_STORE_INST_TO_ID(*instance, *val); *val = MP_STORE_MAJOR_TO_ID(*major, *val); nelem = 1; } else { nelem = 0; } } else { (void) nvlist_lookup_uint64_array(attr_list, OIDLIST, &val, &nelem); log(LOG_INFO, "notifyClient()", "- event has [%d] elements", nelem); } if (nelem > 0) { for (i = 0; i < nelem; i++) { log(LOG_INFO, "notifyClient()", "- event [%d] = %llx", i, val[i]); } oidList = createOidList(nelem); if (NULL == oidList) { log(LOG_INFO, "notifyClient()", "- unable to create MP_OID_LIST"); log(LOG_INFO, "notifyClient()", "- error exit"); nvlist_free(attr_list); return; } oidList->oidCount = nelem; for (i = 0; i < nelem; i++) { oidList->oids[i].objectType = index; oidList->oids[i].ownerId = g_pluginOwnerID; oidList->oids[i].objectSequenceNumber = val[i]; } if (valAllocated) { free(val); } for (i = 0; i < oidList->oidCount; i++) { log(LOG_INFO, "notifyClient()", "oidList->oids[%d].objectType" " = %d", i, oidList->oids[i].objectType); log(LOG_INFO, "notifyClient()", "oidList->oids[%d].ownerId" " = %d", i, oidList->oids[i].ownerId); log(LOG_INFO, "notifyClient()", "oidList->oids[%d].objectSequenceNumber" " = %llx", i, oidList->oids[i].objectSequenceNumber); } if (eventType == PROP_CHANGE) { (void) pthread_mutex_lock(&g_prop_mutex); pCallerData = g_Property_Callback_List[index]. pCallerData; (g_Property_Callback_List[index].pClientFn) (oidList, pCallerData); (void) pthread_mutex_unlock(&g_prop_mutex); } else if (eventType == VISA_CHANGE) { (void) pthread_mutex_lock(&g_visa_mutex); pCallerData = g_Visibility_Callback_List[index]. pCallerData; (g_Visibility_Callback_List[index].pClientFn) (becomingVisible, oidList, pCallerData); (void) pthread_mutex_unlock(&g_visa_mutex); } } nvlist_free(attr_list); } log(LOG_INFO, "notifyClient()", "- exit"); }
/* Event handler called by system */ static void syseventHandler(sysevent_t *ev) { const char ROUTINE[] = "syseventHandler"; nvlist_t *attrList = NULL; char *eventStr, *portAddrStr, *charptr; int update; uint64_t addr; uint8_t phyId, linkRate; HBA_WWN portAddr; /* Is the event one of ours? */ if (strncmp(EC_HBA, sysevent_get_class_name(ev), strlen(EC_HBA)) == 0) { /* handle phy events */ if (strncmp(ESC_SAS_PHY_EVENT, sysevent_get_subclass_name(ev), strlen(ESC_SAS_PHY_EVENT)) == 0) { if (sysevent_get_attr_list(ev, &attrList) != 0) { log(LOG_DEBUG, ROUTINE, "Failed to get event attributes on %s/%s", EC_HBA, ESC_SAS_PHY_EVENT); return; } else { if (nvlist_lookup_string(attrList, "event_type", &eventStr) != 0) { log(LOG_DEBUG, ROUTINE, "Event type not found"); return; } else { if (strncmp(eventStr, "phy_online", sizeof (eventStr)) == 0) { update = ONLINE; if (nvlist_lookup_uint8( attrList, "link_rate", &linkRate) != 0) { log(LOG_DEBUG, ROUTINE, "Link Rate not \ found"); return; } } else if (strncmp(eventStr, "phy_offline", sizeof (eventStr)) == 0) { update = OFFLINE; } else if (strncmp(eventStr, "phy_remove", sizeof (eventStr)) == 0) { update = REMOVED; } else { log(LOG_DEBUG, ROUTINE, "Invalid event type"); return; } } if (nvlist_lookup_string(attrList, "port_address", &portAddrStr) != 0) { log(LOG_DEBUG, ROUTINE, "Port SAS address not found"); return; } else { for (charptr = portAddrStr; charptr != NULL; charptr++) { if (isxdigit(*charptr)) { break; } } addr = htonll(strtoll(charptr, NULL, 16)); (void) memcpy(portAddr.wwn, &addr, 8); } if (nvlist_lookup_uint8(attrList, "PhyIdentifier", &phyId) != 0) { log(LOG_DEBUG, ROUTINE, "Port SAS address not found"); return; } }