static void DisconnectingEntry(UNUSED tState self) { snmp_sess_close(sessp); sessp = NULL; change_state(&Exit); }
static void ConnectingEntry(UNUSED tState self) { netsnmp_session init; netsnmp_transport* t; void* sess; if(sessp) { snmp_sess_close(sessp); sessp = NULL; } snmp_sess_init(&init); init.version = AGENTX_VERSION_1; init.retries = 0; /* Retries are handled by the state machine */ init.timeout = SNMP_DEFAULT_TIMEOUT; init.flags |= SNMP_FLAGS_STREAM_SOCKET; init.callback = handle_agentx_response; init.authenticator = NULL; if(!(t = netsnmp_transport_open_client( "agentx", netsnmp_ds_get_string( NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_X_SOCKET)))) { snmp_log(LOG_ERR, "Failed to connect to AgentX server\n"); change_state(&Exit); } else if(!(sess = snmp_sess_add_ex( &init, t, NULL, agentx_parse, NULL, NULL, agentx_realloc_build, agentx_check_packet, NULL))) { snmp_log(LOG_ERR, "Failed to create session\n"); change_state(&Exit); } else { sessp = sess; change_state(&Opening); } }
/** SNMP Close Session. */ void SnmpClose(HSNMP m_sessp) { if(!m_sessp) return; if(!snmp_sess_close(m_sessp)) { syslog(LOG_ERR,"Close SNMP session: ERROR"); } else syslog(LOG_INFO,"SNMP session closed"); }
/** * snmp_bc_close: * @hnd: Pointer to handler structure. * * Close an SNMP BladeCenter/RSA plugin handler instance. * * Returns: * Void **/ void snmp_bc_close(void *hnd) { struct oh_handler_state *handle = (struct oh_handler_state *)hnd; oh_el_close(handle->elcache); if (is_simulator()) { sim_close(); } else { struct snmp_bc_hnd *custom_handle = (struct snmp_bc_hnd *)handle->data; snmp_sess_close(custom_handle->sessp); /* Windows32 specific net-snmp cleanup (noop on unix) */ SOCK_CLEANUP; } /* Cleanup event2hpi hash table */ event2hpi_hash_free(handle); /* Cleanup errlog2event_hash table */ errlog2event_hash_use_count--; if (errlog2event_hash_use_count == 0) { errlog2event_hash_free(); } }
/** * snmp_bc_recover_snmp_session: * @hnd: Pointer to handler structure. * * . * * Returns: * SA_OK - able to open a snmp session **/ SaErrorT snmp_bc_recover_snmp_session(struct snmp_bc_hnd *custom_handle) { SaErrorT rv; rv = SA_OK; if (custom_handle->host_alternate != NULL) { /* This openhpi.conf stanza has 2 different hosts defined */ if (!custom_handle->sessp) { snmp_sess_close(custom_handle->sessp); /* Windows32 specific net-snmp cleanup (noop on unix) */ SOCK_CLEANUP; } if ( strcmp(custom_handle->host, custom_handle->session.peername) == 0 ) { trace("Attemp recovery with custom_handle->host_alternate %s\n", custom_handle->host_alternate); custom_handle->session.peername = custom_handle->host_alternate; } else { trace("Attemp recovery with custom_handle->host %s\n", custom_handle->host); custom_handle->session.peername = custom_handle->host; } rv = snmp_bc_manage_snmp_open(custom_handle, SAHPI_FALSE); } else { trace("No host_alternate defined in openhpi.conf. No recovery on host_alternate.\n"); rv = SA_ERR_HPI_NO_RESPONSE; } return(rv); }
static void csnmp_host_close_session (host_definition_t *host) /* {{{ */ { if (host->sess_handle == NULL) return; snmp_sess_close (host->sess_handle); host->sess_handle = NULL; } /* }}} void csnmp_host_close_session */
// Creates a SNMP session void snmpDeliverTrap_netsnmp::_destroySession( void* sessionHandle) { PEG_METHOD_ENTER(TRC_IND_HANDLER, "snmpDeliverTrap_netsnmp::_destroySession"); snmp_sess_close(sessionHandle); PEG_METHOD_EXIT(); }
static int noit_snmp_session_cleanse(struct target_session *ts) { if(ts->refcnt == 0 && ts->sess_handle) { eventer_remove_fd(ts->fd); ts->fd = -1; if(ts->timeoutevent) { eventer_remove(ts->timeoutevent); ts->timeoutevent = NULL; } snmp_sess_close(ts->sess_handle); ts->sess_handle = NULL; if(!ts->in_table) { free(ts); } return 1; } return 0; }
/** * snmp_bc_close: * @hnd: Pointer to handler structure. * * Close an SNMP BladeCenter/RSA plugin handler instance. * * Returns: * Void **/ void snmp_bc_close(void *hnd) { struct oh_handler_state *handle; if (!hnd) { dbg("INVALID PARM - NULL handle pointer."); return; } handle = (struct oh_handler_state *)hnd; oh_el_close(handle->elcache); if (is_simulator()) { sim_close(); } else { struct snmp_bc_hnd *custom_handle = (struct snmp_bc_hnd *)handle->data; snmp_sess_close(custom_handle->sessp); /* Windows32 specific net-snmp cleanup (noop on unix) */ SOCK_CLEANUP; } /* Cleanup event2hpi hash table */ event2hpi_hash_free(handle); /* Cleanup errlog2event_hash table */ errlog2event_hash_use_count--; if (errlog2event_hash_use_count == 0) { errlog2event_hash_free(); } oh_flush_rpt(handle->rptcache); g_free(handle->rptcache); }
// bulkwalk executes the SNMP GETBULK operation. // Caller frees returned response. struct bulkwalk_response *bulkwalk(char *peername, char *community) { struct bulkwalk_response *response = calloc(1, sizeof(struct bulkwalk_response)); void *sessp; struct snmp_session session, *sptr; snmp_sess_init(&session); session.version = SNMP_VERSION_2c; session.community = (unsigned char *) community; session.community_len = strlen(community); session.peername = peername; if ((sessp = snmp_sess_open(&session)) == NULL) { char *errstr = open_error(&session); char *err = NULL; int failure = asprintf(&err, "Open SNMP session error: %s", errstr); if (failure == -1) { err = errstr; } else { free(errstr); } add_error(response, err); return response; } oid name[MAX_OID_LEN]; size_t name_length = PRINTER_OID_LEN; memmove(name, PRINTER_OID, name_length * sizeof(oid)); long max_repetitions = MAX_REPETITIONS; struct oid_value **next_ov = &response->ov_root; while (1) { struct snmp_pdu *subtree; char *err = request(sessp, max_repetitions, name, name_length, &subtree); if (err != NULL) { add_error(response, err); snmp_free_pdu(subtree); break; } if (subtree->errstat == SNMP_ERR_NOERROR) { add_responses(subtree->variables, &next_ov, name, &name_length); snmp_free_pdu(subtree); if (name_length == 0) { break; } continue; } if (subtree->errstat == SNMP_ERR_TOOBIG) { // We tried to request too many OIDs at once; request fewer. if (max_repetitions <= 1) { snmp_free_pdu(subtree); break; } max_repetitions /= 2; snmp_free_pdu(subtree); continue; } char *errstr = session_error(sessp); err = NULL; int failure = asprintf(&err, "SNMP response error (%ld): %s", subtree->errstat, errstr); if (failure == -1) { err = errstr; } else { free(errstr); } add_error(response, err); snmp_free_pdu(subtree); break; } snmp_sess_close(sessp); return response; }
void *sync_poller(void *thread_args) { // phoenix async poller; worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker -> crew; // target_t *entry = NULL; target_t *_current_local = NULL; PT_MUTEX_LOCK(&crew -> mutex); PT_COND_WAIT(&crew->go, &crew->mutex); PT_MUTEX_UNLOCK(&crew -> mutex); for( ; ; ) { PT_MUTEX_LOCK(&crew -> mutex); current = _current_local = getNext(); crew -> _sent_work_count--; if (_current_local == NULL && crew->_sent_work_count <= 0) { crew -> _send_worker_count--; PT_COND_BROAD(&crew -> _sending_done); PT_COND_WAIT(&crew -> go, &crew -> mutex); // } else if (_current_local == NULL) { // PT_COND_WAIT(&crew->go, &crew->mutex); // // PT_MUTEX_UNLOCK(&crew -> mutex); // continue; // // return 0; // } else if (crew->_sent_work_count <= 0) { // PT_COND_BROAD(&crew->_sending_done); // // PT_MUTEX_UNLOCK(&crew -> mutex); // continue; // // return 0; PT_MUTEX_UNLOCK(&crew -> mutex); continue; } PT_MUTEX_UNLOCK(&crew -> mutex); // PT_MUTEX_LOCK(&crew->mutex); // current = getNext(); // if (status == STAT_SUCCESS) entry->last_value = result; // if (init == NEW) entry->init = LIVE; // signal for our control thread; // but should also check for number of threads completed; // PT_MUTEX_UNLOCK(&crew->mutex); // while (current == NULL) { // PT_COND_WAIT(&crew -> go, &crew -> mutex); // _current_local = NULL; // } // // if (current != NULL) { // _current_local = current; // // printf("[ info] thread [%d] work_count index: %d\n", worker->index, crew -> _send_work_count); // } // make a copy of current and then unlock; // preparing snmp session; // we got what we need from current entry // moving to next entry for other wating threads; printf( "[ info] thread [%d] processing -> host: %s, oid: %s\n", worker -> index, _current_local -> host, _current_local -> objoid ); // making a snmp session ... // struct session *_host_ss = stuepd you are, this is a ptr! sohuld be initialized 1st :- ; struct session *_host_ss = calloc(1, sizeof(struct session)); // stuepd you are, this is a ptr! sohuld be initialized 1st :- ; // struct host *hp; /* startup all hosts */ // for (hs = sessions, hp = hosts; hp->name; hs++, hp++) { struct snmp_session _sess; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; snmp_sess_init(&_sess); /* initialize session */ _sess.version = SNMP_VERSION_2c; _sess.peername = strdup(_current_local-> host); _sess.community = strdup(_current_local -> community); _sess.community_len = strlen(_sess.community); // /* default callback */ // _sess.callback = asynch_response; // _sess.callback_magic = _host_ss; // if (!(_host_ss -> _sess = snmp_sess_open(&_sess))) { //, snmp_api_errstring(snmp_errno) printf("[error] %s!\n", snmp_api_errstring(snmp_errno)); // exit(-1); // snmp_perror(snmp_errno); continue; } // printf("[ info] thread [%d] &sess: %llu, _host_ss -> _sess: %llu\n", worker->index, // &sess, _host_ss -> _sess); // struct snmp_session *_ss_ptr = snmp_sess_session(_host_ss -> _sess); _host_ss -> _oid_name = strdup(_current_local -> objoid); // also translate this in to snmp format; _host_ss -> _oid_len = sizeof(_host_ss -> _oid) / sizeof(_host_ss -> _oid[0]); if (!read_objid(_host_ss -> _oid_name, _host_ss -> _oid, &_host_ss -> _oid_len)) { snmp_perror("read_objid"); exit(1); } pdu = snmp_pdu_create(SNMP_MSG_GET); /* send the first GET */ snmp_add_null_var(pdu, _host_ss -> _oid, _host_ss -> _oid_len); int _status = snmp_sess_synch_response(_host_ss -> _sess, pdu, &response); // int print_result (int status, struct snmp_session *sp, struct snmp_pdu *pdu) print_result(_status, &_sess, response); // analyzing the result; // and making it look like correct one (limits and correctness check); // if out of range for example we have the following stats update; // PT_MUTEX_LOCK(&stats.mutex); // stats.out_of_range++; // PT_MUTEX_UNLOCK(&stats.mutex); snmp_sess_close(_host_ss -> _sess); /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); // when we have a snmp result, updating a starts counters; PT_MUTEX_UNLOCK(&stats.mutex); // decreasing work counter; } // for (;;) }
int notifyTable_register_notifications(int major, int minor, void *serverarg, void *clientarg) { struct targetAddrTable_struct *ptr; struct targetParamTable_struct *pptr; struct snmpNotifyTable_data *nptr; int confirm, i; char buf[SNMP_MAXBUF_SMALL]; netsnmp_transport *t = NULL; struct agent_add_trap_args *args = (struct agent_add_trap_args *) serverarg; netsnmp_session *ss; if (!args || !(args->ss)) { return (0); } confirm = args->confirm; ss = args->ss; /* * XXX: START move target creation to target code */ for (i = 0; i < MAX_ENTRIES; i++) { sprintf(buf, "internal%d", i); if (get_addrForName(buf) == NULL && get_paramEntry(buf) == NULL) break; } if (i == MAX_ENTRIES) { snmp_log(LOG_ERR, "Can't register new trap destination: max limit reached: %d", MAX_ENTRIES); snmp_sess_close(ss); return (0); } /* * address */ ptr = snmpTargetAddrTable_create(); ptr->name = strdup(buf); t = snmp_sess_transport(snmp_sess_pointer(ss)); memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid)); ptr->tDomainLen = t->domain_length; ptr->tAddressLen = t->remote_length; ptr->tAddress = t->remote; ptr->timeout = ss->timeout / 1000; ptr->retryCount = ss->retries; SNMP_FREE(ptr->tagList); ptr->tagList = strdup(ptr->name); ptr->params = strdup(ptr->name); ptr->storageType = ST_READONLY; ptr->rowStatus = RS_ACTIVE; ptr->sess = ss; DEBUGMSGTL(("trapsess", "adding to trap table\n")); snmpTargetAddrTable_add(ptr); /* * param */ pptr = snmpTargetParamTable_create(); pptr->paramName = strdup(buf); pptr->mpModel = ss->version; if (ss->version == SNMP_VERSION_3) { pptr->secModel = ss->securityModel; pptr->secLevel = ss->securityLevel; pptr->secName = (char *) malloc(ss->securityNameLen + 1); memcpy((void *) pptr->secName, (void *) ss->securityName, ss->securityNameLen); pptr->secName[ss->securityNameLen] = 0; } else { pptr->secModel = ss->version == SNMP_VERSION_1 ? SNMP_SEC_MODEL_SNMPv1 : SNMP_SEC_MODEL_SNMPv2c; pptr->secLevel = SNMP_SEC_LEVEL_NOAUTH; pptr->secName = NULL; if (ss->community && (ss->community_len > 0)) { pptr->secName = (char *) malloc(ss->community_len + 1); memcpy((void *) pptr->secName, (void *) ss->community, ss->community_len); pptr->secName[ss->community_len] = 0; } } pptr->storageType = ST_READONLY; pptr->rowStatus = RS_ACTIVE; snmpTargetParamTable_add(pptr); /* * XXX: END move target creation to target code */ /* * notify table */ nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data); nptr->snmpNotifyName = strdup(buf); nptr->snmpNotifyNameLen = strlen(buf); nptr->snmpNotifyTag = strdup(buf); nptr->snmpNotifyTagLen = strlen(buf); nptr->snmpNotifyType = confirm ? SNMPNOTIFYTYPE_INFORM : SNMPNOTIFYTYPE_TRAP; nptr->snmpNotifyStorageType = ST_READONLY; nptr->snmpNotifyRowStatus = RS_ACTIVE; snmpNotifyTable_add(nptr); return 0; }
void *poller(void *thread_args) { worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker->crew; target_t *entry = NULL; void *sessp = NULL; struct snmp_session session; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars = NULL; unsigned long long result = 0; unsigned long long last_value = 0; unsigned long long insert_val = 0; int status = 0, bits = 0, init = 0; char query[BUFSIZE]; char storedoid[BUFSIZE]; char result_string[BUFSIZE]; if (set.verbose >= HIGH) printf("Thread [%d] starting.\n", worker->index); if (MYSQL_VERSION_ID > 40000) mysql_thread_init(); else my_thread_init(); while (1) { if (set.verbose >= DEVELOP) printf("Thread [%d] locking (wait on work)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); while (current == NULL) { PT_COND_WAIT(&crew->go, &crew->mutex); } if (set.verbose >= DEVELOP) printf("Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count); if (current != NULL) { if (set.verbose >= HIGH) printf("Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host, current->objoid, crew->work_count); snmp_sess_init(&session); if (set.snmp_ver == 2) session.version = SNMP_VERSION_2c; else session.version = SNMP_VERSION_1; session.peername = current->host; session.remote_port = set.snmp_port; session.community = current->community; session.community_len = strlen(session.community); sessp = snmp_sess_open(&session); anOID_len = MAX_OID_LEN; pdu = snmp_pdu_create(SNMP_MSG_GET); read_objid(current->objoid, anOID, &anOID_len); entry = current; last_value = current->last_value; init = current->init; insert_val = 0; bits = current->bits; strncpy(storedoid, current->objoid, sizeof(storedoid)); current = getNext(); } if (set.verbose >= DEVELOP) printf("Thread [%d] unlocking (done grabbing current)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); snmp_add_null_var(pdu, anOID, anOID_len); if (sessp != NULL) status = snmp_sess_synch_response(sessp, pdu, &response); else status = STAT_DESCRIP_ERROR; /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); if (status == STAT_DESCRIP_ERROR) { stats.errors++; printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername); } else if (status == STAT_TIMEOUT) { stats.no_resp++; printf("*** SNMP No response: (%s@%s).\n", session.peername, storedoid); } else if (status != STAT_SUCCESS) { stats.errors++; printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername, storedoid, status); } else if (status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) { stats.errors++; printf("*** SNMP Error: (%s@%s) %s\n", session.peername, storedoid, snmp_errstring(response->errstat)); } else if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { stats.polls++; } PT_MUTEX_UNLOCK(&stats.mutex); /* Liftoff, successful poll, process it */ if (status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { vars = response->variables; #ifdef OLD_UCD_SNMP sprint_value(result_string, anOID, anOID_len, vars); #else snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars); #endif switch (vars->type) { /* * Switch over vars->type and modify/assign result accordingly. */ case ASN_COUNTER64: if (set.verbose >= DEBUG) printf("64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = vars->val.counter64->high; result = result << 32; result = result + vars->val.counter64->low; break; case ASN_COUNTER: if (set.verbose >= DEBUG) printf("32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_INTEGER: if (set.verbose >= DEBUG) printf("Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_GAUGE: if (set.verbose >= DEBUG) printf("32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_TIMETICKS: if (set.verbose >= DEBUG) printf("Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OPAQUE: if (set.verbose >= DEBUG) printf("Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; default: if (set.verbose >= DEBUG) printf("Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string); } /* Gauge Type */ if (bits == 0) { if (result != last_value) { insert_val = result; if (set.verbose >= HIGH) printf("Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val); } else { if (set.withzeros) insert_val = result; if (set.verbose >= HIGH) printf("Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val); } /* Counter Wrap Condition */ } else if (result < last_value) { PT_MUTEX_LOCK(&stats.mutex); stats.wraps++; PT_MUTEX_UNLOCK(&stats.mutex); if (bits == 32) insert_val = (THIRTYTWO - last_value) + result; else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result; if (set.verbose >= LOW) { printf("*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n", session.peername, storedoid, result, last_value, insert_val); } /* Not a counter wrap and this is not the first poll */ } else if ((last_value >= 0) && (init != NEW)) { insert_val = result - last_value; /* Print out SNMP result if verbose */ if (set.verbose == DEBUG) printf("Thread [%d]: (%lld-%lld) = %llu\n", worker->index, result, last_value, insert_val); if (set.verbose == HIGH) printf("Thread [%d]: %llu\n", worker->index, insert_val); /* last_value < 0, so this must be the first poll */ } else { if (set.verbose >= HIGH) printf("Thread [%d]: First Poll, Normalizing\n", worker->index); } /* Check for bogus data, either negative or unrealistic */ if (insert_val > entry->maxspeed || result < 0) { if (set.verbose >= LOW) printf("*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n", session.peername, storedoid, insert_val, entry->maxspeed); insert_val = 0; PT_MUTEX_LOCK(&stats.mutex); stats.out_of_range++; PT_MUTEX_UNLOCK(&stats.mutex); } if (!(set.dboff)) { if ( (insert_val > 0) || (set.withzeros) ) { PT_MUTEX_LOCK(&crew->mutex); snprintf(query, sizeof(query), "INSERT INTO %s VALUES (%d, NOW(), %llu)", entry->table, entry->iid, insert_val); if (set.verbose >= DEBUG) printf("SQL: %s\n", query); status = mysql_query(&mysql, query); if (status) printf("*** MySQL Error: %s\n", mysql_error(&mysql)); PT_MUTEX_UNLOCK(&crew->mutex); if (!status) { PT_MUTEX_LOCK(&stats.mutex); stats.db_inserts++; PT_MUTEX_UNLOCK(&stats.mutex); } } /* insert_val > 0 or withzeros */ } /* !dboff */ } /* STAT_SUCCESS */ if (sessp != NULL) { snmp_sess_close(sessp); if (response != NULL) snmp_free_pdu(response); } if (set.verbose >= DEVELOP) printf("Thread [%d] locking (update work_count)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); crew->work_count--; /* Only if we received a positive result back do we update the last_value object */ if (status == STAT_SUCCESS) entry->last_value = result; if (init == NEW) entry->init = LIVE; if (crew->work_count <= 0) { if (set.verbose >= HIGH) printf("Queue processed. Broadcasting thread done condition.\n"); PT_COND_BROAD(&crew->done); } if (set.verbose >= DEVELOP) printf("Thread [%d] unlocking (update work_count)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); } /* while(1) */ }
int Host_Info::load_oid_table_get(){ unsigned int thread_id; struct snmp_session session; map<string,OID_Value_Table>::iterator iter; int fvalue=0; struct snmp_pdu *req, *resp; void *sp; // struct snmp_session *sptr; oid name[MAX_OID_LEN]; size_t name_length=MAX_OID_LEN; oid root[MAX_OID_LEN]; size_t rootlen=MAX_OID_LEN; struct variable_list *vars; char snmp_err_str[SNMP_ERR_STR_SIZE]; char buf[512]; char *placeholder; char buf2[512]; /// string temp_string1,temp_string2; int running; int status; int i; thread_id=(unsigned int) ((uint64_t)pthread_self()); snmp_sess_init(&session); session.version = SNMP_VERSION_2c; session.peername = (char *) ip_address.c_str(); session.community = (u_char *) community.c_str(); session.community_len = strlen(community.c_str()); for (iter = oid_table.begin(); iter != oid_table.end(); iter++){ assert(0==iter->first.compare(iter->second.oid)); print_log(LOG_DEBUG,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str()); rootlen = MAX_OID_LEN; //rootlen = strlen(iter->first.c_str()); if (!read_objid(iter->first.c_str(), root, &rootlen)) { //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) { //snmp_perror(argv[arg]); //exit(1); print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d oid table get?\n",iter->first.c_str(),rootlen); snmp_perror("read_objid"); return -1; } if(!(sp = snmp_sess_open(&session))){ snmp_perror("snmp_open"); print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str()); return -1; } //////////// req = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(req, root, rootlen); status = snmp_sess_synch_response(sp,req,&resp); if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){ char buf1[512]; char *placeholder; int j; oid tmp[MAX_OID_LEN]; char temp[MAX_OID_LEN]; char ifIndexstr[MAX_OID_LEN]; string value; uint64_t local_index; vars = resp->variables; //first = malloc(sizeof(struct Value_index_mapping)); //assert(first!=NULL); //memset(buf1,'\0',sizeof(buf1)); //memset(first->value,'\0',sizeof(first->value)); //int toosmall = snprint_value(buf1, sizeof(buf1), vars->name, vars->name_length, vars); placeholder = strstr(buf1,":"); if(placeholder != NULL) placeholder = placeholder +2; if(strstr(placeholder,"\"")){ placeholder = placeholder +1; //strncpy(first->value,placeholder,strlen(placeholder)-1); value=placeholder; value.resize(value.size()-1); }else{ //strcpy(first->value,placeholder); value=placeholder; } memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); for(j=0;j<vars->name_length-rootlen;j++){ if(j>0){ i = sprintf(temp, ".%d", (int) tmp[rootlen+j]); strcat(ifIndexstr,temp); }else{ i = sprintf(ifIndexstr, "%d", (int) tmp[rootlen+j]); } } //strcpy(first->index,ifIndexstr); temp_string2=ifIndexstr; local_index=atoll(temp_string2.c_str()); assert(0==1); //this should never get here! under rev 3.1.0 initial //iter->second.indexof[value]=local_index; //iter->second.valueof[local_index]=value; //first->next = NULL; //current = first; }else{ snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"Failure buidling snmp_table Hostname: %s snmp_sync_response",ip_address.c_str()); snmp_perror(snmp_err_str); if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); return -1; } //////////////// running=1; while(running==1) { ///////// oid tmp[MAX_OID_LEN]; req = snmp_pdu_create(SNMP_MSG_GETNEXT); snmp_add_null_var(req,vars->name,vars->name_length); if(resp) snmp_free_pdu(resp); status = snmp_sess_synch_response(sp,req,&resp); if(status == STAT_SUCCESS && resp->errstat == SNMP_ERR_NOERROR){ struct Value_index_mapping *tempIndex = NULL; char buf[512]; char *placeholder; char ifIndexstr[MAX_OID_LEN]; int j; char temp[MAX_OID_LEN]; oid tmp[MAX_OID_LEN]; string value_string; string index_string; int64_t local_index; vars = resp->variables; //tempIndex = malloc(sizeof(struct Value_index_mapping)); //why allocate a != struct? //assert(tempIndex!=NULL); //memset(buf,'\0',sizeof(buf)); //memset(tempIndex->value,'\0',sizeof(tempIndex->value)); //will add a few extra bytes later, ensure we are covered snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars); //printf("Raw Value = %s\n",buf); placeholder = strstr(buf,":"); if(placeholder != NULL) placeholder = placeholder +2; if(strstr(placeholder,"\"")){ placeholder = placeholder +1; //you assert on the size of the dest, not the origin assert(strlen(placeholder)+1<STD_STRING_SIZE); //strncpy(tempIndex->value,placeholder,strlen(placeholder)); value_string=placeholder; }else{ //strncpy(tempIndex->value,placeholder,STD_STRING_SIZE-1); value_string=placeholder; value_string.resize(value_string.size()-1); } memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); for(j=0;j<vars->name_length-rootlen;j++){ if(j>0){ i = sprintf(temp, ".%d",(int) tmp[rootlen+j]); strcat(ifIndexstr,temp); }else{ i = sprintf(ifIndexstr, "%d",(int) tmp[rootlen+j]); } } //strcpy(tempIndex->index,ifIndexstr); index_string=ifIndexstr; local_index=atoll(index_string.c_str()); assert(1==0); //this should never reach this under 3.1.0 //iter->second.indexof[value_string]=local_index; //iter->second.valueof[local_index]=value_string; //print_log(LOG_DEBUG,"[Thread %u] Index = %u , Value = %s\n",thread_id,local_index,value_string.c_str()); //current->next = tempIndex; //current = tempIndex; //current->next = NULL; }else{ //snmp_perror("snmp_synch_response"); //snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, hostInfo.name); snmp_perror(snmp_err_str); if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); return -1; } //oid tmp[MAX_OID_LEN]; memcpy(tmp,vars->name,vars->name_length * sizeof(oid)); if(tmp[rootlen-1] != root[rootlen-1]){ if(resp) snmp_free_pdu(resp); snmp_sess_close(sp); running=0; //done? } ////////// } //end while }//end for each host }
/////////////////////////////////////////////////////////////// /// Given a host loads all the oid mappings for that host /// Uses snmp bulk get to minimize the time required for each /// mapping. int Host_Info::load_oid_table(){ unsigned int thread_id; struct snmp_session session; map<string,OID_Value_Table>::iterator iter; int fvalue=0; //// //netsnmp_session session, *ss; int numprinted = 0; int reps = 15, non_reps = 0; netsnmp_pdu *pdu, *response=NULL; netsnmp_variable_list *vars; int arg; oid name[MAX_OID_LEN]; size_t name_length; oid root[MAX_OID_LEN]; size_t rootlen; int count; int running; int status; int check; int exitval = 0; struct snmp_pdu *req, *resp; void *sp; char snmp_err_str[SNMP_ERR_STR_SIZE]; char buf[512]; char *placeholder; char buf2[512]; /// string temp_string1,temp_string2; int i; //////////// thread_id=(unsigned int)((uint64_t) pthread_self()); simple_snmp_sess_init(&session); session.retries=4; session.version = SNMP_VERSION_2c; //ARE THE NEXT TWO LINES VALID???! session.peername = (char *) ip_address.c_str(); session.community = (u_char *) community.c_str(); session.community_len = strlen(community.c_str()); for (iter = oid_table.begin(); iter != oid_table.end(); iter++){ /// assert(0==iter->first.compare(iter->second.oid)); print_log(LOG_INFO,"Doing host=%s for oid %s\n",ip_address.c_str(),iter->first.c_str()); rootlen = MAX_OID_LEN; //rootlen = strlen(iter->first.c_str()); if (!read_objid(iter->first.c_str(), root, &rootlen)) { //if (!Read_objid_ts(iter->first.c_str(), root, &rootlen)) { //snmp_perror(argv[arg]); //exit(1); print_log(LOG_ERR,"Cannot parse the oid='%s' rootlen=%d host=%s\n",iter->first.c_str(),rootlen,ip_address.c_str()); snmp_perror("read_objid"); return -1; } if(!(sp = snmp_sess_open(&session))){ snmp_perror("snmp_open"); print_log(LOG_WARNING,"[Thread %u] SNMP table builder, failed to open session to %s\n",thread_id,ip_address.c_str()); return -1; } running=1; //why memmove and not memcpy? ask the netsmpbulk writers memmove(name, root, rootlen * sizeof(oid)); name_length = rootlen; //should be a while while(running==1){ /* * create PDU for GETBULK request and add object name to request */ pdu = snmp_pdu_create(SNMP_MSG_GETBULK); pdu->non_repeaters = non_reps; pdu->max_repetitions = reps; /* fill the packet */ snmp_add_null_var(pdu, name, name_length); /* * do the request */ //status = snmp_synch_response(sp, pdu, &response); status = snmp_sess_synch_response(sp,pdu,&response); switch (status){ case STAT_SUCCESS: if (response->errstat == SNMP_ERR_NOERROR) { //Yay success! ////////////// for (vars = response->variables; vars; vars = vars->next_variable) { if ((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0)) { /* * not part of this subtree */ running = 0; continue; } numprinted++; //print_log(LOG_DEBUG,"num_printed=%d\n",numprinted); //print_variable(vars->name, vars->name_length, vars); if ((vars->type != SNMP_ENDOFMIBVIEW) && (vars->type != SNMP_NOSUCHOBJECT) && (vars->type != SNMP_NOSUCHINSTANCE)) { /* * not an exception value */ /* if (check && snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) { fprintf(stderr, "Error: OID not increasing: "); fprint_objid(stderr, name, name_length); fprintf(stderr, " >= "); fprint_objid(stderr, vars->name, vars->name_length); fprintf(stderr, "\n"); running = 0; exitval = 1; } */ snmp_err_str[0]=0; snprint_objid(snmp_err_str,SNMP_ERR_STR_SIZE-1,vars->name,vars->name_length); snprint_value(buf, sizeof(buf)-5, vars->name, vars->name_length, vars); //print_log(LOG_DEBUG,"[Thread %u] '%s'='%s'\n",thread_id,snmp_err_str,buf); temp_string1=snmp_err_str; size_t found; found=temp_string1.find_last_of("."); temp_string2=temp_string1.substr(found+1); string search_string; found=iter->first.find_last_not_of(".0123456789"); if(found==iter->first.npos){ //not found the search string is the whole thing! search_string=iter->first; } else{ search_string=iter->first.substr(found); } search_string=iter->first.substr((iter->first.length()*2)/3); string suffix_str; //iterate over the data. found=temp_string1.find(iter->first); found=temp_string1.find(search_string); print_log(LOG_DEBUG,"[Thread %u] [host %s] found=%u first=%s temp_string1=%s search_str=%s\n" , thread_id,ip_address.c_str(), found,iter->first.c_str(),temp_string1.c_str(),search_string.c_str()); if(temp_string1.npos!=found){ //print_log(LOG_INFO,"[Thread %u] [host %s] found!\n",thread_id,ip_address.c_str()); //suffix_str=temp_string1.substr(found+iter->first.length()+1); suffix_str=temp_string1.substr(found+search_string.length()+1); //print_log(LOG_INFO,"[Thread %u] found=%u first=%s temp_string1=%s\n" , thread_id,found,iter->first.c_str(),temp_string1.c_str()); print_log(LOG_DEBUG,"[Thread %u] [host %s] found =%s!\n",thread_id,ip_address.c_str(),suffix_str.c_str()); } else{ print_log(LOG_DEBUG,"[Thread %u] [host %s] NOT found!\n",thread_id,ip_address.c_str()); found=temp_string1.find_last_of("."); suffix_str=temp_string1.substr(found+1); } //print_log(LOG_DEBUG,"[Thread %u] index='%s'\n",thread_id,temp_string2.c_str()); uint64_t local_index; local_index=atoll(temp_string2.c_str()); //printf("Raw Value = %s\n",buf); temp_string2=extract_value_from_raw(buf); //print_log(LOG_DEBUG,"[Thread %u] index=%lu value='%s' \n",thread_id,local_index,buf2); //iter->second.indexof[temp_string2]=local_index; //iter->second.valueof[local_index]=temp_string2; iter->second.suffix_of[temp_string2]=suffix_str; iter->second.value_of[suffix_str]=temp_string2; print_log(LOG_DEBUG,"[Thread %u] [host %s] suffix_of[%s]='%s' \n",thread_id,ip_address.c_str(),temp_string2.c_str(),suffix_str.c_str()); /* * Check if last variable, and if so, save for next request. */ if (vars->next_variable == NULL) { memmove(name, vars->name, vars->name_length * sizeof(oid)); name_length = vars->name_length; } } else { /* * an exception value, so stop */ running = 0; } } //////////////// } else{ ///Error in response, report and exit loop running=0; snprintf(snmp_err_str,SNMP_ERR_STR_SIZE-1,"[Thread %u] Hostname: %-15s snmp_sync_response",thread_id, ip_address.c_str()); snmp_perror(snmp_err_str); } break; case STAT_TIMEOUT: print_log(LOG_NOTICE,"[Thread %u] SNMP timeout(building table), host=%15s \n",thread_id, ip_address.c_str() ); running=0; break; default: //other error! print_log(LOG_ERR,"SNMP MISC error\n"); running=0; break; } if (response){ snmp_free_pdu(response); response=NULL; } if(0==iter->second.suffix_of.size()){ print_log(LOG_WARNING,"[Thread %u][host %s] no data inserted for %s\n",thread_id,ip_address.c_str(),iter->first.c_str()); //fvalue=-1; } //print_log(LOG_DEBUG,"[Thread %u] inserted %d values\n" ,thread_id,iter->second.indexof.size()); }//end while if (response){ snmp_free_pdu(response); response=NULL; } //is this the best place to clse it? snmp_sess_close(sp); }//end for return fvalue; }
/*! \fn void snmp_host_cleanup(void *snmp_session) * \brief closes an established snmp session * * This function performs cleanup of the snmp sessions once polling is completed * for a host. * */ void snmp_host_cleanup(void *snmp_session) { if (snmp_session != NULL) { snmp_sess_close(snmp_session); } }
void *poller(void *thread_args) { worker_t *worker = (worker_t *) thread_args; crew_t *crew = worker->crew; target_t *entry = NULL; void *sessp = NULL; struct snmp_session session; struct snmp_pdu *pdu = NULL; struct snmp_pdu *response = NULL; oid anOID[MAX_OID_LEN]; size_t anOID_len = MAX_OID_LEN; struct variable_list *vars = NULL; unsigned long long result = 0; unsigned long long last_value = 0; unsigned long long insert_val = 0; int poll_status = 0, db_status = 0, bits = 0, init = 0; char query[BUFSIZE]; char storedoid[BUFSIZE]; char result_string[BUFSIZE]; int cur_work = 0; int prev_work = 99999999; int loop_count = 0; #ifdef FEATURES /* Per thread SQL connection testing */ #if HAVE_MYSQL MYSQL mysql; #elif HAVE_PGSQL PGconn *pgsql; #endif double rate = 0; struct timezone tzp; struct timeval current_time; struct timeval last_time; /* for thread settings */ int oldstate, oldtype; #endif debug(HIGH, "Thread [%d] starting.\n", worker->index); pthread_cleanup_push(cleanup_db, NULL); /* Attempt to connect to the MySQL Database */ #ifdef FEATURES /* Per thread MySQL connection testing */ if (!(set->dboff)) { /* load the database driver */ if (!(db_init(set))) { fatal("** Database error - check configuration.\n"); } /* connect to the database */ if (!(db_connect(set))) { fatal("server not responding.\n"); } /* set up cancel function for exit */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); } #endif /* FEATURES */ while (1) { /* if(loop_count >= POLLS_PER_TRANSACTION) { debug(HIGH, "Thread [%d] doing commit on %d\n", worker->index, POLLS_PER_TRANSACTION); db_status = db_commit(); loop_count = 0; } */ #ifdef FEATURES /* see if we've been cancelled before we start another loop */ pthread_testcancel(); #endif debug(DEVELOP, "Thread [%d] locking (wait on work)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); #ifdef FEATURES /* add an unlock to the cancel stack */ pthread_cleanup_push(cancel_lock, &crew->mutex); #endif while (current == NULL) { PT_COND_WAIT(&crew->go, &crew->mutex); } debug(DEVELOP, "Thread [%d] done waiting, received go (work cnt: %d)\n", worker->index, crew->work_count); cur_work = crew->work_count; /* if(cur_work > prev_work) { debug(HIGH, "Thread [%d] doing commit at %d\n", worker->index,time(NULL)); db_status = db_commit(); loop_count = 0; } */ prev_work = cur_work; if (current != NULL) { debug(DEVELOP, "Thread [%d] processing %s %s (%d work units remain in queue)\n", worker->index, current->host->host, current->objoid, crew->work_count); snmp_enable_stderrlog(); snmp_sess_init(&session); if (current->host->snmp_ver == 2) session.version = SNMP_VERSION_2c; else session.version = SNMP_VERSION_1; session.peername = current->host->host; session.community = current->host->community; session.remote_port = set->snmp_port; session.community_len = strlen(session.community); sessp = snmp_sess_open(&session); anOID_len = MAX_OID_LEN; pdu = snmp_pdu_create(SNMP_MSG_GET); read_objid(current->objoid, anOID, &anOID_len); entry = current; last_value = current->last_value; #ifdef FEATURES /* save the time so we can calculate rate */ last_time = current->last_time; #endif init = current->init; insert_val = 0; bits = current->bits; strncpy(storedoid, current->objoid, sizeof(storedoid)); current = getNext(); } debug(DEVELOP, "Thread [%d] unlocking (done grabbing current)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); #ifdef FEATURES /* take the unlock off the cancel stack */ pthread_cleanup_pop(FALSE); #endif snmp_add_null_var(pdu, anOID, anOID_len); if (sessp != NULL) poll_status = snmp_sess_synch_response(sessp, pdu, &response); else poll_status = STAT_DESCRIP_ERROR; /* Collect response and process stats */ PT_MUTEX_LOCK(&stats.mutex); if (poll_status == STAT_DESCRIP_ERROR) { stats.errors++; printf("*** SNMP Error: (%s) Bad descriptor.\n", session.peername); } else if (poll_status == STAT_TIMEOUT) { stats.no_resp++; printf("*** SNMP No response: (%s@%s).\n", session.peername, storedoid); } else if (poll_status != STAT_SUCCESS) { stats.errors++; printf("*** SNMP Error: (%s@%s) Unsuccessuful (%d).\n", session.peername, storedoid, poll_status); } else if (poll_status == STAT_SUCCESS && response->errstat != SNMP_ERR_NOERROR) { stats.errors++; printf("*** SNMP Error: (%s@%s) %s\n", session.peername, storedoid, snmp_errstring(response->errstat)); } else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type == SNMP_NOSUCHINSTANCE) { stats.errors++; printf("*** SNMP Error: No Such Instance Exists (%s@%s)\n", session.peername, storedoid); } else if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR) { stats.polls++; } PT_MUTEX_UNLOCK(&stats.mutex); /* Liftoff, successful poll, process it */ #ifdef FEATURES /* Get the current time */ gettimeofday(¤t_time, &tzp); #endif if (poll_status == STAT_SUCCESS && response->errstat == SNMP_ERR_NOERROR && response->variables->type != SNMP_NOSUCHINSTANCE) { vars = response->variables; #ifdef OLD_UCD_SNMP sprint_value(result_string, anOID, anOID_len, vars); #else snprint_value(result_string, BUFSIZE, anOID, anOID_len, vars); #endif switch (vars->type) { /* * Switch over vars->type and modify/assign result accordingly. */ case ASN_COUNTER64: debug(DEBUG, "64-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = vars->val.counter64->high; result = result << 32; result = result + vars->val.counter64->low; break; case ASN_COUNTER: debug(DEBUG, "32-bit result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_INTEGER: debug(DEBUG, "Integer result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_GAUGE: debug(DEBUG, "32-bit gauge: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_TIMETICKS: debug(DEBUG, "Timeticks result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OPAQUE: debug(DEBUG, "Opaque result: (%s@%s) %s\n", session.peername, storedoid, result_string); result = (unsigned long) *(vars->val.integer); break; case ASN_OCTET_STR: debug(DEBUG, "String Result: (%s@%s) %s\n", session.peername, storedoid, result_string); #ifdef HAVE_STRTOLL result = strtoll(vars->val.string, NULL, 0); #else result = strtol(vars->val.string, NULL, 0); #endif break; default: debug(LOW, "Unknown result type: (%s@%s) %s\n", session.peername, storedoid, result_string); } /* Gauge Type */ if (bits == 0) { if (result != last_value) { insert_val = result; debug(DEVELOP, "Thread [%d]: Gauge change from %lld to %lld\n", worker->index, last_value, insert_val); } else { if (set->withzeros) insert_val = result; debug(DEVELOP, "Thread [%d]: Gauge steady at %lld\n", worker->index, insert_val); } /* Counter Wrap Condition */ } else if (result < last_value) { PT_MUTEX_LOCK(&stats.mutex); stats.wraps++; PT_MUTEX_UNLOCK(&stats.mutex); if (bits == 32) insert_val = (THIRTYTWO - last_value) + result; else if (bits == 64) insert_val = (SIXTYFOUR - last_value) + result; #ifdef FEATURES rate = insert_val / timediff(current_time, last_time); #endif debug(LOW, "*** Counter Wrap (%s@%s) [poll: %llu][last: %llu][insert: %llu]\n", session.peername, storedoid, result, last_value, insert_val); /* Not a counter wrap and this is not the first poll */ } else if ((last_value >= 0) && (init != NEW)) { insert_val = result - last_value; #ifdef FEATURES rate = insert_val / timediff(current_time, last_time); #endif /* Print out SNMP result if verbose */ if (set->verbose == DEBUG) printf("Thread [%d]: (%lld-%lld -- %llu) = %llu\n", worker->index, result, last_value, insert_val,rate); if (set->verbose == HIGH) printf("Thread [%d]: %llu\n", worker->index, insert_val); /* last_value < 0, so this must be the first poll */ } else { #ifdef FEATURES /* set up this result for the next poll */ entry->last_value = result; #endif debug(HIGH, "Thread [%d]: First Poll, Normalizing\n", worker->index); } /* Check for bogus data, either negative or unrealistic */ if (insert_val > entry->maxspeed || result < 0) { debug(LOW, "*** Out of Range (%s@%s) [insert_val: %llu] [oor: %lld]\n", session.peername, storedoid, insert_val, entry->maxspeed); insert_val = 0; #ifdef FEATURES rate = 0; #endif PT_MUTEX_LOCK(&stats.mutex); stats.out_of_range++; PT_MUTEX_UNLOCK(&stats.mutex); } if (!(set->dboff)) { if ( (insert_val > 0) || (set->withzeros) ) { #ifndef FEATURES /* MP - since we have our own database connection we don't need to lock it anymore */ PT_MUTEX_LOCK(&crew->mutex); #endif debug(DEVELOP, "db_insert sent: %s %d %d %e\n",entry->table,entry->iid,insert_val,rate); /* insert into the database */ db_status = db_insert(entry->table, entry->iid, insert_val, rate); #ifndef FEATURES /* MP - since we have our own database connection we don't need to lock it anymore */ PT_MUTEX_UNLOCK(&crew->mutex); #endif if (db_status) { PT_MUTEX_LOCK(&stats.mutex); stats.db_inserts++; PT_MUTEX_UNLOCK(&stats.mutex); } else { fatal("Fatal database error.\n"); } } /* insert_val > 0 or withzeros */ } /* !dboff */ } /* STAT_SUCCESS */ /* debug(HIGH, "Thread [%d] doing commit\n", worker->index); db_status = db_commit(); */ if (sessp != NULL) { snmp_sess_close(sessp); if (response != NULL) snmp_free_pdu(response); } debug(DEVELOP, "Thread [%d] locking (update work_count)\n", worker->index); PT_MUTEX_LOCK(&crew->mutex); crew->work_count--; /* Only if we received a positive result back do we update the last_value object */ if (poll_status == STAT_SUCCESS) { entry->last_value = result; if (init == NEW) entry->init = LIVE; } #ifdef FEATURES /* always update the time */ entry->last_time = current_time; #endif if (crew->work_count <= 0) { debug(HIGH, "Queue processed. Broadcasting thread done condition.\n"); PT_COND_BROAD(&crew->done); } debug(DEVELOP, "Thread [%d] unlocking (update work_count)\n", worker->index); PT_MUTEX_UNLOCK(&crew->mutex); loop_count++; } /* while(1) */ pthread_cleanup_pop(FALSE); /* Not reached */ }