/** * main: Starts with an RPTable of 10 resources, multiple rdrs * on some resources. Remove resource. Check if resource was removed * searching for it in sequence. If not fail, else passed test. * * Return value: 0 on success, 1 on failure **/ int main(int argc, char **argv) { RPTable *rptable = (RPTable *)g_malloc0(sizeof(RPTable)); SaHpiRptEntryT *tmpentry = NULL; guint i = 0; for (i = 0; rptentries[i].ResourceId != 0; i++) { if (oh_add_resource(rptable, rptentries + i, NULL, 0)) return 1; } for (i = 0; i < 5; i++) { if (oh_add_rdr(rptable, SAHPI_FIRST_ENTRY, rdrs + i, NULL,0)) return 1; } for (; i < 7; i++) { if (oh_add_rdr(rptable, rptentries[9].ResourceId, rdrs + i, NULL,0)) return 1; } oh_remove_resource(rptable, rptentries[0].ResourceId); for (tmpentry = oh_get_resource_by_id(rptable, SAHPI_FIRST_ENTRY); tmpentry; tmpentry = oh_get_resource_next(rptable, tmpentry->ResourceId)) { if (tmpentry->ResourceId == rptentries[0].ResourceId) return 1; } return 0; }
static int process_resource_event(struct oh_handler *h, RPTable *rpt, struct oh_event *e) { int rv; data_access_lock(); if (e->type == OH_ET_RESOURCE_DEL) { rv = oh_remove_resource(rpt,e->u.res_del_event.resource_id); } else { struct oh_resource_data *rd = g_malloc0(sizeof(struct oh_resource_data)); if (!rd) { dbg("Couldn't allocate resource data"); return SA_ERR_HPI_ERROR; } rd->handler = h; rd->controlled = 0; rd->auto_extract_timeout = get_default_hotswap_auto_extract_timeout(); rv = oh_add_resource(rpt,&(e->u.res_event.entry),rd,0); } data_access_unlock(); return rv; }
static int process_resource_event(struct oh_event *e) { int rv; RPTable *rpt = NULL; struct oh_domain *d = NULL; struct oh_event hpie; d = oh_get_domain(e->did); if(!d) { dbg("Domain %d doesn't exist", e->did); return -1; } rpt = &(d->rpt); memset(&hpie, 0, sizeof(hpie)); if (e->type == OH_ET_RESOURCE_DEL) { rv = oh_remove_resource(rpt,e->u.res_event.entry.ResourceId); trace("Resource %d in Domain %d has been REMOVED.", e->u.res_event.entry.ResourceId, e->did); hpie.did = e->did; hpie.u.hpi_event.event.Severity = e->u.res_event.entry.ResourceSeverity; hpie.u.hpi_event.event.Source = e->u.res_event.entry.ResourceId; hpie.u.hpi_event.event.EventType = SAHPI_ET_RESOURCE; hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType = SAHPI_RESE_RESOURCE_FAILURE; } else { struct oh_resource_data *rd = g_malloc0(sizeof(struct oh_resource_data)); if (!rd) { dbg("Couldn't allocate resource data"); return SA_ERR_HPI_OUT_OF_MEMORY; } rd->hid = e->hid; rd->controlled = 0; rd->auto_extract_timeout = get_default_hotswap_auto_extract_timeout(); rv = oh_add_resource(rpt,&(e->u.res_event.entry),rd,0); trace("Resource %d in Domain %d has been ADDED.", e->u.res_event.entry.ResourceId, e->did); hpie.did = e->did; hpie.u.hpi_event.event.Severity = e->u.res_event.entry.ResourceSeverity; hpie.u.hpi_event.event.Source = e->u.res_event.entry.ResourceId; hpie.u.hpi_event.event.EventType = SAHPI_ET_RESOURCE; hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType = SAHPI_RESE_RESOURCE_ADDED; } oh_release_domain(d); if (rv == SA_OK) { rv = process_hpi_event(&hpie); } return rv; }
static void delete_entity(struct oh_handler_state *handler, ipmi_entity_t *entity) { ipmi_entity_id_t entity_id = ipmi_entity_convert_to_id(entity); SaHpiRptEntryT *rpt; struct ohoi_resource_info *res_info; rpt = ohoi_get_resource_by_entityid(handler->rptcache, &entity_id); if (rpt == NULL) { dbg("couldn't find out resource"); return; } res_info = oh_get_resource_data(handler->rptcache, rpt->ResourceId); // send event to infrastructure and remove rpt entry struct oh_event *event = malloc(sizeof(*event)); if (event != NULL) { memset(event, 0, sizeof(*event)); event->type = OH_ET_RESOURCE_DEL; memcpy(&event->u.res_event.entry, rpt, sizeof(SaHpiRptEntryT)); handler->eventq = g_slist_append(handler->eventq, event); } else { dbg("Out of memory"); } while (SA_OK == oh_remove_rdr(handler->rptcache, rpt->ResourceId, SAHPI_FIRST_ENTRY)); if (res_info) { ohoi_delete_rpt_fru(res_info); } oh_remove_resource(handler->rptcache, rpt->ResourceId); }
/** * main: Starting with an empty RPTable, adds 10 resources to it * and removes one by specifying RPT_ENTRY_BEGIN as the Resource Id. * Removes again to make sure it is not there anymore. * Passes the test if the interface returns 0 (success), else it fails. * * Return value: 0 on success, 1 on failure **/ int main(int argc, char **argv) { RPTable *rptable = (RPTable *)g_malloc0(sizeof(RPTable)); guint i; for (i = 0; rptentries[i].ResourceId != 0; i++) { if (oh_add_resource(rptable, rptentries+i, NULL, 0)) return 1; } if (oh_remove_resource(rptable, RPT_ENTRY_BEGIN)) return 1; if (!oh_remove_resource(rptable, rptentries[0].ResourceId)) return 1; return 0; }
/** * oh_flush_rpt * @table: Pointer to the RPT to flush. * * Cleans RPT from all entries and RDRs and frees the memory * associated with them. * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_flush_rpt(RPTable *table) { SaHpiRptEntryT *tmp_entry; while ((tmp_entry = oh_get_resource_by_id(table, SAHPI_FIRST_ENTRY)) != NULL) { oh_remove_resource(table, SAHPI_FIRST_ENTRY); } return SA_OK; }
SaErrorT sim_resource_failed_remove(void *hnd, SaHpiResourceIdT rid) { struct oh_handler_state *h; SaHpiRptEntryT *resource = NULL; struct oh_event e; SaHpiHsStateT hsstate = SAHPI_HS_STATE_ACTIVE; SaErrorT rv; if (hnd == NULL) { err("Invalid parameter"); return SA_ERR_HPI_INVALID_PARAMS; } h = (struct oh_handler_state *) hnd; resource = oh_get_resource_by_id(h->rptcache, rid); if (resource == NULL) { err("Failed to get the RPT entry"); return SA_ERR_HPI_NOT_PRESENT; } if (resource->ResourceCapabilities & SAHPI_CAPABILITY_MANAGED_HOTSWAP) { rv = sim_get_hotswap_state(hnd, rid, &hsstate); if (rv != SA_OK) { err("Failed to get the hotswap state"); return rv; } } /* Raise the resource removal hotswap event */ memset(&e, 0, sizeof(struct oh_event)); e.hid = h->hid; e.resource = *resource; e.rdrs = NULL; e.event.Source = rid; e.event.Severity = resource->ResourceSeverity; oh_gettimeofday(&e.event.Timestamp); e.event.EventType = SAHPI_ET_HOTSWAP; e.event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = hsstate; e.event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_NOT_PRESENT; e.event.EventDataUnion.HotSwapEvent.CauseOfStateChange = SAHPI_HS_CAUSE_USER_UPDATE; oh_evt_queue_push(h->eventq, oh_dup_event(&e)); /* Remove the failed resource from plugin rptcache */ rv = oh_remove_resource(h->rptcache, rid); if (rv != SA_OK) { err("Resource removal from RPTable failed"); return rv; } return SA_OK; }
bool cIpmiResource::Destroy() { SaHpiRptEntryT *rptentry; stdlog << "removing resource: " << m_entity_path << ").\n"; // remove sensors while( Num() ) { cIpmiRdr *rdr = GetRdr( 0 ); RemRdr( rdr ); delete rdr; } // create remove event oh_event *e = (oh_event *)g_malloc0( sizeof( oh_event ) ); if ( !e ) { stdlog << "out of space !\n"; return false; } memset( e, 0, sizeof( struct oh_event ) ); e->type = OH_ET_RESOURCE_DEL; rptentry = oh_get_resource_by_id( Domain()->GetHandler()->rptcache, m_resource_id ); if ( !rptentry ) { stdlog << "Can't find resource in plugin cache !\n"; g_free( e ); return false; } e->u.res_event.entry = *rptentry; stdlog << "cIpmiResource::Destroy OH_ET_RESOURCE_DEL Event resource " << m_resource_id << "\n"; Domain()->AddHpiEvent( e ); // remove resource from local cache int rv = oh_remove_resource( Domain()->GetHandler()->rptcache, m_resource_id ); if ( rv != 0 ) { stdlog << "Can't remove resource from plugin cache !\n"; return false; } m_mc->RemResource( this ); delete this; return true; }
/** * oh_flush_rpt: Cleans RPT from all entries and RDRs and frees the memory * associated with them. * @table: Pointer to the RPT to flush. **/ void oh_flush_rpt(RPTable *table) { SaHpiRptEntryT *tmp_entry; if (!(table)) { dbg("ERROR: Cannot work on a null table pointer."); return; } while ((tmp_entry = oh_get_resource_by_id(table, RPT_ENTRY_BEGIN)) != NULL) { oh_remove_resource(table, RPT_ENTRY_BEGIN); } }
static int process_resource_event(struct oh_handler *h, RPTable *rpt, struct oh_event *e) { int rv; data_access_lock(); if (e->type == OH_ET_RESOURCE_DEL) { rv = oh_remove_resource(rpt,e->u.res_del_event.resource_id); } else { rv = oh_add_resource(rpt,&(e->u.res_event.entry),h); } data_access_unlock(); return rv; }
bool cIpmiResource::Destroy() { stdlog << "removing resource: " << m_entity_path << ").\n"; // remove sensors while( m_rdrs ) { cIpmiRdr *rdr = (cIpmiRdr *)m_rdrs->data; Rem( rdr ); delete rdr; } // create remove event oh_event *e = (oh_event *)g_malloc0( sizeof( oh_event ) ); if ( !e ) { stdlog << "out of space !\n"; return false; } memset( e, 0, sizeof( struct oh_event ) ); e->type = oh_event::OH_ET_RESOURCE_DEL; e->u.res_del_event.resource_id = m_resource_id; Domain()->AddHpiEvent( e ); // remove resource from local cache int rv = oh_remove_resource( Domain()->GetHandler()->rptcache, m_resource_id ); assert( rv == 0 ); m_mc->RemResource( this ); delete this; return true; }
static int process_hs_event(struct oh_domain *d, struct oh_event *e) { RPTable *rpt = NULL; SaHpiRptEntryT *exists = NULL; SaHpiHotSwapEventT * hse = NULL; unsigned int *hidp = NULL; SaErrorT error = SA_OK; if (!d || !e) { return -1; } rpt = &(d->rpt); exists = oh_get_resource_by_id(rpt, e->resource.ResourceId); hse = &e->event.EventDataUnion.HotSwapEvent; if (hse->HotSwapState == SAHPI_HS_STATE_NOT_PRESENT) { oh_remove_resource(rpt, e->resource.ResourceId); } else { hidp = g_new0(unsigned int, 1); *hidp = e->hid; error = oh_add_resource(rpt, &e->resource, hidp, FREE_RPT_DATA); if (error == SA_OK && !exists) { GSList *node = NULL; for (node = e->rdrs; node; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; oh_add_rdr(rpt, e->resource.ResourceId, rdr, NULL, 0); } } } if (hse->HotSwapState != hse->PreviousHotSwapState) { process_hpi_event(d, e); } return 0; }
static int process_resource_event(struct oh_domain *d, struct oh_event *e) { RPTable *rpt = NULL; SaHpiRptEntryT *exists = NULL; unsigned int *hidp = NULL; SaErrorT error = SA_OK; SaHpiBoolT process = TRUE; SaHpiBoolT update = FALSE; SaHpiBoolT remove = FALSE; if (!d || !e) { return -1; } rpt = &(d->rpt); exists = oh_get_resource_by_id(rpt, e->resource.ResourceId); switch ( e->event.EventDataUnion.ResourceEvent.ResourceEventType ) { case SAHPI_RESE_RESOURCE_FAILURE: case SAHPI_RESE_RESOURCE_INACCESSIBLE: if ( exists && exists->ResourceFailed ) { process = FALSE; } else { e->resource.ResourceFailed = SAHPI_TRUE; } break; case SAHPI_RESE_RESOURCE_RESTORED: if ( exists && exists->ResourceFailed ) { e->resource.ResourceFailed = SAHPI_FALSE; } else { process = FALSE; } break; case SAHPI_RESE_RESOURCE_ADDED: case SAHPI_RESE_RESOURCE_UPDATED: update = TRUE; break; case SAHPI_RESE_RESOURCE_REMOVED: remove = TRUE; process = ( exists != 0 ) ? TRUE : FALSE; break; default: // unknown resource event // do nothing CRIT("Got unknown resource event."); return -1; } if ( remove ) { if ( exists ) { oh_remove_resource(rpt, e->resource.ResourceId); } } else { hidp = g_new0(unsigned int, 1); *hidp = e->hid; error = oh_add_resource(rpt, &e->resource, hidp, FREE_RPT_DATA); if (error != SA_OK) { g_free( hidp ); CRIT("Cannot update resource."); return -1; } if ( update ) { GSList *node = NULL; for (node = e->rdrs_to_remove; node; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiInstrumentIdT instr_id = oh_get_instrument_id(rdr); SaHpiEntryIdT rdrid = oh_get_rdr_uid(rdr->RdrType, instr_id); oh_remove_rdr(rpt, e->resource.ResourceId, rdrid); } for (node = e->rdrs; node; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; oh_add_rdr(rpt, e->resource.ResourceId, rdr, NULL, 0); } } } if ( process ) { process_hpi_event(d, e); } return 0; }
static int snmp_rsa_discover_resources(void *hnd) { SaHpiEntityPathT entity_root; guint i; struct oh_event *e; struct snmp_value get_value; // struct snmp_value get_active; struct oh_handler_state *handle = (struct oh_handler_state *)hnd; struct snmp_rsa_hnd *custom_handle = (struct snmp_rsa_hnd *)handle->data; RPTable *tmpcache = (RPTable *)g_malloc0(sizeof(RPTable)); GSList *tmpqueue = NULL; char *root_tuple = (char *)g_hash_table_lookup(handle->config,"entity_root"); string2entitypath(root_tuple, &entity_root); /* see if the chassis exists by querying system health */ if(snmp_get(custom_handle->ss,".1.3.6.1.4.1.2.3.51.1.2.7.1.0",&get_value) != 0) { /* If we get here, something is hosed. No need to do more discovery */ dbg("Couldn't fetch SNMP RSA system health.\n"); dbg("There is no chassis."); g_free(tmpcache); return -1; } /* discover the chassis */ e = snmp_rsa_discover_chassis(handle, &entity_root); if(e != NULL) { struct ResourceMibInfo *res_mib = g_memdup(&(snmp_rsa_rpt_array[RSA_RPT_ENTRY_CHASSIS].rsa_res_info.mib), sizeof(struct snmp_rpt)); oh_add_resource(tmpcache,&(e->u.res_event.entry),res_mib,0); tmpqueue = g_slist_append(tmpqueue, e); SaHpiResourceIdT rid = e->u.res_event.entry.ResourceId; SaHpiEntityPathT parent_ep = e->u.res_event.entry.ResourceEntity; find_sensors(snmp_rsa_chassis_sensors); find_controls(snmp_rsa_chassis_controls); find_inventories(snmp_rsa_chassis_inventories); } /* discover all cpus */ for (i = 0; i < RSA_MAX_CPU; i++) { /* see if the cpu exists by querying the thermal sensor */ if((snmp_get(custom_handle->ss, snmp_rsa_cpu_thermal_sensors[i].rsa_sensor_info.mib.oid, &get_value) != 0) || (get_value.type != ASN_OCTET_STR) || (strcmp(get_value.string, "Not Readable!") == 0)) { /* If we get here the CPU is not installed */ dbg("CPU %d not found.\n", i+RSA_HPI_INSTANCE_BASE); continue; } e = snmp_rsa_discover_cpu(handle, &entity_root, i); if(e != NULL) { struct ResourceMibInfo *res_mib = g_memdup(&(snmp_rsa_rpt_array[RSA_RPT_ENTRY_CPU].rsa_res_info.mib), sizeof(struct snmp_rpt)); oh_add_resource(tmpcache,&(e->u.res_event.entry),res_mib,0); tmpqueue = g_slist_append(tmpqueue, e); SaHpiResourceIdT rid = e->u.res_event.entry.ResourceId; SaHpiEntityPathT parent_ep = e->u.res_event.entry.ResourceEntity; /* add the CPU thermal sensor */ e = snmp_rsa_discover_sensors(handle, parent_ep, &snmp_rsa_cpu_thermal_sensors[i]); if(e != NULL) { struct RSA_SensorInfo *rsa_data = g_memdup(&(snmp_rsa_cpu_thermal_sensors[i].rsa_sensor_info), sizeof(struct RSA_SensorInfo)); oh_add_rdr(tmpcache,rid,&(e->u.rdr_event.rdr), rsa_data, 0); tmpqueue = g_slist_append(tmpqueue, e); } } } /* discover all dasd */ for (i = 0; i < RSA_MAX_DASD; i++) { /* see if the dasd exists by querying the thermal sensor */ if((snmp_get(custom_handle->ss, snmp_rsa_dasd_thermal_sensors[i].rsa_sensor_info.mib.oid, &get_value) != 0) || (get_value.type != ASN_OCTET_STR) || (strcmp(get_value.string, "Not Readable!") == 0)) { /* If we get here the DASD is not installed */ dbg("DASD %d not found.\n", i+RSA_HPI_INSTANCE_BASE); continue; } e = snmp_rsa_discover_dasd(handle, &entity_root, i); if(e != NULL) { struct ResourceMibInfo *res_mib = g_memdup(&(snmp_rsa_rpt_array[RSA_RPT_ENTRY_DASD].rsa_res_info.mib), sizeof(struct snmp_rpt)); oh_add_resource(tmpcache,&(e->u.res_event.entry),res_mib,0); tmpqueue = g_slist_append(tmpqueue, e); SaHpiResourceIdT rid = e->u.res_event.entry.ResourceId; SaHpiEntityPathT parent_ep = e->u.res_event.entry.ResourceEntity; /* add the DASD thermal sensor */ e = snmp_rsa_discover_sensors(handle, parent_ep, &snmp_rsa_dasd_thermal_sensors[i]); if(e != NULL) { struct RSA_SensorInfo *rsa_data = g_memdup(&(snmp_rsa_dasd_thermal_sensors[i].rsa_sensor_info), sizeof(struct RSA_SensorInfo)); oh_add_rdr(tmpcache,rid,&(e->u.rdr_event.rdr), rsa_data, 0); tmpqueue = g_slist_append(tmpqueue, e); } } } /* discover all fans */ for (i = 0; i < RSA_MAX_FAN; i++) { /* see if the fan exists by querying the sensor */ if((snmp_get(custom_handle->ss, snmp_rsa_fan_sensors[i].rsa_sensor_info.mib.oid, &get_value) != 0) || (get_value.type != ASN_OCTET_STR) || (strcmp(get_value.string, "Not Readable!") == 0)) { /* If we get here the fan is not installed */ dbg("Fan %d not found.\n", i+RSA_HPI_INSTANCE_BASE); continue; } e = snmp_rsa_discover_fan(handle, &entity_root, i); if(e != NULL) { struct ResourceMibInfo *res_mib = g_memdup(&(snmp_rsa_rpt_array[RSA_RPT_ENTRY_FAN].rsa_res_info.mib), sizeof(struct snmp_rpt)); oh_add_resource(tmpcache,&(e->u.res_event.entry),res_mib,0); tmpqueue = g_slist_append(tmpqueue, e); SaHpiResourceIdT rid = e->u.res_event.entry.ResourceId; SaHpiEntityPathT parent_ep = e->u.res_event.entry.ResourceEntity; /* add the fan sensor */ e = snmp_rsa_discover_sensors(handle, parent_ep, &snmp_rsa_fan_sensors[i]); if(e != NULL) { struct RSA_SensorInfo *rsa_data = g_memdup(&(snmp_rsa_fan_sensors[i].rsa_sensor_info), sizeof(struct RSA_SensorInfo)); oh_add_rdr(tmpcache,rid,&(e->u.rdr_event.rdr), rsa_data, 0); tmpqueue = g_slist_append(tmpqueue, e); } } } /* Rediscovery: Get difference between current rptcache and tmpcache. Delete obsolete items from rptcache and add new items in. */ GSList *res_new = NULL, *rdr_new = NULL, *res_gone = NULL, *rdr_gone = NULL; GSList *node = NULL; rpt_diff(handle->rptcache, tmpcache, &res_new, &rdr_new, &res_gone, &rdr_gone); dbg("%d resources have gone away.", g_slist_length(res_gone)); dbg("%d resources are new or have changed", g_slist_length(res_new)); for (node = rdr_gone; node != NULL; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); /* Create remove rdr event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->type = OH_ET_RDR_DEL; e->u.rdr_del_event.record_id = rdr->RecordId; e->u.rdr_del_event.parent_entity = rdr->Entity; handle->eventq = g_slist_append(handle->eventq, e); } else dbg("Could not allocate more memory to create event."); /* Remove rdr from plugin's rpt cache */ if (rdr && res) oh_remove_rdr(handle->rptcache, res->ResourceId, rdr->RecordId); else dbg("No valid resource or rdr at hand. Could not remove rdr."); } g_slist_free(rdr_gone); for (node = res_gone; node != NULL; node = node->next) { SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; /* Create remove resource event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->type = OH_ET_RESOURCE_DEL; e->u.res_del_event.resource_id = res->ResourceId; handle->eventq = g_slist_append(handle->eventq, e); } else dbg("Could not allocate more memory to create event."); /* Remove resource from plugin's rpt cache */ if (res) oh_remove_resource(handle->rptcache, res->ResourceId); else dbg("No valid resource at hand. Could not remove resource."); } g_slist_free(res_gone); for (node = res_new; node != NULL; node = node->next) { GSList *tmpnode = NULL; SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; if (!res) { dbg("No valid resource at hand. Could not process new resource."); continue; } gpointer data = oh_get_resource_data(tmpcache, res->ResourceId); oh_add_resource(handle->rptcache, res, g_memdup(data, sizeof(struct snmp_rpt)),0); /* Add new/changed resources to the event queue */ for (tmpnode = tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RESOURCE && e->u.res_event.entry.ResourceId == res->ResourceId) { handle->eventq = g_slist_append(handle->eventq, e); tmpqueue = g_slist_remove_link(tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } g_slist_free(res_new); for (node = rdr_new; node != NULL; node = node->next) { guint rdr_data_size = 0; GSList *tmpnode = NULL; SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); if (!res || !rdr) { dbg("No valid resource or rdr at hand. Could not process new rdr."); continue; } gpointer data = oh_get_rdr_data(tmpcache, res->ResourceId, rdr->RecordId); /* Need to figure out the size of the data associated with the rdr */ if (rdr->RdrType == SAHPI_SENSOR_RDR) rdr_data_size = sizeof(struct RSA_SensorMibInfo); else if (rdr->RdrType == SAHPI_CTRL_RDR) rdr_data_size = sizeof(struct RSA_ControlMibInfo); else if (rdr->RdrType == SAHPI_INVENTORY_RDR) rdr_data_size = sizeof(struct RSA_InventoryMibInfo); oh_add_rdr(handle->rptcache, res->ResourceId, rdr, g_memdup(data, rdr_data_size),0); /* Add new/changed rdrs to the event queue */ for (tmpnode = tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RDR && ep_cmp(&(e->u.rdr_event.rdr.Entity),&(rdr->Entity)) == 0 && e->u.rdr_event.rdr.RecordId == rdr->RecordId) { handle->eventq = g_slist_append(handle->eventq, e); tmpqueue = g_slist_remove_link(tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } g_slist_free(rdr_new); /* Clean up tmpqueue and tmpcache */ g_slist_free(tmpqueue); oh_flush_rpt(tmpcache); g_free(tmpcache); return SA_OK; }
void cIpmiResource::Destroy() { SaHpiRptEntryT *rptentry; stdlog << "removing resource: " << m_entity_path << ").\n"; while( Num() ) { cIpmiRdr *rdr = GetRdr( 0 ); RemRdr( rdr ); delete rdr; } rptentry = oh_get_resource_by_id( Domain()->GetHandler()->rptcache, m_resource_id ); if ( !rptentry ) { stdlog << "Can't find resource in plugin cache !\n"; } else { // create remove event oh_event *e = (oh_event *)g_malloc0( sizeof( oh_event ) ); // remove sensors only if resource is FRU if ( rptentry->ResourceCapabilities & SAHPI_CAPABILITY_FRU ) { e->event.EventType = SAHPI_ET_HOTSWAP; if (e->resource.ResourceCapabilities & SAHPI_CAPABILITY_MANAGED_HOTSWAP) { e->event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_NOT_PRESENT; e->event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = SAHPI_HS_STATE_NOT_PRESENT; } else { e->event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_NOT_PRESENT; e->event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = SAHPI_HS_STATE_ACTIVE; } } else { e->event.EventType = SAHPI_ET_RESOURCE; e->event.EventDataUnion.ResourceEvent.ResourceEventType = SAHPI_RESE_RESOURCE_FAILURE; rptentry->ResourceFailed = SAHPI_TRUE; } e->event.Source = rptentry->ResourceId; oh_gettimeofday(&e->event.Timestamp); e->event.Severity = rptentry->ResourceSeverity; e->resource = *rptentry; stdlog << "cIpmiResource::Destroy OH_ET_RESOURCE_DEL Event resource " << m_resource_id << "\n"; Domain()->AddHpiEvent( e ); // remove resource from local cache int rv = oh_remove_resource( Domain()->GetHandler()->rptcache, m_resource_id ); if ( rv != 0 ) { stdlog << "Can't remove resource from plugin cache !\n"; } } m_mc->RemResource( this ); delete this; }
/** * snmp_bc_discover_resources: * @hnd: Handler data pointer. * * Discover all the resources, sensors, controls, etc. for this instance * of the plugin. Found entities are compared with what the HPI * Infra-structure thinks is there and any new, deleted, or changed * entities are updated. * * Return values: * Builds/updates internal RPT cache - normal operation. * SA_ERR_HPI_OUT_OF_SPACE - Cannot allocate space for internal memory **/ SaErrorT snmp_bc_discover_resources(void *hnd) { char *root_tuple; SaErrorT err, err1; SaHpiEntityPathT ep_root; SaHpiEntityPathT valEntity; GSList *res_new, *rdr_new, *res_gone, *rdr_gone; GSList *node; guint rdr_data_size; GSList *tmpnode; SaHpiRdrT *rdr; SaHpiRptEntryT *res; struct oh_event *e; gpointer data; struct oh_handler_state *handle; struct snmp_bc_hnd *custom_handle; if (!hnd) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } err = SA_OK; err1 = SA_OK; handle = (struct oh_handler_state *)hnd; custom_handle = (struct snmp_bc_hnd *)handle->data; if (!custom_handle) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } snmp_bc_lock_handler(custom_handle); /* Find root Entity Path */ root_tuple = (char *)g_hash_table_lookup(handle->config, "entity_root"); if (root_tuple == NULL) { dbg("Cannot find configuration parameter."); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_INTERNAL_ERROR); } err = oh_encode_entitypath(root_tuple, &ep_root); if (err) { dbg("Cannot convert entity path to string. Error=%s.", oh_lookup_error(err)); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_INTERNAL_ERROR); } /* Allocate space for temporary RPT cache */ custom_handle->tmpcache = (RPTable *)g_malloc0(sizeof(RPTable)); if (custom_handle->tmpcache == NULL) { dbg("Out of memory."); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_OUT_OF_SPACE); } /* Initialize tmpqueue */ custom_handle->tmpqueue = NULL; /* Individual platform discovery */ if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) { err = snmp_bc_discover_rsa(handle, &ep_root); } else { err = snmp_bc_discover(handle, &ep_root); } if (err) { if (err == SA_ERR_HPI_DUPLICATE) { /* Special case: * snmp_bc_discover() has found there is * no changes in any of the BladeCenter * resource masks, so there is nothing to do. * Setting returncode to SA_OK then return. */ err = SA_OK; } else { dbg("Discovery failed. Error=%s.", oh_lookup_error(err)); } goto CLEANUP; } /********************************************************************** * Rediscovery: * Get difference between current rptcache and custom_handle->tmpcache. * Delete obsolete items from rptcache and add new items in. **********************************************************************/ res_new = NULL; rdr_new = NULL; res_gone = NULL; rdr_gone = NULL; node = NULL; rpt_diff(handle->rptcache, custom_handle->tmpcache, &res_new, &rdr_new, &res_gone, &rdr_gone); trace("%d resources have gone away.", g_slist_length(res_gone)); trace("%d resources are new or have changed", g_slist_length(res_new)); for (node = rdr_gone; node != NULL; node = node->next) { rdr = (SaHpiRdrT *)node->data; snmp_bc_validate_ep(&(rdr->Entity), &valEntity); res = oh_get_resource_by_ep(handle->rptcache, &(valEntity)); /* Create remove RDR event and add to event queue */ e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->did = oh_get_default_domain_id(); e->type = OH_ET_RDR_DEL; e->u.rdr_event.parent = res->ResourceId; memcpy(&(e->u.rdr_event.rdr), rdr, sizeof(SaHpiRdrT)); handle->eventq = g_slist_append(handle->eventq, e); } else { dbg("Out of memory."); } /* Remove RDR from plugin's RPT cache */ if (rdr && res) oh_remove_rdr(handle->rptcache, res->ResourceId, rdr->RecordId); else { dbg("No valid resource or rdr at hand. Could not remove rdr."); } } g_slist_free(rdr_gone); for (node = res_gone; node != NULL; node = node->next) { res = (SaHpiRptEntryT *)node->data; /* Create remove resource event and add to event queue */ e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->did = oh_get_default_domain_id(); e->type = OH_ET_RESOURCE_DEL; e->u.res_event.entry.ResourceId = res->ResourceId; handle->eventq = g_slist_append(handle->eventq, e); } else { dbg("Out of memory."); } /* Remove resource from plugin's RPT cache */ if (res) oh_remove_resource(handle->rptcache, res->ResourceId); else dbg("No valid resource at hand. Could not remove resource."); } g_slist_free(res_gone); for (node = res_new; node != NULL; node = node->next) { tmpnode = NULL; res = (SaHpiRptEntryT *)node->data; if (!res) { dbg("No valid resource at hand. Could not process new resource."); continue; } data = oh_get_resource_data(custom_handle->tmpcache, res->ResourceId); if (data) { oh_add_resource(handle->rptcache, res, g_memdup(data, sizeof(struct snmp_rpt)),0); /* Add new/changed resources to the event queue */ for (tmpnode = custom_handle->tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RESOURCE && e->u.res_event.entry.ResourceId == res->ResourceId) { handle->eventq = g_slist_append(handle->eventq, e); custom_handle->tmpqueue = g_slist_remove_link(custom_handle->tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } else { dbg(" NULL data pointer for ResourceID %d \n", res->ResourceId); } } g_slist_free(res_new); for (node = rdr_new; node != NULL; node = node->next) { rdr_data_size = 0; tmpnode = NULL; rdr = (SaHpiRdrT *)node->data; snmp_bc_validate_ep(&(rdr->Entity), &valEntity); res = oh_get_resource_by_ep(handle->rptcache, &(valEntity)); if (!res || !rdr) { dbg("No valid resource or rdr at hand. Could not process new rdr."); continue; } data = oh_get_rdr_data(custom_handle->tmpcache, res->ResourceId, rdr->RecordId); /* Need to figure out the size of the data associated with the rdr */ if (rdr->RdrType == SAHPI_SENSOR_RDR) rdr_data_size = sizeof(struct SensorInfo); else if (rdr->RdrType == SAHPI_CTRL_RDR) rdr_data_size = sizeof(struct ControlInfo); else if (rdr->RdrType == SAHPI_INVENTORY_RDR) rdr_data_size = sizeof(struct InventoryInfo); oh_add_rdr(handle->rptcache, res->ResourceId, rdr, g_memdup(data, rdr_data_size),0); /* Add new/changed rdrs to the event queue */ for (tmpnode = custom_handle->tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RDR && oh_cmp_ep(&(e->u.rdr_event.rdr.Entity),&(rdr->Entity)) && e->u.rdr_event.rdr.RecordId == rdr->RecordId) { handle->eventq = g_slist_append(handle->eventq, e); custom_handle->tmpqueue = g_slist_remove_link(custom_handle->tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } g_slist_free(rdr_new); /* Build cache copy of SEL. RID == 1 (2nd parm) is a dummy id */ /** * This design depends on the BladeCenter management of the Event Log. * That is, * (a) The BC Event Log will always have at least one entry. It *never* has zero entry. * (b) If a Clear Event Log command is received, the BC clears the log, then creates * "Event Log has just been cleared by xxx" entry * So, if the cache copy of the Event Log is empty, this is the first invocation of OpenHPI/snmp_bc. * Otherwise, only processes newer entries for (re) discovery. **/ if (g_list_length(handle->elcache->elentries) == 0) err1 = snmp_bc_build_selcache(handle, 1); else err1 = snmp_bc_check_selcache(handle, 1, SAHPI_NEWEST_ENTRY); if (err1) { /* --------------------------------------------------------------- */ /* If an error is encounterred during building of snmp_bc elcache, */ /* only log the error. Do not do any recovery because log entries */ /* are still kept in bc mm. We'll pick them up during synch. */ /* --------------------------------------------------------------- */ trace("snmp_bc_discover, Error %s when building elcache.\n", oh_lookup_error(err1)); } if (custom_handle->isFirstDiscovery == SAHPI_TRUE) custom_handle->isFirstDiscovery = SAHPI_FALSE; CLEANUP: g_slist_free(custom_handle->tmpqueue); oh_flush_rpt(custom_handle->tmpcache); g_free(custom_handle->tmpcache); snmp_bc_unlock_handler(custom_handle); return(err); }
static SaErrorT RemoteClientDiscoverResources( void *hnd ) { struct oh_handler_state *handler = (struct oh_handler_state *)hnd; cRemoteClientConfig *config = (cRemoteClientConfig *)handler->data; SaErrorT rv = RemoteClientResourcesDiscover( &config->m_config, config->m_session_id ); if ( rv ) return rv; config->ClearMarks(); // read resources SaHpiEntryIdT next = SAHPI_FIRST_ENTRY; do { SaHpiEntryIdT current = next; SaHpiRptEntryT entry; rv = RemoteClientRptEntryGet( &config->m_config, config->m_session_id, current, &next, &entry ); if ( rv != SA_OK ) { if ( current != SAHPI_FIRST_ENTRY ) { dbg( "saHpiRptEntryGet: %d", rv ); return rv; } dbg( "empty RPT" ); break; } cRrdMap *rm = config->FindRemoteId( entry.ResourceId ); if ( rm ) rm->m_mark = true; else { // add new resource SaHpiResourceIdT rid = entry.ResourceId; config->AppendEntityRoot( entry.ResourceEntity ); SaHpiResourceIdT id = oh_uid_from_entity_path( &entry.ResourceEntity ); entry.ResourceId = id; // create mapping config->AddMapping( id, rid ); struct oh_event *e = (struct oh_event *)g_malloc0( sizeof( struct oh_event ) ); if ( !e ) { dbg( "out of space !" ); return SA_ERR_HPI_OUT_OF_SPACE; } memset( e, 0, sizeof( struct oh_event ) ); e->type = oh_event::OH_ET_RESOURCE; e->u.res_event.entry = entry; // add the entity to the resource cache int r = oh_add_resource( handler->rptcache, &(e->u.res_event.entry), 0, 0 ); assert( r == 0 ); handler->eventq = g_slist_append( handler->eventq, e ); // add rdrs SaHpiEntryIdT next_rdr = SAHPI_FIRST_ENTRY; do { SaHpiEntryIdT current_rdr = next_rdr; SaHpiRdrT rdr; rv = RemoteClientRdrGet( &config->m_config, config->m_session_id, rid, current_rdr, &next_rdr, &rdr ); if ( rv != SA_OK ) return rv; // create rdrs config->AppendEntityRoot( rdr.Entity ); // create event e = (oh_event *)g_malloc0( sizeof( oh_event ) ); if ( !e ) { dbg( "out of space" ); return SA_ERR_HPI_OUT_OF_SPACE; } memset( e, 0, sizeof( struct oh_event ) ); e->type = oh_event::OH_ET_RDR; // create rdr e->u.rdr_event.rdr = rdr; r = oh_add_rdr( handler->rptcache, entry.ResourceId, &e->u.rdr_event.rdr, 0, 0 ); assert( r == 0 ); handler->eventq = g_slist_append( handler->eventq, e ); } while( next_rdr != SAHPI_LAST_ENTRY ); } } while( next != SAHPI_LAST_ENTRY ); // remove old resources for( GList *list = config->m_resource_map; list; ) { GList *n = g_list_next( list ); cRrdMap *rm = (cRrdMap *)list->data; if ( rm->m_mark ) { list = n; continue; } // remove resource from local cache int r = oh_remove_resource( handler->rptcache, rm->m_id ); assert( r == 0 ); config->m_resource_map = g_list_remove( config->m_resource_map, rm ); // create remove event oh_event *e = (oh_event *)g_malloc0( sizeof( oh_event ) ); if ( !e ) { dbg( "out of space" ); delete rm; return SA_ERR_HPI_OUT_OF_SPACE; } memset( e, 0, sizeof( struct oh_event ) ); e->type = oh_event::OH_ET_RESOURCE_DEL; e->u.res_event.entry.ResourceId = rm->m_id; handler->eventq = g_slist_append( handler->eventq, e ); delete rm; list = n; } return SA_OK; }
void process_diff_table(struct oh_handler_state *handle, RPTable *diff_table) { /* Rediscovery: Get difference between current rptcache and tmpcache. */ /* Delete obsolete items from rptcache and add new items in. */ GSList *res_new = NULL; GSList *rdr_new = NULL; GSList *res_gone = NULL; GSList *rdr_gone = NULL; GSList *node = NULL; rpt_diff(handle->rptcache, diff_table, &res_new, &rdr_new, &res_gone, &rdr_gone); for (node = rdr_gone; node != NULL; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); /* Create remove rdr event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); e->type = OH_ET_RDR_DEL; e->u.rdr_del_event.record_id = rdr->RecordId; e->u.rdr_del_event.parent_entity = rdr->Entity; handle->eventq = g_slist_append(handle->eventq, e); /* free rdr remote data */ gpointer data = oh_get_rdr_data(diff_table, res->ResourceId, rdr->RecordId); remote_rdr_data_free(rdr, data); /* Remove rdr from plugin's rpt cache */ oh_remove_rdr(handle->rptcache, res->ResourceId, rdr->RecordId); } g_slist_free(rdr_gone); for (node = res_gone; node != NULL; node = node->next) { SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; /* Create remove resource event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); e->type = OH_ET_RESOURCE_DEL; e->u.res_del_event.resource_id = res->ResourceId; handle->eventq = g_slist_append(handle->eventq, e); /* free the remote resource data */ gpointer data = oh_get_resource_data(diff_table, res->ResourceId); remote_res_data_free(res, data); /* Remove resource from plugin's rpt cache */ oh_remove_resource(handle->rptcache, res->ResourceId); } g_slist_free(res_gone); for (node = res_new; node != NULL; node = node->next) { SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; gpointer data = oh_get_resource_data(diff_table, res->ResourceId); oh_add_resource(handle->rptcache, res, data, 1); /* Add new/changed resources to the event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); e->type = OH_ET_RESOURCE; e->u.res_event.entry.ResourceId = res->ResourceId; memcpy(&e->u.res_event.entry, res, sizeof(*res)); handle->eventq = g_slist_append(handle->eventq, e); } g_slist_free(res_new); for (node = rdr_new; node != NULL; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); gpointer data = oh_get_rdr_data(diff_table, res->ResourceId, rdr->RecordId); oh_add_rdr(handle->rptcache, res->ResourceId, rdr, data, 1); /* Add new/changed rdrs to the event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); e->type = OH_ET_RDR; e->u.rdr_event.rdr.RecordId = rdr->RecordId; memcpy(&e->u.rdr_event.rdr, rdr, sizeof(*rdr)); handle->eventq = g_slist_append(handle->eventq, e); } g_slist_free(rdr_new); /* Clean up tmpqueue and tmpcache */ }
/** * process_interconnect_insertion_event * @oh_handler: Pointer to openhpi handler structure * @con: Pointer to the SOAP_CON structure * @oa_event: Pointer to OA event structure * * Purpose: * Creates the interconnect insertion hpi hotswap event * * Detailed Description: NA * * Return values: * SA_OK - success. * SA_ERR_HPI_INVALID_PARAMS - on wrong parameters. * SA_ERR_HPI_INTERNAL_ERROR - on failure **/ SaErrorT process_interconnect_insertion_event(struct oh_handler_state *oh_handler, SOAP_CON *con, struct eventInfo *oa_event) { SaErrorT rv = SA_OK; struct oa_soap_handler *oa_handler = NULL; struct getInterconnectTrayInfo info; struct interconnectTrayInfo response; struct oh_event event; SaHpiInt32T bay_number; SaHpiResourceIdT resource_id; GSList *asserted_sensors = NULL; SaHpiRptEntryT *rpt; if (oh_handler == NULL || oa_event == NULL || con == NULL) { err("Invalid parameters"); return SA_ERR_HPI_INVALID_PARAMS; } oa_handler = (struct oa_soap_handler *) oh_handler->data; bay_number = oa_event->eventData.interconnectTrayStatus.bayNumber; update_hotswap_event(oh_handler, &event); info.bayNumber = bay_number; rv = soap_getInterconnectTrayInfo(con, &info, &response); if (rv != SOAP_OK) { err("Get interconnect tray info failed"); return SA_ERR_HPI_INTERNAL_ERROR; } /* Build the inserted interconnect RPT entry */ rv = build_interconnect_rpt(oh_handler, con, response.name, bay_number, &resource_id, TRUE); if (rv != SA_OK) { err("Failed to build the interconnect RPT"); return rv; } /* Update resource_status structure with resource_id, * serial_number, and presence status */ oa_soap_update_resource_status( &oa_handler->oa_soap_resources.interconnect, bay_number, response.serialNumber, resource_id, RES_PRESENT); /* Build the inserted interconnect RDRs */ rv = build_interconnect_rdr(oh_handler, con, bay_number, resource_id); if (rv != SA_OK) { err("Failed to build the interconnect RDR"); rv = oh_remove_resource(oh_handler->rptcache, event.resource.ResourceId); /* reset resource_status structure to default values */ oa_soap_update_resource_status( &oa_handler->oa_soap_resources.interconnect, bay_number, "", SAHPI_UNSPECIFIED_RESOURCE_ID, RES_ABSENT); return rv; } rv = oa_soap_populate_event(oh_handler, resource_id, &event, &asserted_sensors); if (rv != SA_OK) { err("Creating hotswap event failed"); return rv; } event.event.EventType = SAHPI_ET_HOTSWAP; event.event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = SAHPI_HS_STATE_NOT_PRESENT; event.event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_INSERTION_PENDING; /* NOT_PRESENT to INSERTION_PENDING state change happened due * to operator action */ event.event.EventDataUnion.HotSwapEvent.CauseOfStateChange = SAHPI_HS_CAUSE_OPERATOR_INIT; oh_evt_queue_push(oh_handler->eventq, copy_oa_soap_event(&event)); /* Raise the assert sensor events */ if (asserted_sensors) { rpt = oh_get_resource_by_id(oh_handler->rptcache, resource_id); oa_soap_assert_sen_evt(oh_handler, rpt, asserted_sensors); } return SA_OK; }
/** * snmp_bc_discover_resources: * @hnd: Handler data pointer. * * Discover all the resources, sensors, controls, etc. for this instance * of the plugin. Found entities are compared with what the HPI * Infra-structure thinks is there and any new, deleted, or changed * entities are updated. * * Return values: * Builds/updates internal RPT cache - normal operation. * SA_ERR_HPI_OUT_OF_SPACE - Cannot allocate space for internal memory **/ SaErrorT snmp_bc_discover_resources(void *hnd) { char *root_tuple; SaErrorT err = SA_OK, err1 = SA_OK; SaHpiEntityPathT ep_root; if (!hnd) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } struct oh_handler_state *handle = (struct oh_handler_state *)hnd; struct snmp_bc_hnd *custom_handle = (struct snmp_bc_hnd *)handle->data; if (!custom_handle) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } snmp_bc_lock_handler(custom_handle); /* Find root Entity Path */ root_tuple = (char *)g_hash_table_lookup(handle->config, "entity_root"); if (root_tuple == NULL) { dbg("Cannot find configuration parameter."); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_INTERNAL_ERROR); } err = oh_encode_entitypath(root_tuple, &ep_root); if (err) { dbg("Cannot convert entity path to string. Error=%s.", oh_lookup_error(err)); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_INTERNAL_ERROR); } /* Allocate space for temporary RPT cache */ custom_handle->tmpcache = (RPTable *)g_malloc0(sizeof(RPTable)); if (custom_handle->tmpcache == NULL) { dbg("Out of memory."); snmp_bc_unlock_handler(custom_handle); return(SA_ERR_HPI_OUT_OF_SPACE); } /* Initialize tmpqueue */ custom_handle->tmpqueue = NULL; /* Individual platform discovery */ if (custom_handle->platform == SNMP_BC_PLATFORM_RSA) { err = snmp_bc_discover_rsa(handle, &ep_root); } else { err = snmp_bc_discover(handle, &ep_root); } if (err) { dbg("Discovery failed. Error=%s.", oh_lookup_error(err)); goto CLEANUP; } /********************************************************************** * Rediscovery: * Get difference between current rptcache and custom_handle->tmpcache. * Delete obsolete items from rptcache and add new items in. **********************************************************************/ GSList *res_new = NULL, *rdr_new = NULL, *res_gone = NULL, *rdr_gone = NULL; GSList *node = NULL; rpt_diff(handle->rptcache, custom_handle->tmpcache, &res_new, &rdr_new, &res_gone, &rdr_gone); trace("%d resources have gone away.", g_slist_length(res_gone)); trace("%d resources are new or have changed", g_slist_length(res_new)); for (node = rdr_gone; node != NULL; node = node->next) { SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); /* Create remove RDR event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->did = oh_get_default_domain_id(); e->type = OH_ET_RDR_DEL; e->u.rdr_event.parent = res->ResourceId; memcpy(&(e->u.rdr_event.rdr), rdr, sizeof(SaHpiRdrT)); handle->eventq = g_slist_append(handle->eventq, e); } else { dbg("Out of memory."); } /* Remove RDR from plugin's RPT cache */ if (rdr && res) oh_remove_rdr(handle->rptcache, res->ResourceId, rdr->RecordId); else { dbg("No valid resource or rdr at hand. Could not remove rdr."); } } g_slist_free(rdr_gone); for (node = res_gone; node != NULL; node = node->next) { SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; /* Create remove resource event and add to event queue */ struct oh_event *e = (struct oh_event *)g_malloc0(sizeof(struct oh_event)); if (e) { e->did = oh_get_default_domain_id(); e->type = OH_ET_RESOURCE_DEL; e->u.res_event.entry.ResourceId = res->ResourceId; handle->eventq = g_slist_append(handle->eventq, e); } else { dbg("Out of memory."); } /* Remove resource from plugin's RPT cache */ if (res) oh_remove_resource(handle->rptcache, res->ResourceId); else dbg("No valid resource at hand. Could not remove resource."); } g_slist_free(res_gone); for (node = res_new; node != NULL; node = node->next) { GSList *tmpnode = NULL; SaHpiRptEntryT *res = (SaHpiRptEntryT *)node->data; if (!res) { dbg("No valid resource at hand. Could not process new resource."); continue; } gpointer data = oh_get_resource_data(custom_handle->tmpcache, res->ResourceId); oh_add_resource(handle->rptcache, res, g_memdup(data, sizeof(struct snmp_rpt)),0); /* Add new/changed resources to the event queue */ for (tmpnode = custom_handle->tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RESOURCE && e->u.res_event.entry.ResourceId == res->ResourceId) { handle->eventq = g_slist_append(handle->eventq, e); custom_handle->tmpqueue = g_slist_remove_link(custom_handle->tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } g_slist_free(res_new); for (node = rdr_new; node != NULL; node = node->next) { guint rdr_data_size = 0; GSList *tmpnode = NULL; SaHpiRdrT *rdr = (SaHpiRdrT *)node->data; SaHpiRptEntryT *res = oh_get_resource_by_ep(handle->rptcache, &(rdr->Entity)); if (!res || !rdr) { dbg("No valid resource or rdr at hand. Could not process new rdr."); continue; } gpointer data = oh_get_rdr_data(custom_handle->tmpcache, res->ResourceId, rdr->RecordId); /* Need to figure out the size of the data associated with the rdr */ if (rdr->RdrType == SAHPI_SENSOR_RDR) rdr_data_size = sizeof(struct SensorInfo); else if (rdr->RdrType == SAHPI_CTRL_RDR) rdr_data_size = sizeof(struct ControlInfo); else if (rdr->RdrType == SAHPI_INVENTORY_RDR) rdr_data_size = sizeof(struct InventoryInfo); oh_add_rdr(handle->rptcache, res->ResourceId, rdr, g_memdup(data, rdr_data_size),0); /* Add new/changed rdrs to the event queue */ for (tmpnode = custom_handle->tmpqueue; tmpnode != NULL; tmpnode = tmpnode->next) { struct oh_event *e = (struct oh_event *)tmpnode->data; if (e->type == OH_ET_RDR && oh_cmp_ep(&(e->u.rdr_event.rdr.Entity),&(rdr->Entity)) && e->u.rdr_event.rdr.RecordId == rdr->RecordId) { handle->eventq = g_slist_append(handle->eventq, e); custom_handle->tmpqueue = g_slist_remove_link(custom_handle->tmpqueue, tmpnode); g_slist_free_1(tmpnode); break; } } } g_slist_free(rdr_new); /* Build cache copy of SEL. RID == 1 (2nd parm) is a dummy id */ if (g_list_length(handle->elcache->elentries) != 0) { trace("Discovery called and elcache is not empty. Re-discovery?\n"); err1 = oh_el_clear(handle->elcache); } err1 = snmp_bc_build_selcache(handle, 1); /*err1 = snmp_bc_check_selcache(handle, 1, SAHPI_NEWEST_ENTRY); */ if (err1) { /* --------------------------------------------------------------- */ /* If an error is encounterred during building of snmp_bc elcache, */ /* only log the error. Do not do any recovery because log entries */ /* are still kept in bc mm. We'll pick them up during synch. */ /* --------------------------------------------------------------- */ dbg("snmp_bc_discover, Error %s when building elcache.\n", oh_lookup_error(err1)); } CLEANUP: g_slist_free(custom_handle->tmpqueue); oh_flush_rpt(custom_handle->tmpcache); g_free(custom_handle->tmpcache); snmp_bc_unlock_handler(custom_handle); return(err); }
/** * process_server_insertion_event * @oh_handler: Pointer to openhpi handler structure * @con: Pointer to SOAP_CON structure * @oa_event: Pointer to the OA event structure * * Purpose: * Creates the server insertion hpi hotswap event * * Detailed Description: * - The inserted server blade will not have all the * information with the insertion event. * Build the bare minimum inventory RDR * - Raise the NOT_PRESENT to INSERTION_PENDING hotswap event * * Return values: * SA_OK - success. * SA_ERR_HPI_INVALID_PARAMS - on wrong parameters. * SA_ERR_HPI_INTERNAL_ERROR - on failure **/ SaErrorT process_server_insertion_event(struct oh_handler_state *oh_handler, SOAP_CON *con, struct eventInfo *oa_event) { SaErrorT rv = SA_OK; struct getBladeInfo info; struct bladeInfo response; struct oa_soap_handler *oa_handler = NULL; SaHpiInt32T bay_number; struct oh_event event; SaHpiRptEntryT rpt; GSList *asserted_sensors = NULL; char blade_name[MAX_NAME_LEN]; if (oh_handler == NULL || con == NULL || oa_event == NULL) { err("Invalid parameters"); return SA_ERR_HPI_INVALID_PARAMS; } oa_handler = (struct oa_soap_handler *) oh_handler->data; update_hotswap_event(oh_handler, &event); bay_number = oa_event->eventData.bladeStatus.bayNumber; info.bayNumber = bay_number; rv = soap_getBladeInfo(con, &info, &response); if (rv != SOAP_OK) { err("Get blade info failed"); return SA_ERR_HPI_INTERNAL_ERROR; } /* Copy the blade name from response for future processing */ convert_lower_to_upper(response.name, strlen(response.name), blade_name, MAX_NAME_LEN); /* Build the server RPT entry */ rv = build_inserted_server_rpt(oh_handler, &response, &rpt); if (rv != SA_OK) { err("build inserted server rpt failed"); return rv; } /* Update resource_status structure with resource_id, serial_number, * and presence status */ oa_soap_update_resource_status( &oa_handler->oa_soap_resources.server, bay_number, response.serialNumber, rpt.ResourceId, RES_PRESENT); /* Build the server RDR */ rv = build_server_rdr(oh_handler, con, bay_number, rpt.ResourceId, blade_name); if (rv != SA_OK) { err("build inserted server RDR failed"); /* Free the inventory info from inventory RDR */ rv = free_inventory_info(oh_handler, rpt.ResourceId); if (rv != SA_OK) { err("Inventory cleanup failed for resource id %d", rpt.ResourceId); } oh_remove_resource(oh_handler->rptcache, rpt.ResourceId); /* reset resource_status structure to default values */ oa_soap_update_resource_status( &oa_handler->oa_soap_resources.server, bay_number, "", SAHPI_UNSPECIFIED_RESOURCE_ID, RES_ABSENT); return rv; } rv = oa_soap_populate_event(oh_handler, rpt.ResourceId, &event, &asserted_sensors); if (rv != SA_OK) { err("Populating event struct failed"); return SA_ERR_HPI_INTERNAL_ERROR; } event.event.EventType = SAHPI_ET_HOTSWAP; event.event.EventDataUnion.HotSwapEvent.PreviousHotSwapState = SAHPI_HS_STATE_NOT_PRESENT; /* For blades that do not support managed hotswap, current hotswap state * is ACTIVE */ if (!(rpt.ResourceCapabilities & SAHPI_CAPABILITY_MANAGED_HOTSWAP)) { event.event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_ACTIVE; } else { event.event.EventDataUnion.HotSwapEvent.HotSwapState = SAHPI_HS_STATE_INSERTION_PENDING; } /* NOT_PRESENT to INSERTION_PENDING/ACTIVE state change happened due * to operator action of blade insertion */ event.event.EventDataUnion.HotSwapEvent.CauseOfStateChange = SAHPI_HS_CAUSE_OPERATOR_INIT; /* Raise the hotswap event for the inserted server blade */ oh_evt_queue_push(oh_handler->eventq, copy_oa_soap_event(&event)); /* Raise the assert sensor events */ if (asserted_sensors) oa_soap_assert_sen_evt(oh_handler, &rpt, asserted_sensors); return SA_OK; }