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); }
/** * oh_remove_resource * @table: Pointer to the RPT from which an RPT entry will be removed. * @rid: Resource id of the RPT entry to be removed. * * Remove a resource from the RPT. If the @rid is * %SAHPI_FIRST_ENTRY, the first RPT entry in the table will be removed. * The void data will be freed if @owndata was false (%FREE_RPT_DATA) when adding * the resource, otherwise if @owndata was true (%KEEP_RPT_DATA) it will not be freed. * * Returns: SA_OK on success Or minus SA_OK on error. **/ SaErrorT oh_remove_resource(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { dbg("Failed to remove RPT entry. No Resource found by that id"); return SA_ERR_HPI_NOT_PRESENT; } else { SaHpiRdrT *tmp_rdr; /* Remove all RDRs for the resource first */ while ((tmp_rdr = oh_get_rdr_by_id(table, rid, SAHPI_FIRST_ENTRY)) != NULL) { oh_remove_rdr(table, rid, SAHPI_FIRST_ENTRY); } /* then remove the resource itself. */ table->rptlist = g_slist_remove(table->rptlist, (gpointer)rptentry); if (!rptentry->owndata) g_free(rptentry->data); g_hash_table_remove(table->rptable, &(rptentry->rpt_entry.EntryId)); g_free((gpointer)rptentry); if (!table->rptlist) { g_hash_table_destroy(table->rptable); table->rptable = NULL; } } update_rptable(table); return SA_OK; }
/** * oh_remove_resource * @table: Pointer to the RPT from which an RPT entry will be removed. * @rid: Resource id of the RPT entry to be removed. * * Remove a resource from the RPT. If the @rid is * %SAHPI_FIRST_ENTRY, the first RPT entry in the table will be removed. * The void data will be freed if @owndata was false (%FREE_RPT_DATA) when adding * the resource, otherwise if @owndata was true (%KEEP_RPT_DATA) it will not be freed. * * Returns: * 0 - Successful removal from the RPT. * -1 - table pointer is NULL. * -2 - Failure. No resource found by that id. **/ int oh_remove_resource(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; if (!table) { dbg("ERROR: Cannot work on a null table pointer."); return -1; } rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { dbg("Failed to remove RPT entry. No Resource found by that id"); return -2; } else { SaHpiRdrT *tmp_rdr; /* Remove all RDRs for the resource first */ while ((tmp_rdr = oh_get_rdr_by_id(table, rid, SAHPI_FIRST_ENTRY)) != NULL) { oh_remove_rdr(table, rid, SAHPI_FIRST_ENTRY); } /* then remove the resource itself. */ table->rptable = g_slist_remove(table->rptable, (gpointer)rptentry); if (!rptentry->owndata) g_free(rptentry->data); g_free((gpointer)rptentry); } update_rptable(table); return 0; }
static int process_rdr_event(struct oh_handler *h, RPTable *rpt, struct oh_event *e) { int rv; SaHpiResourceIdT rid; if (e->type == OH_ET_RDR_DEL) { rid = oh_uid_lookup(&(e->u.rdr_del_event.parent_entity)); rv = (rid)? oh_remove_rdr(rpt,rid,e->u.rdr_del_event.record_id) : -1; } else { rid = oh_uid_lookup(&(e->u.rdr_event.rdr.Entity)); rv = (rid)? oh_add_rdr(rpt,rid,&(e->u.rdr_event.rdr),NULL) : -1; } if (rv) dbg("Could not process rdr event. Parent resource not found."); return rv; }
/** * main: Starting with an empty RPTable, adds 1 resource to it * and then adds 1 rdr to it. Removes rdr using a special value like * SAHPI_FIRST_ENTRY. * Passes the test if the interface returns ok, 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_add_rdr(rptable, rptentries[0].ResourceId, rdrs, NULL, 1)) return 1; if (oh_remove_rdr(rptable, rptentries[0].ResourceId, SAHPI_FIRST_ENTRY)) return 1; return 0; }
/** * main: Starting with an empty RPTable, adds 1 resource to it * and then adds 1 rdr to it. Removes rdr using a Resource Id not present * in the table. * Passes the test if the interface returns an error, 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); guint i; for (i = 0; rptentries[i].ResourceId != 0; i++) { if (oh_add_resource(rptable, rptentries+i, NULL, 0)) return 1; } if (oh_add_rdr(rptable, rptentries[0].ResourceId, sensors, NULL, 1)) return 1; if (!oh_remove_rdr(rptable, 1234567, sensors[0].RecordId)) return 1; return 0; }
static int process_rdr_event(struct oh_event *e) { int rv = -1; SaHpiResourceIdT rid = e->u.rdr_event.parent; RPTable *rpt = NULL; struct oh_domain *d = NULL; d = oh_get_domain(e->did); /* get the RPT for this domain */ if(!d) { dbg("Domain %d doesn't exist", e->did); return -1; } rpt = &(d->rpt); if (e->type == OH_ET_RDR_DEL) { /* Remove RDR */ if (!(rv = oh_remove_rdr(rpt, rid, e->u.rdr_event.rdr.RecordId)) ) { dbg("SUCCESS: RDR %x in Resource %d in Domain %d has been REMOVED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } else { dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been REMOVED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } } else if (e->type == OH_ET_RDR) { /* Add/Update RDR */ if(!(rv = oh_add_rdr(rpt, rid, &(e->u.rdr_event.rdr), NULL, 0))) { dbg("SUCCES: RDR %x in Resource %d in Domain %d has been ADDED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } else { dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been ADDED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } } oh_release_domain(d); return rv; }
/** * oh_remove_resource: Remove a resource from the RPT. If the rid is * RPT_ENTRY_BEGIN (0xffffffff), the first RPT entry in the table will be removed. * @table: Pointer to the RPT from which an RPT entry will be removed. * @rid: Resource id of the RPT entry to be removed. * * Return value: * 0 - Successful removal from the RPT. * -2 - Failure. No resource found by that id. **/ int oh_remove_resource(RPTable *table, SaHpiResourceIdT rid) { RPTEntry *rptentry; rptentry = get_rptentry_by_rid(table, rid); if (!rptentry) { dbg("Failed to remove RPT entry. No Resource found by that id"); return -2; } else { SaHpiRdrT *tmp_rdr; /* Remove all RDRs for the resource first */ while ((tmp_rdr = oh_get_rdr_by_id(table, rid, RDR_BEGIN)) != NULL) { oh_remove_rdr(table, rid, RDR_BEGIN); } /* then remove the resource itself. */ table->rptable = g_slist_remove(table->rptable, (gpointer)rptentry); g_free((gpointer)rptentry); } update_rptable(table, RPT_DECREMENT); 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; }
int entity_presence(ipmi_entity_t *entity, int present, void *cb_data, ipmi_event_t *event) { struct oh_handler_state *handler = (struct oh_handler_state *)cb_data; struct ohoi_handler *ipmi_handler = handler->data; SaHpiRptEntryT *rpt; SaHpiResourceIdT rid; ipmi_entity_id_t ent_id; struct ohoi_resource_info *res_info; ent_id = ipmi_entity_convert_to_id(entity); g_static_rec_mutex_lock(&ipmi_handler->ohoih_lock); rpt = ohoi_get_resource_by_entityid(handler->rptcache, &ent_id); if (!rpt) { trace_ipmi_entity("SET PRESENCE. NO RPT", present, entity); dbg("No rpt"); g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock); return SA_ERR_HPI_NOT_PRESENT; } rid = rpt->ResourceId; if (!(rpt->ResourceCapabilities & SAHPI_CAPABILITY_FRU) && !present) { // This is a workaround trace_ipmi_entity("PRESENCE HANDLER CALLED FOR NOT FRU ENTITY", present, entity); g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock); return SA_ERR_HPI_NOT_PRESENT; } res_info = oh_get_resource_data(handler->rptcache, rid); if (res_info->presence == present) { g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock); return SA_OK; } trace_ipmi_entity(present ? "PRESENT" : "NOT PRESENT", present, entity); if (present && res_info->deleted) { // became not present and present again. res_info->deleted = 0; rpt->ResourceFailed = SAHPI_FALSE; } if (IS_ATCA(ipmi_handler->d_type)) { switch (ipmi_entity_get_entity_id(entity)) { case 0xa0: // Blade atca_slot_state_sensor_event_send(handler, rpt, present); break; case 0xf0: // Shelf Manager if ((ipmi_entity_get_device_channel(entity) == 0) && (ipmi_entity_get_device_address(entity) == 32)) { // Virtual ShM. Do nothing. It cannot be. break; } if (present) { ipmi_handler->shmc_present_num++; } else { if (rpt->ResourceFailed) { // it's already marked break; } ipmi_handler->shmc_present_num--; } if (ipmi_handler->fully_up) { ohoi_send_vshmgr_redundancy_sensor_event( handler, present); } break; case 0x1e: // Fan Tray if (present) { ohoi_create_fan_control(handler, rpt->ResourceId); } break; default: break; } } entity_rpt_set_presence(res_info, handler->data, present); if (!present) { res_info->deleted = 1; // send event to infrastructure but don't // touch our local structures while 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"); } #if 0 while (SA_OK == oh_remove_rdr(handler->rptcache, rid, SAHPI_FIRST_ENTRY)); ohoi_delete_rpt_fru(res_info); res_info->type = OHOI_RESOURCE_ENTITY; // XXX free inventory area memory #endif } g_static_rec_mutex_unlock(&ipmi_handler->ohoih_lock); 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 */ }
/** * 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); }
static int process_rdr_event(struct oh_event *e) { int rv; SaHpiResourceIdT rid = e->u.rdr_event.parent; RPTable *rpt = NULL; struct oh_domain *d = NULL; struct oh_event hpie; d = oh_get_domain(e->did); /* get the RPT for this domain */ if(!d) { dbg("Domain %d doesn't exist", e->did); return -1; } rpt = &(d->rpt); if (e->type == OH_ET_RDR_DEL) { /* DELETE event */ if (!(rv = oh_remove_rdr(rpt, rid, e->u.rdr_event.rdr.RecordId)) ) { dbg("SUCCESS: RDR %x in Resource %d in Domain %d has been REMOVED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } else { dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been REMOVED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } /* build event for event queue */ } else { /* ADD event */ if(!(rv = oh_add_rdr(rpt, rid, &(e->u.rdr_event.rdr), NULL, 0))) { dbg("SUCCES: RDR %x in Resource %d in Domain %d has been ADDED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } else { dbg("FAILED: RDR %x in Resource %d in Domain %d has NOT been ADDED.", e->u.rdr_event.rdr.RecordId, rid, e->did); } /* build event for event queue */ hpie.did = e->did; //hpie.u.hpi_event.event.Severity = e->u.rdr_event.rdr.RdrType; hpie.u.hpi_event.event.Source = e->u.rdr_event.parent; hpie.u.hpi_event.event.EventType = e->u.rdr_event.rdr.RdrType; hpie.u.hpi_event.rdr = e->u.rdr_event.rdr; // hpie.u.hpi_event.event.EventDataUnion.ResourceEvent.ResourceEventType = // SAHPI_RESE_RESOURCE_ADDED; /* switch (e->u.rdr_event.rdr.RdrType) { case SAHPI_NO_RECORD: dbg("SAHPI_NO_RECORD: process_rdr_event"); break; case SAHPI_CTRL_RDR:. break; case SAHPI_SENSOR_RDR; break; case SAHPI_INVENTORY_RDR; hpie.u.hpi_event break; case SAHPI_WATCHDOG_RDR; break; case SAHPI_ANNUNCIATOR_RDR; break; default: dbg("ERROR: process_rdr_event, unknown SaHpiRdrTypeT Type"); break; } */ } oh_release_domain(d); if (rv == SA_OK) { rv = process_hpi_event(&hpie); dbg("process_rdr_event, done process_hpi_event"); } return rv; /* need this after different type rdr events are processed above FIXME:DJ otherwise rdr events are never palced on eventq if(rv == SA_OK) { rv = process_hpi_event(&hpie); } */ }
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; }