/*
 * 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);
}
Beispiel #2
0
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);
    }
}