/* * Check if disk archiving is configured by looking for diskvols.conf * file. If it is configured then HA-SAM will not support it. * * Return: success = B_TRUE [or] failure = B_FALSE */ boolean_t check_disk_archive_conf(void) { struct stat buf; boolean_t found; struct disk_archive_info *dskarch_info; int j; if (stat(diskvolsconf, &buf) < 0) { scds_syslog(LOG_DEBUG, "Disk archiving not configured"); dprintf(stderr, "Disk archiving not configured !\n"); /* * Since disk archiving is not configured, just return * success as no need to do further processing */ return (B_TRUE); } /* * Since diskvols.conf file exists, * gather disk resource information */ dskarch_info = collect_diskarchive_info(); if ((dskarch_info == NULL) || (num_disk_archives <= 0)) { dprintf(stderr, "Error collecting disk archive info\n"); free(dskarch_info); return (B_FALSE); } for (j = 0; j < num_disk_archives; j++) { /* * Verify if disk archive directory are valid * for locally available resources with no host. */ if (streq(dskarch_info->dskarch_host[j], "")) { if (search_dir(dskarch_info->dskarch_path[j]) == NULL) { scds_syslog(LOG_ERR, "Invalid disk archive directory %s !", dskarch_info->dskarch_path[j]); dprintf(stderr, "Invalid disk archive directory %s !\n", dskarch_info->dskarch_path[j]); free(dskarch_info); return (B_FALSE); } } else { /* * Disk archive resource is on a remote server. * Verify if remote host can be ping'd on which * NFS disk archive resources are configured. * In this case host has a valid entry. */ if (!ping_host(dskarch_info->dskarch_host[j])) { dprintf(stderr, "Unable to ping host = %s\n", dskarch_info->dskarch_host[j]); return (B_FALSE); } } } free(dskarch_info); return (B_TRUE); }
void poll_host(int host_id) { char query1[BUFSIZE]; char query2[BUFSIZE]; char *query3; char query4[BUFSIZE]; char errstr[512]; int num_rows; int host_status; int assert_fail = 0; char *poll_result = NULL; char logmessage[LOGSIZE]; char update_sql[BUFSIZE]; reindex_t *reindex; target_t *entry; host_t *host; ping_t *ping; MYSQL mysql; MYSQL_RES *result; MYSQL_ROW row; /* allocate host and ping structures with appropriate values */ host = (host_t *) malloc(sizeof(host_t)); ping = (ping_t *) malloc(sizeof(ping_t)); #ifndef OLD_MYSQL mysql_thread_init(); #endif snprintf(query1, sizeof(query1), "select action,hostname,snmp_community,snmp_version,snmp_username,snmp_password,rrd_name,rrd_path,arg1,arg2,arg3,local_data_id,rrd_num,snmp_port,snmp_timeout from poller_item where host_id=%i order by rrd_path,rrd_name", host_id); snprintf(query2, sizeof(query2), "select id, hostname,snmp_community,snmp_version,snmp_port,snmp_timeout,status,status_event_count,status_fail_date,status_rec_date,status_last_error,min_time,max_time,cur_time,avg_time,total_polls,failed_polls,availability from host where id=%i", host_id); snprintf(query4, sizeof(query4), "select data_query_id,action,op,assert_value,arg1 from poller_reindex where host_id=%i", host_id); db_connect(set.dbdb, &mysql); /* get data about this host */ result = db_query(&mysql, query2); num_rows = (int)mysql_num_rows(result); if (num_rows != 1) { snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Host ID", host_id); cacti_log(logmessage); return; } row = mysql_fetch_row(result); /* populate host structure */ host->id = atoi(row[0]); if (row[1] != NULL) snprintf(host->hostname, sizeof(host->hostname), "%s", row[1]); if (row[2] != NULL) snprintf(host->snmp_community, sizeof(host->snmp_community), "%s", row[2]); host->snmp_version = atoi(row[3]); host->snmp_port = atoi(row[4]); host->snmp_timeout = atoi(row[5]); if (row[6] != NULL) host->status = atoi(row[6]); host->status_event_count = atoi(row[7]); snprintf(host->status_fail_date, sizeof(host->status_fail_date), "%s", row[8]); snprintf(host->status_rec_date, sizeof(host->status_rec_date), "%s", row[9]); snprintf(host->status_last_error, sizeof(host->status_last_error), "%s", row[10]); host->min_time = atof(row[11]); host->max_time = atof(row[12]); host->cur_time = atof(row[13]); host->avg_time = atof(row[14]); host->total_polls = atoi(row[15]); host->failed_polls = atoi(row[16]); host->availability = atof(row[17]); host->ignore_host = 0; /* initialize SNMP */ snmp_host_init(host); /* perform a check to see if the host is alive by polling it's SysDesc * if the host down from an snmp perspective, don't poll it. * function sets the ignore_host bit */ if ((set.availability_method == AVAIL_SNMP) && (host->snmp_community == "")) { update_host_status(HOST_UP, host, ping, set.availability_method); if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%s] No host availability check possible for '%s'\n", host->id, host->hostname); cacti_log(logmessage); } } else { if (ping_host(host, ping) == HOST_UP) { update_host_status(HOST_UP, host, ping, set.availability_method); } else { host->ignore_host = 1; update_host_status(HOST_DOWN, host, ping, set.availability_method); } } /* update host table */ snprintf(update_sql, sizeof(update_sql), "update host set status='%i',status_event_count='%i', status_fail_date='%s',status_rec_date='%s',status_last_error='%s',min_time='%f',max_time='%f',cur_time='%f',avg_time='%f',total_polls='%i',failed_polls='%i',availability='%.4f' where id='%i'\n", host->status, host->status_event_count, host->status_fail_date, host->status_rec_date, host->status_last_error, host->min_time, host->max_time, host->cur_time, host->avg_time, host->total_polls, host->failed_polls, host->availability, host->id); db_insert(&mysql, update_sql); /* do the reindex check for this host */ if (!host->ignore_host) { reindex = (reindex_t *) malloc(sizeof(reindex_t)); result = db_query(&mysql, query4); num_rows = (int)mysql_num_rows(result); if (num_rows > 0) { if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "Host[%i] RECACHE: Processing %i items in the auto reindex cache for '%s'\n", host->id, num_rows, host->hostname); cacti_log(logmessage); } while ((row = mysql_fetch_row(result))) { assert_fail = 0; reindex->data_query_id = atoi(row[0]); reindex->action = atoi(row[1]); if (row[2] != NULL) snprintf(reindex->op, sizeof(reindex->op), "%s", row[2]); if (row[3] != NULL) snprintf(reindex->assert_value, sizeof(reindex->assert_value), "%s", row[3]); if (row[4] != NULL) snprintf(reindex->arg1, sizeof(reindex->arg1), "%s", row[4]); switch(reindex->action) { case POLLER_ACTION_SNMP: /* snmp */ poll_result = snmp_get(host, reindex->arg1); break; case POLLER_ACTION_SCRIPT: /* script (popen) */ poll_result = exec_poll(host, reindex->arg1); break; } /* assume ok if host is up and result wasn't obtained */ if (!strcmp(poll_result,"U")) { assert_fail = 0; } else if ((!strcmp(reindex->op, "=")) && (strcmp(reindex->assert_value,poll_result) != 0)) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s=%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } else if ((!strcmp(reindex->op, ">")) && (strtoll(reindex->assert_value, (char **)NULL, 10) <= strtoll(poll_result, (char **)NULL, 10))) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s>%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } else if ((!strcmp(reindex->op, "<")) && (strtoll(reindex->assert_value, (char **)NULL, 10) >= strtoll(poll_result, (char **)NULL, 10))) { snprintf(logmessage, LOGSIZE, "ASSERT: '%s<%s' failed. Recaching host '%s', data query #%i\n", reindex->assert_value, poll_result, host->hostname, reindex->data_query_id); cacti_log(logmessage); query3 = (char *)malloc(128); snprintf(query3, 128, "insert into poller_command (poller_id,time,action,command) values (0,NOW(),%i,'%i:%i')", POLLER_COMMAND_REINDEX, host_id, reindex->data_query_id); db_insert(&mysql, query3); free(query3); assert_fail = 1; } /* update 'poller_reindex' with the correct information if: * 1) the assert fails * 2) the OP code is > or < meaning the current value could have changed without causing * the assert to fail */ if ((assert_fail == 1) || (!strcmp(reindex->op, ">")) || (!strcmp(reindex->op, ">"))) { query3 = (char *)malloc(255); snprintf(query3, 255, "update poller_reindex set assert_value='%s' where host_id='%i' and data_query_id='%i' and arg1='%s'", poll_result, host_id, reindex->data_query_id, reindex->arg1); db_insert(&mysql, query3); free(query3); } free(poll_result); } } } /* retreive each hosts polling items from poller cache */ entry = (target_t *) malloc(sizeof(target_t)); result = db_query(&mysql, query1); num_rows = (int)mysql_num_rows(result); while ((row = mysql_fetch_row(result)) && (!host->ignore_host)) { /* initialize monitored object */ entry->target_id = 0; entry->action = atoi(row[0]); if (row[1] != NULL) snprintf(entry->hostname, sizeof(entry->hostname), "%s", row[1]); if (row[2] != NULL) { snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", row[2]); } else { snprintf(entry->snmp_community, sizeof(entry->snmp_community), "%s", ""); } entry->snmp_version = atoi(row[3]); if (row[4] != NULL) snprintf(entry->snmp_username, sizeof(entry->snmp_username), "%s", row[4]); if (row[5] != NULL) snprintf(entry->snmp_password, sizeof(entry->snmp_password), "%s", row[5]); if (row[6] != NULL) snprintf(entry->rrd_name, sizeof(entry->rrd_name), "%s", row[6]); if (row[7] != NULL) snprintf(entry->rrd_path, sizeof(entry->rrd_path), "%s", row[7]); if (row[8] != NULL) snprintf(entry->arg1, sizeof(entry->arg1), "%s", row[8]); if (row[9] != NULL) snprintf(entry->arg2, sizeof(entry->arg2), "%s", row[9]); if (row[10] != NULL) snprintf(entry->arg3, sizeof(entry->arg3), "%s", row[10]); entry->local_data_id = atoi(row[11]); entry->rrd_num = atoi(row[12]); entry->snmp_port = atoi(row[13]); entry->snmp_timeout = atoi(row[14]); snprintf(entry->result, sizeof(entry->result), "%s", "U"); if (!host->ignore_host) { switch(entry->action) { case POLLER_ACTION_SNMP: /* raw SNMP poll */ poll_result = snmp_get(host, entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); if (host->ignore_host) { snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: SNMP timeout detected [%i milliseconds], ignoring host '%s'\n", host_id, host->snmp_timeout, host->hostname); cacti_log(logmessage); snprintf(entry->result, sizeof(entry->result), "%s", "U"); } else { /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous non-numeric result */ if (!is_numeric(entry->result)) { strncpy(errstr, entry->result,sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SNMP not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SNMP: v%i: %s, dsname: %s, oid: %s, value: %s\n", host_id, host->snmp_version, host->hostname, entry->rrd_name, entry->arg1, entry->result); cacti_log(logmessage); } break; case POLLER_ACTION_SCRIPT: /* execute script file */ poll_result = exec_poll(host, entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous result. can be non-numeric */ if (!validate_result(entry->result)) { strncpy(errstr, (char *) strip_string_crlf(entry->result),sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SCRIPT not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SCRIPT: %s, output: %s\n", host_id, entry->arg1, entry->result); cacti_log(logmessage); } break; case POLLER_ACTION_PHP_SCRIPT_SERVER: /* execute script server */ poll_result = php_cmd(entry->arg1); snprintf(entry->result, sizeof(entry->result), "%s", poll_result); free(poll_result); /* remove double or single quotes from string */ strncpy(entry->result, strip_quotes(entry->result), sizeof(entry->result)); /* detect erroneous result. can be non-numeric */ if (!validate_result(entry->result)) { strncpy(errstr, entry->result, sizeof(errstr)); snprintf(logmessage, LOGSIZE, "Host[%i] WARNING: Result from SERVER not valid. Partial Result: %.20s...\n", host_id, errstr); cacti_log(logmessage); strncpy(entry->result, "U", sizeof(entry->result)); } if (set.verbose >= POLLER_VERBOSITY_MEDIUM) { snprintf(logmessage, LOGSIZE, "Host[%i] SERVER: %s, output: %s\n", host_id, entry->arg1, entry->result); cacti_log(logmessage); } break; default: /* unknown action, generate error */ snprintf(logmessage, LOGSIZE, "Host[%i] ERROR: Unknown Poller Action: %s\n", host_id, entry->arg1); cacti_log(logmessage); break; } } if (entry->result != NULL) { /* format database insert string */ query3 = (char *)malloc(sizeof(entry->result) + sizeof(entry->local_data_id) + 128); snprintf(query3, (sizeof(entry->result) + sizeof(entry->local_data_id) + 128), "insert into poller_output (local_data_id,rrd_name,time,output) values (%i,'%s','%s','%s')", entry->local_data_id, entry->rrd_name, start_datetime, entry->result); db_insert(&mysql, query3); free(query3); } } /* cleanup memory and prepare for function exit */ snmp_host_cleanup(host); free(entry); free(host); free(ping); mysql_free_result(result); #ifndef OLD_MYSQL mysql_thread_end(); #endif mysql_close(&mysql); if (set.verbose == POLLER_VERBOSITY_DEBUG) { snprintf(logmessage, LOGSIZE, "Host[%i] DEBUG: HOST COMPLETE: About to Exit Host Polling Thread Function\n", host_id); cacti_log(logmessage); } }