/** * main: Adds 100 resources to RPTable. Fetches the hundredth resource * and times how long it took to fetch it. Fails if it can't get the resource. * * Return value: 0 on success, 1 on failure **/ int main(int argc, char **argv) { RPTable *rptable = (RPTable *)g_malloc0(sizeof(RPTable)); oh_init_rpt(rptable); guint i = 0; struct timeval start, end; SaHpiRptEntryT *tmpentry = NULL; for (i = 1; i <= 10000; i++) { rptentries[0].ResourceId = i; rptentries[0].ResourceEntity.Entry[0].EntityLocation = i; oh_add_resource(rptable, rptentries, NULL, 0); } gettimeofday(&start, NULL); /*printf("Started at %ld.%ld\n",start.tv_sec,start.tv_usec);*/ if (!(tmpentry = oh_get_resource_by_ep(rptable, &(rptentries[0].ResourceEntity)))) return 1; gettimeofday(&end, NULL); /*printf("Ended at %ld.%ld\n",end.tv_sec,end.tv_usec);*/ printf("%ld.%ld seconds elapsed.\n",(long)(end.tv_sec - start.tv_sec),(long)(end.tv_usec - start.tv_usec)); return 0; }
/** * main: Starting with an empty RPTable, adds 1 resource to it. * Fetches the resource back by entity path using a NULL table. * Passes the test if the interface returns NULL, else it fails. * * Return value: 0 on success, 1 on failure **/ int main(int argc, char **argv) { RPTable *rptable = (RPTable *)g_malloc0(sizeof(RPTable)); oh_init_rpt(rptable); if (oh_add_resource(rptable, rptentries, NULL, 1)) return 1; if (oh_get_resource_by_ep(NULL, &(rptentries[0].ResourceEntity))) return 1; return 0; }
/** * main: Starts with an RPTable of 10 resources and fetches * them randomly by the Entity Path and compares them against the original * resource. A failed comparison means the test failed, * otherwise the test passed. * * Return value: 0 on success, 1 on failure **/ int main(int argc, char **argv) { RPTable *rptable = (RPTable *)g_malloc0(sizeof(RPTable)); oh_init_rpt(rptable); guint i = 0, k = 0; GSList *resources = NULL; for (i = 0; rptentries[i].ResourceId != 0; i++) { if (oh_add_resource(rptable, rptentries + i, NULL, 0)) return 1; else resources = g_slist_append(resources, rptentries + i); } for (; resources; i--) { SaHpiRptEntryT *randentry = NULL, *tmpentry = NULL; GSList *tmpnode = NULL; k = (guint) (((gfloat)i)*rand()/(RAND_MAX+1.0)); tmpnode = g_slist_nth(resources, k); randentry = (SaHpiRptEntryT *)tmpnode->data; tmpentry = oh_get_resource_by_ep(rptable, &(randentry->ResourceEntity)); if (!tmpentry || memcmp(randentry, tmpentry, sizeof(SaHpiRptEntryT))) return 1; else { resources = g_slist_remove_link(resources, tmpnode); g_slist_free_1(tmpnode); } } 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; }
static void get_entity_event(ipmi_entity_t *entity, struct ohoi_resource_info *ohoi_res_info, SaHpiRptEntryT *entry, void *cb_data) { SaHpiEntityPathT entity_ep; struct oh_handler_state *handler = cb_data; struct ohoi_handler *ipmi_handler = handler->data; // int rv; const char *str; int entity_id = ipmi_entity_get_entity_id(entity); int entity_instance = ipmi_entity_get_entity_instance(entity); SaHpiEntityPathT ep; unsigned char slot_n_str[8]; int no_slot = 1; unsigned int slot_val = 0; init_rpt(entry); entry->ResourceEntity.Entry[0].EntityType = entity_id; if(entity_instance >= 96) { entry->ResourceEntity.Entry[0].EntityLocation = entity_instance- 96; } else { entry->ResourceEntity.Entry[0].EntityLocation = entity_instance; } entry->ResourceEntity.Entry[1].EntityType = SAHPI_ENT_ROOT; entry->ResourceEntity.Entry[1].EntityLocation = 0; update_resource_capabilities(entity, entry, ohoi_res_info); if (entry->ResourceEntity.Entry[0].EntityType == SAHPI_ENT_SYSTEM_BOARD) { /* This is the BMC entry, so we need to add watchdog. */ if (!ipmi_handler->islan) { // no watchdog commands over lan entry->ResourceCapabilities |= SAHPI_CAPABILITY_WATCHDOG; } } if (ipmi_handler->d_type != IPMI_DOMAIN_TYPE_ATCA) { goto no_atca; } if (entry->ResourceEntity.Entry[0].EntityType == SAHPI_ENT_SYSTEM_CHASSIS) { entry->ResourceEntity.Entry[0].EntityType = SAHPI_ENT_ROOT; entry->ResourceEntity.Entry[0].EntityLocation = 0; oh_append_textbuffer(&entry->ResourceTag, "Shelf"); } /* Since OpenIPMI does not hand us a more descriptive tag which is an SDR issue in the chassis really, we'll over-ride it here until things change */ /* * If entity has a slot try to get it's number */ no_slot = ipmi_entity_get_physical_slot_num(entity, &slot_val); trace_ipmi_entity(" SLOT presence for Entity", no_slot ? 0 : 1, entity); if (no_slot) { /* will use device address */ goto end_of_slot; } { // create Resource for phisical blade slot if it hasn't already been created SaHpiEntityPathT rootep; SaHpiRptEntryT *rpt; struct ohoi_resource_info *s_r_info; char *name; switch (entity_id) { case 0xa0: // Blade ep.Entry[0].EntityType = SAHPI_ENT_PHYSICAL_SLOT; name = "Blade Slot "; break; case 0xf0: // Shelf Manager ep.Entry[0].EntityType = ATCAHPI_ENT_SHELF_MANAGER_SLOT; name = "Shelf Manager Slot "; break; case 0xf1: // Filtration Unit ep.Entry[0].EntityType = ATCAHPI_ENT_FAN_FILTER_TRAY_SLOT; name = "Fan Filter Tray Slot "; break; case 0x0a: // PEM ep.Entry[0].EntityType = ATCAHPI_ENT_POWER_ENTRY_MODULE_SLOT; name = "PEM Slot "; break; case 0xf2: // Shelf FRU ep.Entry[0].EntityType = ATCAHPI_ENT_SHELF_FRU_DEVICE_SLOT; name = "Shelf FRU Device Slot "; break; case 0x1e: // Fan Tray ep.Entry[0].EntityType = ATCAHPI_ENT_FAN_TRAY_SLOT; name = "Fan Tray Slot "; break; case 0xc0: // RTM ep.Entry[0].EntityType = ATCAHPI_ENT_RTM_SLOT; name = "RTM Slot "; break; default: no_slot = 1; goto end_of_slot; } ep.Entry[0].EntityLocation = slot_val; ep.Entry[1].EntityType = SAHPI_ENT_ROOT; ep.Entry[1].EntityLocation = 0; oh_encode_entitypath(ipmi_handler->entity_root, &rootep); oh_concat_ep(&ep, &rootep); rpt = oh_get_resource_by_ep(handler->rptcache, &ep); if (rpt == NULL) { // create rpt for slot SaHpiRptEntryT srpt; int i; init_rpt(&srpt); for (i = 0; i < SAHPI_MAX_ENTITY_PATH; i ++) { srpt.ResourceEntity.Entry[i].EntityLocation = ep.Entry[i].EntityLocation; srpt.ResourceEntity.Entry[i].EntityType = ep.Entry[i].EntityType; if (ep.Entry[i].EntityType == SAHPI_ENT_ROOT) { break; } } oh_append_textbuffer(&srpt.ResourceTag, name); snprintf((char *)slot_n_str, 8, "%d", slot_val); oh_append_textbuffer(&srpt.ResourceTag, (char *)slot_n_str); srpt.ResourceId = oh_uid_from_entity_path(&srpt.ResourceEntity); s_r_info = malloc(sizeof(*ohoi_res_info)); if (s_r_info == NULL) { dbg("Out of Memory"); goto end_of_slot; } memset(s_r_info, 0, sizeof(*ohoi_res_info)); s_r_info->type = OHOI_RESOURCE_SLOT; s_r_info->u.slot.devid = ipmi_entity_get_fru_device_id(entity); s_r_info->u.slot.addr = ipmi_entity_get_device_address(entity); s_r_info->u.slot.entity_id = ipmi_entity_convert_to_id(entity); if (oh_add_resource(handler->rptcache, &srpt, s_r_info, 1)) { dbg("couldn't add resource for slot %d", ep.Entry[0].EntityLocation); trace_ipmi_entity("COULD NOT CREATE SLOT for ", 0, entity); no_slot = 1; g_free(s_r_info); goto end_of_slot; } trace_ipmi_entity("CREATE SLOT for ", 0, entity); if (ipmi_entity_get_entity_id(entity) == 0xf0) { // this is not virtual shelf manager ipmi_handler->shmc_num++; } entity_rpt_set_presence(s_r_info, ipmi_handler, 1); rpt = oh_get_resource_by_ep(handler->rptcache, &ep); atca_create_slot_rdrs(handler, srpt.ResourceId); } else { s_r_info = oh_get_resource_data(handler->rptcache, rpt->ResourceId); if (s_r_info && (s_r_info->type & OHOI_RESOURCE_SLOT)) { s_r_info->u.slot.devid = ipmi_entity_get_fru_device_id(entity); s_r_info->u.slot.addr = ipmi_entity_get_device_address(entity); s_r_info->u.slot.entity_id = ipmi_entity_convert_to_id(entity); } else { dbg("Internal error. s_r_info == %p", s_r_info); } } } end_of_slot: if ((entity_id == 0xa0) && (entity_instance >= 96)) { // ATCA Board if ((ipmi_entity_get_device_address(entity) == 130) || (ipmi_entity_get_device_address(entity) == 132)) { oh_append_textbuffer(&entry->ResourceTag, "Switch "); entry->ResourceEntity.Entry[0].EntityType = SAHPI_ENT_SWITCH_BLADE; } else if (entity_instance == 102) { /* this is here for Force-made Storage blades * until we have access to latest hardware * DO NOT CHANGE */ oh_append_textbuffer(&entry->ResourceTag, "Storage/Disk Blade "); entry->ResourceEntity.Entry[0].EntityType = SAHPI_ENT_DISK_BLADE; } else { oh_append_textbuffer(&entry->ResourceTag, "Blade "); entry->ResourceEntity.Entry[0].EntityType = SAHPI_ENT_SBC_BLADE; } } if ((entity_id == 0x0a) && (entity_instance >= 96)) { // Power Unit oh_append_textbuffer(&entry->ResourceTag, "PEM "); } if ((entity_id == 0xf0) && (entity_instance >= 96)) { // Shelf Manager if ((ipmi_entity_get_device_channel(entity) != 0) || (ipmi_entity_get_device_address(entity) != 32)) { oh_append_textbuffer(&entry->ResourceTag, "Shelf Manager "); } else { oh_append_textbuffer(&entry->ResourceTag, "Virtual Shelf Manager"); no_slot = 1; // XXXX Temporary. Until SDRs fixed ohoi_res_info->type |= OHOI_RESOURCE_MC; ohoi_res_info->u.entity.mc_id = ipmi_handler->virt_mcid; // entry->ResourceCapabilities |= SAHPI_CAPABILITY_EVENT_LOG; } entry->ResourceEntity.Entry[0].EntityType = SAHPI_ENT_SHELF_MANAGER; } if ((entity_id == 0xf2) && (entity_instance >= 96)) { // Shelf FRU oh_append_textbuffer(&entry->ResourceTag, "Shelf FRU Device "); entry->ResourceEntity.Entry[0].EntityType = ATCAHPI_ENT_SHELF_FRU_DEVICE; } if ((entity_id == 0xf1) && (entity_instance >= 96)) { // Filtration Unit oh_append_textbuffer(&entry->ResourceTag, "Fan Filter Tray "); entry->ResourceEntity.Entry[0].EntityType = ATCAHPI_ENT_FILTRATION_UNIT; } if ((entity_id == 0x1e) && (entity_instance >= 96)) { // Fan Tray oh_append_textbuffer(&entry->ResourceTag, "Fan Tray "); } if ((entity_id == 0xc0) && (entity_instance >= 96)) { // Fan Tray oh_append_textbuffer(&entry->ResourceTag, "RTM "); } /* End AdvancedTCA Fix-ups */ if (!no_slot) { oh_append_textbuffer(&entry->ResourceTag, (char *)slot_n_str); } no_atca: if (entry->ResourceTag.DataLength == 0) { str = ipmi_entity_get_entity_id_string(entity); oh_append_textbuffer(&entry->ResourceTag, str); } if (!no_slot) { oh_concat_ep(&entry->ResourceEntity, &ep); } else if (ipmi_entity_get_is_child(entity)) { struct add_parent_ep_s info; info.handler = handler; info.entry = entry; ipmi_entity_iterate_parents(entity, add_parent_ep, &info); } else { oh_encode_entitypath(ipmi_handler->entity_root, &entity_ep); oh_concat_ep(&entry->ResourceEntity, &entity_ep); } entry->ResourceId = oh_uid_from_entity_path(&entry->ResourceEntity); }
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 */ }
/** * 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); }
/** * 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); }