/* * Retrieve a filesystem entry based on the hardware device, * (or exported path for remote mounts). * (Optionally) insert a new one into the container. */ netsnmp_fsys_info *netsnmp_fsys_by_device (char *device, int create_type) { netsnmp_fsys_info *sp; DEBUGMSGTL (("fsys:device", "Get filesystem entry (%s)\n", device)); /* * Look through the list for a matching entry */ /* .. or use a secondary index container ?? */ for (sp = CONTAINER_FIRST (_fsys_container); sp; sp = CONTAINER_NEXT (_fsys_container, sp)) { if (!strcmp (device, sp->device)) return sp; } /* * Not found... */ if (create_type == NETSNMP_FS_FIND_EXIST) { DEBUGMSGTL (("fsys:device", "No such filesystem entry\n")); return NULL; } /* * ... so let's create a new one */ sp = _fsys_create_entry (); if (sp) strlcpy (sp->device, device, sizeof (sp->device)); return sp; }
/** * * @sessionid * * @return */ SaErrorT clear_domain_info_entry(SaHpiDomainIdT domain_id) { SaErrorT rv = SA_OK; netsnmp_index *row_idx; saHpiDomainInfoTable_context *ctx; DEBUGMSGTL ((AGENT, "clear_domain_info_entry, called\n")); DEBUGMSGTL ((AGENT, " domainId [%d]\n", domain_id)); row_idx = CONTAINER_FIRST(cb.container); if (row_idx) //At least one entry was found. { do { ctx = CONTAINER_FIND(cb.container, row_idx); row_idx = CONTAINER_NEXT(cb.container, row_idx); if (ctx->index.oids[saHpiDomainId_INDEX] == domain_id) { /* all conditions met remove row */ CONTAINER_REMOVE (cb.container, ctx); saHpiDomainInfoTable_delete_row (ctx); domain_info_entry_count = CONTAINER_SIZE (cb.container); DEBUGMSGTL ((AGENT, "clear_domain_info_entry:" " found row: removing\n")); } } while (row_idx); } return rv; }
NETSNMP_INLINE netsnmp_index * find_next_row(netsnmp_table_request_info *tblreq_info, table_container_data * tad) { netsnmp_index *row = NULL; netsnmp_index index; if (!tblreq_info || !tad) return NULL; netsnmp_assert(NULL != tad->table); /* * below our minimum column? */ if (tblreq_info->colnum < tad->tblreg_info->min_column) { tblreq_info->colnum = tad->tblreg_info->min_column; row = CONTAINER_FIRST(tad->table); } else { index.oids = tblreq_info->index_oid; index.len = tblreq_info->index_oid_len; row = CONTAINER_NEXT(tad->table, &index); /* * we don't have a row, but we might be at the end of a * column, so try the next one. */ if (!row) { ++tblreq_info->colnum; if (tad->tblreg_info->valid_columns) { tblreq_info->colnum = netsnmp_closest_column (tblreq_info->colnum, tad->tblreg_info->valid_columns); } else if (tblreq_info->colnum > tad->tblreg_info->max_column) tblreq_info->colnum = 0; if (tblreq_info->colnum != 0) row = CONTAINER_FIRST(tad->table); } } return row; }
/* * Architecture-independent release of filesystem statistics */ static void _fsys_free (void) { netsnmp_fsys_info *sp; for (sp = CONTAINER_FIRST (_fsys_container); sp; sp = CONTAINER_NEXT (_fsys_container, sp)) { sp->flags &= ~NETSNMP_FS_FLAG_ACTIVE; } }
/* * Architecture-independent release of sensor statistics */ static void _sensor_free( void ) { netsnmp_sensor_info *sp; for (sp = CONTAINER_FIRST( _sensor_container ); sp; sp = CONTAINER_NEXT( _sensor_container, sp )) { sp->flags &= ~ NETSNMP_SENSOR_FLAG_ACTIVE; } }
/* * Retrieve a sensor entry by name, * or (optionally) insert a new one into the container */ netsnmp_sensor_info * sensor_by_name( char *name, int create_type ) { netsnmp_sensor_info *sp; DEBUGMSGTL(("sensors:name", "Get sensor entry (%s)\n", name)); /* * Look through the list for a matching entry */ /* .. or use a secondary index container ?? */ for (sp = CONTAINER_FIRST( _sensor_container ); sp; sp = CONTAINER_NEXT( _sensor_container, sp )) { if ( !strcmp( name, sp->name )) return sp; } /* * Not found... */ if ( create_type == NETSNMP_SENSOR_FIND_EXIST ) { DEBUGMSGTL(("sensors:name", "No such sensor entry\n")); return NULL; } /* * ... so let's create a new one, using the type supplied */ sp = SNMP_MALLOC_TYPEDEF( netsnmp_sensor_info ); if ( sp ) { strcpy( sp->name, name ); sp->type = create_type; /* * Set up the index value. * * All this trouble, just for a simple integer. * Surely there must be a better way? */ sp->idx.len = 1; sp->idx.oids = SNMP_MALLOC_TYPEDEF( oid ); sp->idx.oids[0] = ++_sensor_idx; } DEBUGMSGTL(("sensors:name", "Create sensor entry (type = %d, index = %d\n", create_type, _sensor_idx)); CONTAINER_INSERT( _sensor_container, sp ); return sp; }
/* * Remove all entries from sctpAssocRemAddrTable, which are not marked as valid. * All valid entries are then marked as invalid (to delete them in next cache * load, if the entry is not updated). */ void sctpAssocRemAddrTable_delete_invalid(netsnmp_container *remAddrTable) { netsnmp_container *to_delete = netsnmp_container_find("lifo"); CONTAINER_FOR_EACH(remAddrTable, sctpAssocRemAddrTable_collect_invalid, to_delete); while (CONTAINER_SIZE(to_delete)) { sctpAssocRemAddrTable_entry *entry = CONTAINER_FIRST(to_delete); CONTAINER_REMOVE(remAddrTable, entry); sctpAssocRemAddrTable_entry_free(entry); CONTAINER_REMOVE(to_delete, NULL); } CONTAINER_FREE(to_delete); }
/** * * @domainId * @resourceId * * @return */ SaErrorT clear_sensor_normal_max(SaHpiDomainIdT domainId, SaHpiResourceIdT resourceId) { SaErrorT rv = SA_OK; netsnmp_index *row_idx; saHpiSensorReadingNormalMaxTable_context *sen_norm_max_ctx; DEBUGMSGTL ((AGENT, "clear_sensor_normal_max, called\n")); DEBUGMSGTL ((AGENT, " domainId [%d]\n", domainId)); DEBUGMSGTL ((AGENT, " resourceId [%d]\n", resourceId)); row_idx = CONTAINER_FIRST(cb.container); if (row_idx) //At least one entry was found. { do { /* based on the found row_idx get the pointer */ /* to its context (row data) */ sen_norm_max_ctx = CONTAINER_FIND(cb.container, row_idx); /* before we delete the context we should get the */ /* next row (context) if any before we delete this */ /* one. */ row_idx = CONTAINER_NEXT(cb.container, row_idx); if ((sen_norm_max_ctx->index.oids[saHpiSenNormMaxDomainId_INDEX] == domainId) && (sen_norm_max_ctx->index.oids[saHpiSenNormMaxResourceId_INDEX] == resourceId)) { /* all conditions met remove row */ CONTAINER_REMOVE (cb.container, sen_norm_max_ctx); saHpiSensorReadingNormalMaxTable_delete_row (sen_norm_max_ctx); DEBUGMSGTL ((AGENT, "clear_sensor_normal_max: " "found row: removing\n")); } } while (row_idx); } return rv; }
/** returns the first row in the table */ netsnmp_tdata_row *netsnmp_tdata_row_first (netsnmp_tdata * table) { return (netsnmp_tdata_row *) CONTAINER_FIRST (table->container); }
/** * load initial data * * TODO:350:M: Implement ipAddressTable data load * This function will also be called by the cache helper to load * the container again (after the container free function has been * called to free the previous contents). * * @param container container to which items should be inserted * * @retval MFD_SUCCESS : success. * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source * @retval MFD_ERROR : other error. * * This function is called to load the index(es) (and data, optionally) * for the every row in the data set. * * @remark * While loading the data, the only important thing is the indexes. * If access to your data is cheap/fast (e.g. you have a pointer to a * structure in memory), it would make sense to update the data here. * If, however, the accessing the data invovles more work (e.g. parsing * some other existing data, or peforming calculations to derive the data), * then you can limit yourself to setting the indexes and saving any * information you will need later. Then use the saved information in * ipAddressTable_row_prep() for populating data. * * @note * If you need consistency between rows (like you want statistics * for each row to be from the same time frame), you should set all * data here. * */ int ipAddressTable_container_load(netsnmp_container *container) { netsnmp_container *ipaddress_container; void *tmp_ptr[2]; DEBUGMSGTL(("verbose:ipAddressTable:ipAddressTable_cache_load", "called\n")); /* * TODO:351:M: |-> Load/update data in the ipAddressTable container. * loop over your ipAddressTable data, allocate a rowreq context, * set the index(es) [and data, optionally] and insert into * the container. */ ipaddress_container = netsnmp_access_ipaddress_container_load(NULL, NETSNMP_ACCESS_IPADDRESS_LOAD_ADDL_IDX_BY_ADDR); /* * we just got a fresh copy of interface data. compare it to * what we've already got, and make any adjustments, saving * missing addresses to be deleted. */ tmp_ptr[0] = ipaddress_container->next; tmp_ptr[1] = NULL; CONTAINER_FOR_EACH(container, (netsnmp_container_obj_func *) _check_entry_for_updates, tmp_ptr); /* * now add any new interfaces */ CONTAINER_FOR_EACH(ipaddress_container, (netsnmp_container_obj_func *) _add_new_entry, container); /* * free the container. we've either claimed each entry, or released it, * so the access function doesn't need to clear the container. */ netsnmp_access_ipaddress_container_free(ipaddress_container, NETSNMP_ACCESS_IPADDRESS_FREE_DONT_CLEAR); /* * remove deleted addresses from table container */ if (NULL != tmp_ptr[1]) { netsnmp_container *tmp_container = (netsnmp_container *) tmp_ptr[1]; ipAddressTable_rowreq_ctx *tmp_ctx; /* * this works because the tmp_container is a linked list, * which can be used like a stack... */ while (CONTAINER_SIZE(tmp_container)) { /* * get from delete list */ tmp_ctx = (ipAddressTable_rowreq_ctx*)CONTAINER_FIRST(tmp_container); /* * release context, delete from table container */ CONTAINER_REMOVE(container, tmp_ctx); ipAddressTable_release_rowreq_ctx(tmp_ctx); /* * pop off delete list */ CONTAINER_REMOVE(tmp_container, NULL); } } DEBUGMSGT(("verbose:ipAddressTable:ipAddressTable_cache_load", "%lu records\n", (unsigned long)CONTAINER_SIZE(container))); return MFD_SUCCESS; }
/** * * @domainId * @resourceId * * @return */ SaErrorT clear_ctrl_digital(SaHpiDomainIdT domainId, SaHpiResourceIdT resourceId) { SaErrorT rv = SA_OK; netsnmp_index *row_idx; saHpiCtrlDigitalTable_context *ctrl_ctx; DEBUGMSGTL ((AGENT, "clear_ctrl_digital, called\n")); DEBUGMSGTL ((AGENT, " domainId [%d]\n", domainId)); DEBUGMSGTL ((AGENT, " resourceId [%d]\n", resourceId)); DR_XREF *dr_entry; SaHpiDomainIdResourceIdArrayT dr_pair; /* reset any existing indexEntry value */ dr_pair.domainId_resourceId_arry[0] = domainId; dr_pair.domainId_resourceId_arry[1] = resourceId; dr_entry = domain_resoruce_pair_lookup(&dr_pair, &dr_table); if (dr_entry == NULL) { DEBUGMSGTL ((AGENT, "INFO: clear_ctrl_digital() domain_resource_pair_get returned NULL\n")); return SA_ERR_HPI_NOT_PRESENT; } else { dr_entry->entry_id = 0; } row_idx = CONTAINER_FIRST(cb.container); if (row_idx) //At least one entry was found. { do { /* based on the found row_idx get the pointer */ /* to its context (row data) */ ctrl_ctx = CONTAINER_FIND(cb.container, row_idx); /* before we delete the context we should get the */ /* next row (context) if any before we delete this */ /* one. */ row_idx = CONTAINER_NEXT(cb.container, row_idx); if ((ctrl_ctx->index.oids[saHpiCtrlDigitalDomainId_INDEX] == domainId) && (ctrl_ctx->index.oids[saHpiCtrlDigitalResourceEntryId_INDEX] == resourceId)) { /* all conditions met remove row */ CONTAINER_REMOVE (cb.container, ctrl_ctx); saHpiCtrlDigitalTable_delete_row (ctrl_ctx); ctrl_digital_entry_count = CONTAINER_SIZE (cb.container); DEBUGMSGTL ((AGENT, "clear_ctrl_digital: " "found row: removing\n")); } } while (row_idx); } return rv; }
netsnmp_fsys_info *netsnmp_fsys_get_first( void ) { return CONTAINER_FIRST( _fsys_container ); }
unsigned long purge_rdr () { SaHpiDomainIdT domain_id; SaHpiResourceIdT resource_id; SaHpiEntryIdT num; SaHpiRdrTypeT type; unsigned long child_id; saHpiRdrTable_context *rdr_context; // SaHpiSessionIdT session_id; // SaHpiRdrT rdr_entry; int rc; unsigned long count = 0; unsigned int deleted; // Q: How do we determine which RDR entry is "fresh" ? // A: 'dirty-bit' is set (in populate_rdr) // to AGENT_FALSE for existing ('cleaned') records. The // dirty ones are removed. DEBUGMSGTL ((AGENT, "purge_rdr. Entry.\n")); if (rdr_mutex == AGENT_TRUE) { rdr_context = CONTAINER_FIRST (cb.container); while (rdr_context != NULL) { deleted = AGENT_FALSE; DEBUGMSGTL ((AGENT, "Found %d.%d.%d (%X) (child: %d) purge: %s\n", rdr_context->domain_id, rdr_context->saHpiResourceID, rdr_context->saHpiRdrRecordId, rdr_context->saHpiRdrRecordId, rdr_context->saHpiRdrId, (rdr_context->dirty_bit == AGENT_TRUE) ? "Yes" : "No")); if (rdr_context != NULL) { if (rdr_context->dirty_bit == AGENT_FALSE) { // Its ok. rdr_context->dirty_bit = AGENT_TRUE; } else { // Dirty bit hasn't been cleaned. Purge the record. // Copy the values (we are going to remove 'rdr_context' and // we need the domain_id, resource_id, etc values for // deleteing sub-RDR records. domain_id = rdr_context->domain_id; resource_id = rdr_context->saHpiResourceID; num = rdr_context->saHpiRdrRecordId; type = rdr_context->saHpiRdrType; child_id = rdr_context->saHpiRdrId; // We are getting the next item here b/c effectivly the rpt_context // will be set to NULL in the 'delete_rpt_row' rdr_context = CONTAINER_NEXT (cb.container, rdr_context); deleted = AGENT_TRUE; count++; // Delete the RDR row rc = delete_rdr_row (domain_id, resource_id, num, type); if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "delete_rdr_row failed. Return code: %d.\n", rc)); // Delete the other sub-type. Keep in mind that this will delete // _only_ the specific subtypes. Therfore other records // with the same resource_id, domain_id, and num can still // exist. /* Subtract -1 to be compliant with the +1 addition */ switch (type-1) { case SAHPI_NO_RECORD: break; case SAHPI_CTRL_RDR: rc = delete_ctrl_row (domain_id, resource_id, child_id); break; case SAHPI_SENSOR_RDR: rc = delete_sensor_row (domain_id, resource_id, child_id); break; case SAHPI_INVENTORY_RDR: rc = delete_inventory_rows (domain_id, resource_id, child_id); break; case SAHPI_WATCHDOG_RDR: rc = delete_watchdog_row (domain_id, resource_id, child_id); break; default: break; } if (rc != AGENT_ERR_NOERROR) DEBUGMSGTL ((AGENT, "Couldn't delete sub-RDR entry (rc: %d)\n", rc)); } } // Only get the next item if no deletion has happend. if (deleted == AGENT_FALSE) rdr_context = CONTAINER_NEXT (cb.container, rdr_context); } rdr_mutex = AGENT_FALSE; } DEBUGMSGTL ((AGENT, "purge_rdr: Exit (deleted: %d).\n", count)); return count; }
/** * * @session_id * @resource_id * @saHpiEventLogRowPointer * @aHpiEventLogRowPointer_len * * @return */ SaErrorT domain_event_log_clear(SaHpiSessionIdT session_id, SaHpiResourceIdT resource_id, oid *saHpiEventLogRowPointer, size_t saHpiEventLogRowPointer_len, int modifyTotal) { oid domain_evt_oid[DOMAIN_EVENT_LOG_INDEX_NR]; netsnmp_index domain_evt_idx; netsnmp_index *domain_index; saHpiDomainEventLogTable_context *domain_evt_ctx; DR_XREF *dr_entry; SaHpiDomainIdResourceIdArrayT dr_pair; int column_len = 2; DEBUGMSGTL ((AGENT, "domain_event_log_clear, called\n")); DEBUGMSGTL ((AGENT, "Attempting to delete domain el row with the following indexes:\n")); DEBUGMSGTL ((AGENT," Domain [%ld]\n", saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len])); DEBUGMSGTL ((AGENT," Entry id [%ld]\n", saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len + 1])); DEBUGMSGTL ((AGENT," Severity [%s]\n", oh_lookup_severity( saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len + 2]-1))); /* BUILD oid for new row */ /* assign the number of indices */ domain_evt_idx.len = DOMAIN_EVENT_LOG_INDEX_NR; /** Index saHpiDomainId is external */ domain_evt_oid[0] = saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len]; /** Index saHpiDomainEventEntryId is external */ domain_evt_oid[1] = saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len + 1]; /** Index saHpiEventSeverity is external */ domain_evt_oid[2] = saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len + 2]; /* assign the indices to the index */ domain_evt_idx.oids = (oid *) & domain_evt_oid; domain_index = CONTAINER_FIRST(cb.container); domain_evt_ctx = CONTAINER_FIND(cb.container, &domain_evt_idx); if (!domain_evt_ctx) { DEBUGMSGTL ((AGENT, "domain_event_log_clear did not find a row to delete\n")); } else { DEBUGMSGTL ((AGENT, "domain_event_log_clear found row to delete\n")); CONTAINER_REMOVE(cb.container, domain_evt_ctx); saHpiDomainEventLogTable_delete_row(domain_evt_ctx); /* Reset the entry id for this domain/resource pair */ dr_pair.domainId_resourceId_arry[0] = saHpiEventLogRowPointer[saHpiDomainEventLogTable_oid_len + column_len]; dr_pair.domainId_resourceId_arry[1] = resource_id; dr_entry = domain_resoruce_pair_lookup(&dr_pair, &dr_table); if (dr_entry == NULL) { DEBUGMSGTL ((AGENT, "ERROR: domain_event_log_clear() domain_resoruce_pair_lookup returned NULL\n")); return AGENT_ERR_INTERNAL_ERROR; } DEBUGMSGTL ((AGENT, "domain_event_log_clear() resetting entry_id to 0\n")); dr_entry->entry_id = 0; domain_event_log_entry_count = CONTAINER_SIZE (cb.container); if (modifyTotal == MIB_TRUE) { domain_event_log_entry_count_total--; } } return SA_OK; }