/****************************************************************************** * * * Function: get_proxy_id * * * * Purpose: * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ int get_proxy_id(struct zbx_json_parse *jp, zbx_uint64_t *hostid) { DB_RESULT result; DB_ROW row; char host[HOST_HOST_LEN_MAX], host_esc[MAX_STRING_LEN]; int res = FAIL; if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { DBescape_string(host, host_esc, sizeof(host_esc)); result = DBselect("select hostid from hosts where host='%s'" " and status in (%d)" DB_NODE, host_esc, HOST_STATUS_PROXY, DBnode_local("hostid")); if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0])) { *hostid = zbx_atoui64(row[0]); res = SUCCEED; } else zabbix_log(LOG_LEVEL_WARNING, "Unknown proxy \"%s\"", host); DBfree_result(result); } else { zabbix_log(LOG_LEVEL_WARNING, "Incorrect data. %s", zbx_json_strerror()); zabbix_syslog("Incorrect data. %s", zbx_json_strerror()); } return res; }
/****************************************************************************** * * * Function: update_triggers * * * * Purpose: re-calculate and updates values of triggers related to the item * * * * Parameters: itemid - item to update trigger values for * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ void update_triggers(zbx_uint64_t itemid) { char *exp; char error[MAX_STRING_LEN]; int exp_value; DB_TRIGGER trigger; DB_RESULT result; DB_ROW row; zabbix_log( LOG_LEVEL_DEBUG, "In update_triggers [itemid:" ZBX_FS_UI64 "]", itemid); result = DBselect("select distinct t.triggerid,t.expression,t.description,t.url,t.comments,t.status,t.value,t.priority,t.type from triggers t,functions f,items i where i.status<>%d and i.itemid=f.itemid and t.status=%d and f.triggerid=t.triggerid and f.itemid=" ZBX_FS_UI64, ITEM_STATUS_NOTSUPPORTED, TRIGGER_STATUS_ENABLED, itemid); while((row=DBfetch(result))) { ZBX_STR2UINT64(trigger.triggerid,row[0]); strscpy(trigger.expression,row[1]); strscpy(trigger.description,row[2]); trigger.url = row[3]; trigger.comments = row[4]; trigger.status = atoi(row[5]); trigger.value = atoi(row[6]); trigger.priority = atoi(row[7]); trigger.type = atoi(row[8]); exp = strdup(trigger.expression); if( evaluate_expression(&exp_value, &exp, &trigger, error, sizeof(error)) != 0 ) { zabbix_log(LOG_LEVEL_WARNING, "Expression [%s] for item [" ZBX_FS_UI64 "][%s] cannot be evaluated: %s", trigger.expression, itemid, zbx_host_key_string(itemid), error); zabbix_syslog("Expression [%s] for item [" ZBX_FS_UI64 "][%s] cannot be evaluated: %s", trigger.expression, itemid, zbx_host_key_string(itemid), error); /* DBupdate_trigger_value(&trigger, exp_value, time(NULL), error);*//* We shouldn't update triggervalue if expressions failed */ } else { DBupdate_trigger_value(&trigger, exp_value, time(NULL), NULL); } zbx_free(exp); } DBfree_result(result); zabbix_log( LOG_LEVEL_DEBUG, "End update_triggers [" ZBX_FS_UI64 "]", itemid); }
/****************************************************************************** * * * Function: proxy_update_item * * * * Purpose: update item info after new value is received * * * * Parameters: item - item data * * value - new value of the item * * now - current timestamp * * * * Author: Alexei Vladishev, Eugene Grigorjev * * * * Comments: * * * ******************************************************************************/ static void proxy_update_item(DB_ITEM *item, AGENT_RESULT *value, time_t now) { zabbix_log( LOG_LEVEL_DEBUG, "In proxy_update_item()"); item->nextcheck = calculate_item_nextcheck(item->itemid, item->type, item->delay, item->delay_flex, now); if (item->value_type == ITEM_VALUE_TYPE_LOG) { DBexecute("update items set nextcheck=%d,lastlogsize=%d where itemid=" ZBX_FS_UI64, item->nextcheck, item->lastlogsize, item->itemid); } else { DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64, item->nextcheck, item->itemid); } item->prevvalue_str = item->lastvalue_str; item->prevvalue_dbl = item->lastvalue_dbl; item->prevvalue_uint64 = item->lastvalue_uint64; item->prevvalue_null = item->lastvalue_null; item->lastvalue_uint64 = value->ui64; item->lastvalue_dbl = value->dbl; item->lastvalue_str = value->str; item->lastvalue_null = 0; if (item->status == ITEM_STATUS_NOTSUPPORTED) { zabbix_log( LOG_LEVEL_WARNING, "Parameter [%s] became supported by agent on host [%s]", item->key, item->host_name); zabbix_syslog("Parameter [%s] became supported by agent on host [%s]", item->key, item->host_name); item->status = ITEM_STATUS_ACTIVE; DBexecute("update items set status=%d where itemid=" ZBX_FS_UI64, ITEM_STATUS_ACTIVE, item->itemid); } /* Required for nodata() */ item->lastclock = now; zabbix_log( LOG_LEVEL_DEBUG, "End proxy_update_item()"); }
/****************************************************************************** * * * Function: process_proxy_heartbeat * * * * Purpose: process heartbeat sent by proxy servers * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_proxy_heartbeat(zbx_sock_t *sock, struct zbx_json_parse *jp) { zbx_uint64_t proxy_hostid; zabbix_log(LOG_LEVEL_DEBUG, "In process_proxy_heartbeat()"); if (FAIL == get_proxy_id(jp, &proxy_hostid)) return FAIL; update_proxy_lastaccess(proxy_hostid); if (send_result(sock, SUCCEED, NULL) != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } return SUCCEED; }
/****************************************************************************** * * * Function: do_ping * * * * Purpose: ping hosts listed in the host files * * * * Parameters: * * * * Return value: => 0 - successfully processed items * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: use external binary 'fping' to avoid superuser priviledges * * * ******************************************************************************/ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len) { int res; zabbix_log(LOG_LEVEL_DEBUG, "In do_ping(hosts_count:%d)", hosts_count); if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, error, max_error_len))) { zabbix_log(LOG_LEVEL_ERR, "%s", error); zabbix_syslog("%s", error); } zabbix_log(LOG_LEVEL_DEBUG, "End of do_ping():%s", zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: do_ping * * * * Purpose: ping hosts listed in the host files * * * * Parameters: * * * * Return value: SUCCEED - successfully processed hosts * * NOTSUPPORTED - otherwise * * * * Author: Alexei Vladishev * * * * Comments: use external binary 'fping' to avoid superuser privileges * * * ******************************************************************************/ int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { const char *__function_name = "do_ping"; int res; zabbix_log(LOG_LEVEL_DEBUG, "In %s() hosts_count:%d", __function_name, hosts_count); if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, count, interval, size, timeout, error, max_error_len))) { zabbix_log(LOG_LEVEL_ERR, "%s", error); zabbix_syslog("%s", error); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
static void add_object_msg(int source, zbx_uint64_t triggerid, DB_OPERATION *operation, ZBX_USER_MSG **user_msg, char *subject, char *message) { DB_RESULT result; DB_ROW row; zbx_uint64_t mediatypeid = 0, userid; result = DBselect("select mediatypeid from opmediatypes where operationid=" ZBX_FS_UI64, operation->operationid); if (NULL != (row = DBfetch(result))) ZBX_STR2UINT64(mediatypeid, row[0]); DBfree_result(result); switch (operation->object) { case OPERATION_OBJECT_USER: add_user_msg(source, operation->objectid, mediatypeid, triggerid, user_msg, subject, message); break; case OPERATION_OBJECT_GROUP: result = DBselect("select ug.userid from users_groups ug,usrgrp g" " WHERE ug.usrgrpid=" ZBX_FS_UI64 " AND g.usrgrpid=ug.usrgrpid AND g.users_status=%d", operation->objectid, GROUP_STATUS_ACTIVE); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(userid, row[0]); add_user_msg(source, userid, mediatypeid, triggerid, user_msg, subject, message); } DBfree_result(result); break; default: zabbix_log(LOG_LEVEL_WARNING, "Unknown object type [%d] for operationid [" ZBX_FS_UI64 "]", operation->object, operation->operationid); zabbix_syslog("Unknown object type [%d] for operationid [" ZBX_FS_UI64 "]", operation->object, operation->operationid); break; } }
static void deactivate_host(DC_ITEM *item, int now, const char *error) { char sql[MAX_STRING_LEN], *error_esc, error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (SUCCEED != DCconfig_deactivate_host(item, now)) return; DBbegin(); *error_msg = '\0'; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); /* First error */ if (0 == *errors_from) { zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: first network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *errors_from = now; *disable_until = now + CONFIG_UNREACHABLE_DELAY; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_errors_from, *errors_from); } else { if (now - *errors_from <= CONFIG_UNREACHABLE_PERIOD) { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: another network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *disable_until = now + CONFIG_UNREACHABLE_DELAY; } else { *disable_until = now + CONFIG_UNAVAILABLE_DELAY; if (HOST_AVAILABLE_FALSE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Disabling %s host [%s]", type, item->host.host); *available = HOST_AVAILABLE_FALSE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_AVAILABLE_FALSE, now); /* 2 */ update_triggers_status_to_unknown(item->host.hostid, item->type, now, "Agent is unavailable."); } error_esc = DBdyn_escape_string_len(error, HOST_ERROR_LEN); offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s='%s',", fld_error, error_esc); zbx_free(error_esc); } } offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d where hostid=" ZBX_FS_UI64, fld_disable_until, *disable_until, item->host.hostid); DBexecute("%s", sql); DBcommit(); if ('\0' != *error_msg) { zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); } }
/****************************************************************************** * * * Function: add_history * * * * Purpose: add new value to history * * * * Parameters: item - item data * * value - new value of the item * * now - new value of the item * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int add_history(DB_ITEM *item, AGENT_RESULT *value, int now) { int ret = FAIL; zbx_uint64_t value_uint64; double value_double; zabbix_log(LOG_LEVEL_DEBUG, "In add_history(key:%s,value_type:%X,type:%X)", item->key, item->value_type, value->type); if (value->type & AR_UINT64) zabbix_log(LOG_LEVEL_DEBUG, "In add_history(itemid:"ZBX_FS_UI64",UINT64:"ZBX_FS_UI64")", item->itemid, value->ui64); if (value->type & AR_STRING) zabbix_log(LOG_LEVEL_DEBUG, "In add_history(itemid:"ZBX_FS_UI64",STRING:%s)", item->itemid, value->str); if (value->type & AR_DOUBLE) zabbix_log(LOG_LEVEL_DEBUG, "In add_history(itemid:"ZBX_FS_UI64",DOUBLE:"ZBX_FS_DBL")", item->itemid, value->dbl); if (value->type & AR_TEXT) zabbix_log(LOG_LEVEL_DEBUG, "In add_history(itemid:"ZBX_FS_UI64",TEXT:[%s])", item->itemid, value->text); switch (item->value_type) { case ITEM_VALUE_TYPE_FLOAT: if (NULL == GET_DBL_RESULT(value)) break; switch (item->delta) { /* Should we store delta or original value? */ case ITEM_STORE_AS_IS: if (item->history > 0) DBadd_history(item->itemid, DBmultiply_value_float(item, value->dbl), now); ret = SUCCEED; break; case ITEM_STORE_SPEED_PER_SECOND: /* Delta as speed of change */ if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl && item->lastclock < now) { if (item->history > 0) { value_double = (value->dbl - item->prevorgvalue_dbl) / (now - item->lastclock); DBadd_history(item->itemid, DBmultiply_value_float(item, value_double), now); } ret = SUCCEED; } break; case ITEM_STORE_SIMPLE_CHANGE: /* Real delta: simple difference between values */ if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl) { if (item->history > 0) DBadd_history(item->itemid, DBmultiply_value_float(item, value->dbl - item->prevorgvalue_dbl), now); ret = SUCCEED; } break; default: zabbix_log(LOG_LEVEL_ERR, "Value not stored for itemid [" ZBX_FS_UI64 "]. Unknown delta [%d]", item->itemid, item->delta); zabbix_syslog("Value not stored for itemid [" ZBX_FS_UI64 "]. Unknown delta [%d]", item->itemid, item->delta); } break; case ITEM_VALUE_TYPE_UINT64: if (NULL == GET_UI64_RESULT(value)) break; switch (item->delta) { /* Should we store delta or original value? */ case ITEM_STORE_AS_IS: if (item->history > 0) DBadd_history_uint(item->itemid, DBmultiply_value_uint64(item, value->ui64), now); ret = SUCCEED; break; case ITEM_STORE_SPEED_PER_SECOND: /* Delta as speed of change */ if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64 && item->lastclock < now) { if (item->history > 0) { value_uint64 = (zbx_uint64_t)(value->ui64 - item->prevorgvalue_uint64) / (now - item->lastclock); DBadd_history_uint(item->itemid, DBmultiply_value_uint64(item, value_uint64), now); } ret = SUCCEED; } break; case ITEM_STORE_SIMPLE_CHANGE: /* Real delta: simple difference between values */ if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64) { if (item->history > 0) DBadd_history_uint(item->itemid, DBmultiply_value_uint64(item, value->ui64 - item->prevorgvalue_uint64), now); ret = SUCCEED; } break; default: zabbix_log(LOG_LEVEL_ERR, "Value not stored for itemid [" ZBX_FS_UI64 "]. Unknown delta [%d]", item->itemid, item->delta); zabbix_syslog("Value not stored for itemid [" ZBX_FS_UI64 "]. Unknown delta [%d]", item->itemid, item->delta); } break; case ITEM_VALUE_TYPE_STR: if (NULL == GET_STR_RESULT(value)) break; if (item->history > 0) DBadd_history_str(item->itemid, value->str, now); ret = SUCCEED; break; case ITEM_VALUE_TYPE_LOG: if (NULL == GET_STR_RESULT(value)) break; if (item->history > 0) DBadd_history_log(item->itemid, value->str, now, item->timestamp, item->eventlog_source, item->eventlog_severity, item->lastlogsize); ret = SUCCEED; break; case ITEM_VALUE_TYPE_TEXT: if (NULL == GET_TEXT_RESULT(value)) break; if (item->history > 0) DBadd_history_text(item->itemid,value->text,now); ret = SUCCEED; break; default: zabbix_log(LOG_LEVEL_ERR, "Unknown value type [%d] for itemid [" ZBX_FS_UI64 "]", item->value_type, item->itemid); zabbix_syslog("Unknown value type [%d] for itemid [" ZBX_FS_UI64 "]", item->value_type, item->itemid); } zabbix_log(LOG_LEVEL_DEBUG, "End of add_history():%s", zbx_result_string(ret)); return ret; }
static int process_trap(zbx_sock_t *sock, char *s, int max_len) { char *server,*key,*value_string, *data; char copy[MAX_STRING_LEN]; char host_dec[MAX_STRING_LEN],key_dec[MAX_STRING_LEN],value_dec[MAX_STRING_LEN]; char lastlogsize[MAX_STRING_LEN]; char timestamp[MAX_STRING_LEN]; char source[MAX_STRING_LEN]; char severity[MAX_STRING_LEN]; int sender_nodeid, nodeid; char *answer; int ret=SUCCEED, res; size_t datalen; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; AGENT_VALUE av; zbx_rtrim(s, " \r\n\0"); datalen = strlen(s); zabbix_log( LOG_LEVEL_DEBUG, "Trapper got [%s] len %zd", s, datalen); if (0 == strncmp(s,"ZBX_GET_ACTIVE_CHECKS", 21)) /* Request for list of active checks */ { ret = send_list_of_active_checks(sock, s); /* Request for last ids */ } else if (strncmp(s,"ZBX_GET_HISTORY_LAST_ID", 23) == 0) { send_history_last_id(sock, s); return ret; } else if (strncmp(s,"ZBX_GET_TRENDS_LAST_ID", 22) == 0) { send_trends_last_id(sock, s); return ret; /* Process information sent by zabbix_sender */ } else { /* Command? */ if(strncmp(s,"Command",7) == 0) { node_process_command(sock, s); return ret; } /* Node data exchange? */ if(strncmp(s,"Data",4) == 0) { node_sync_lock(0); /* zabbix_log( LOG_LEVEL_WARNING, "Node data received [len:%d]", strlen(s)); */ res = node_sync(s, &sender_nodeid, &nodeid); if (FAIL == res) send_data_to_node(sender_nodeid, sock, "FAIL"); else { res = calculate_checksums(nodeid, NULL, 0); if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE))) { res = send_data_to_node(sender_nodeid, sock, data); zbx_free(data); if (SUCCEED == res) res = recv_data_from_node(sender_nodeid, sock, &answer); if (SUCCEED == res && 0 == strcmp(answer, "OK")) res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL); } } node_sync_unlock(0); return ret; } /* Slave node history ? */ if(strncmp(s,"History",7) == 0) { /* zabbix_log( LOG_LEVEL_WARNING, "Slave node history received [len:%d]", strlen(s)); */ if (node_history(s, datalen) == SUCCEED) { if (zbx_tcp_send_raw(sock,"OK") != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending confirmation to node"); zabbix_syslog("Trapper: error sending confirmation to node"); } } return ret; } /* JSON protocol? */ else if (SUCCEED == zbx_json_open(s, &jp)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) { if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG) && zbx_process == ZBX_PROCESS_SERVER) { send_proxyconfig(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) || 0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA)) { ret = process_new_values(sock, &jp, 0); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_proxy_values(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_discovery_data(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT) && zbx_process == ZBX_PROCESS_SERVER) { ret = process_proxy_heartbeat(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS)) { ret = send_list_of_active_checks_json(sock, &jp); } else { zabbix_log( LOG_LEVEL_WARNING, "Unknown request received [%s]", value); } } return ret; } /* New XML protocol? */ else if(s[0]=='<') { zabbix_log( LOG_LEVEL_DEBUG, "XML received [%s]", s); comms_parse_response(s,host_dec,key_dec,value_dec,lastlogsize,timestamp,source,severity,sizeof(host_dec)-1); server=host_dec; value_string=value_dec; key=key_dec; } else { strscpy(copy,s); server=(char *)strtok(s,":"); if(NULL == server) { return FAIL; } key=(char *)strtok(NULL,":"); if(NULL == key) { return FAIL; } value_string=strchr(copy,':'); value_string=strchr(value_string+1,':'); if(NULL == value_string) { return FAIL; } /* It points to ':', so have to increment */ value_string++; lastlogsize[0]=0; timestamp[0]=0; source[0]=0; severity[0]=0; } zabbix_log( LOG_LEVEL_DEBUG, "Value [%s]", value_string); av.clock = time(NULL); zbx_strlcpy(av.host_name, server, sizeof(av.host_name)); zbx_strlcpy(av.key, key, sizeof(av.key)); av.value = value_string; av.lastlogsize = atoi(lastlogsize); av.timestamp = atoi(timestamp); av.source = source; av.severity = atoi(severity); process_mass_data(sock, 0, &av, 1, NULL, 0); if( zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK") != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } zabbix_log( LOG_LEVEL_DEBUG, "After write()"); } return ret; }
/****************************************************************************** * * * Function: process_data * * * * Purpose: process new item value * * * * Parameters: sockfd - descriptor of agent-server socket connection * * server - server name * * key - item's key * * value - new value of server:key * * lastlogsize - if key=log[*], last size of log file * * * * Return value: SUCCEED - new value processed sucesfully * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: for trapper server process * * * ******************************************************************************/ static void process_mass_data(zbx_sock_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALUE *values, int value_num, int *processed, time_t proxy_timediff) { AGENT_RESULT agent; DB_RESULT result; DB_ROW row; DB_ITEM item; char host_esc[MAX_STRING_LEN], key_esc[MAX_STRING_LEN]; static char *sql = NULL; static int sql_allocated = 65536; int sql_offset = 0, i; zabbix_log(LOG_LEVEL_DEBUG, "In process_mass_data()"); if (NULL == sql) sql = zbx_malloc(sql, sql_allocated); DCinit_nextchecks(); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 2048, "select %s where h.hostid=i.hostid and h.proxy_hostid=" ZBX_FS_UI64 " and h.status=%d and i.status in (%d,%d)", ZBX_SQL_ITEM_SELECT, proxy_hostid, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); if (proxy_hostid == 0) { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d)", ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE); } else { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_TRAPPER, ITEM_TYPE_SIMPLE, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_HTTPTEST, ITEM_TYPE_EXTERNAL, ITEM_TYPE_IPMI); } zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, " and ("); for (i = 0; i < value_num; i++) { DBescape_string(values[i].host_name, host_esc, sizeof(host_esc)); DBescape_string(values[i].key, key_esc, sizeof(key_esc)); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 512, "(h.host='%s' and i.key_='%s') or ", host_esc, key_esc); } sql_offset -= 4; zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); if (item.type == ITEM_TYPE_ZABBIX_ACTIVE && FAIL == zbx_tcp_check_security(sock, item.trapper_hosts, 1)) continue; if (item.maintenance_status == HOST_MAINTENANCE_STATUS_ON && item.maintenance_type == MAINTENANCE_TYPE_NODATA && item.maintenance_from <= values[i].clock) continue; for (i = 0; i < value_num; i++) { if (0 == strcmp(item.host_name, values[i].host_name) && 0 == strcmp(item.key_orig, values[i].key)) { /* zabbix_log(LOG_LEVEL_DEBUG, "Processing [%s@%s: \"%s\"]", item.key, item.host_name, values[i].value);*/ if (0 == strcmp(values[i].value, "ZBX_NOTSUPPORTED")) { zabbix_log(LOG_LEVEL_WARNING, "Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); zabbix_syslog("Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); DCadd_nextcheck(&item, values[i].clock, proxy_timediff, "Not supported by ZABBIX agent"); if (NULL != processed) (*processed)++; } else { if (0 == strncmp(item.key, "log[", 4) || 0 == strncmp(item.key, "eventlog[", 9)) { item.lastlogsize = values[i].lastlogsize; item.timestamp = values[i].timestamp; calc_timestamp(values[i].value, &item.timestamp, item.logtimefmt); item.eventlog_severity = values[i].severity; item.eventlog_source = values[i].source; /* zabbix_log(LOG_LEVEL_DEBUG, "Value [%s] Lastlogsize [%s] Timestamp [%s]", values[i].value, item.lastlogsize, item.timestamp);*/ } init_result(&agent); if (SUCCEED == set_result_type(&agent, item.value_type, item.data_type, values[i].value)) { if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, values[i].clock); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, values[i].clock); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (NULL != processed) (*processed)++; /* only for screen Administration|Queue */ if (item.type != ITEM_TYPE_TRAPPER && item.type != ITEM_TYPE_HTTPTEST && item.value_type != ITEM_VALUE_TYPE_LOG && 0 != strcmp(item.key, SERVER_STATUS_KEY) && 0 != strcmp(item.key, SERVER_ICMPPING_KEY) && 0 != strcmp(item.key, SERVER_ICMPPINGSEC_KEY) && 0 != strcmp(item.key, SERVER_ZABBIXLOG_KEY)) DCadd_nextcheck(&item, values[i].clock, proxy_timediff, NULL); } else { if (GET_MSG_RESULT(&agent)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(&item), agent.msg); } free_result(&agent); } } } } DBfree_result(result); DCflush_nextchecks(); }
/****************************************************************************** * * * Function: process_new_values * * * * Purpose: process values sent by active agents and senders * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_new_values(zbx_sock_t *sock, struct zbx_json_parse *jp, const zbx_uint64_t proxy_hostid) { struct zbx_json_parse jp_data, jp_row; const char *p; char info[MAX_STRING_LEN], tmp[MAX_STRING_LEN]; int ret = SUCCEED; int processed = 0; double sec; time_t now, proxy_timediff = 0; #define VALUES_MAX 256 static AGENT_VALUE *values = NULL, *av; int value_num = 0; zabbix_log(LOG_LEVEL_DEBUG, "In process_new_values()"); now = time(NULL); sec = zbx_time(); if (NULL == values) values = zbx_malloc(values, VALUES_MAX * sizeof(AGENT_VALUE)); if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_CLOCK, tmp, sizeof(tmp))) proxy_timediff = now - atoi(tmp); /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^ */ if (NULL == (p = zbx_json_pair_by_name(jp, ZBX_PROTO_TAG_DATA))) { zabbix_log(LOG_LEVEL_WARNING, "Can't find \"data\" pair"); ret = FAIL; } if(SUCCEED == ret) { /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------------------^ */ if (FAIL == (ret = zbx_json_brackets_open(p, &jp_data))) zabbix_log(LOG_LEVEL_WARNING, "Can't proceed jason request. %s", zbx_json_strerror()); } /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^ */ p = NULL; while (SUCCEED == ret && NULL != (p = zbx_json_next(&jp_data, p))) { /* {"request":"ZBX_SENDER_DATA","data":[{"key":"system.cpu.num",...,...},{...},...]} * ^------------------------------^ */ if (FAIL == (ret = zbx_json_brackets_open(p, &jp_row))) break; /* zabbix_log(LOG_LEVEL_DEBUG, "Next \"%.*s\"", jp_row.end - jp_row.start + 1, jp_row.start);*/ av = &values[value_num]; memset(av, 0, sizeof(AGENT_VALUE)); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_CLOCK, tmp, sizeof(tmp))) av->clock = atoi(tmp) + proxy_timediff; else av->clock = now; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_HOST, av->host_name, sizeof(av->host_name))) continue; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_KEY, av->key, sizeof(av->key))) continue; if (FAIL == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_VALUE, tmp, sizeof(tmp))) continue; av->value = strdup(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGLASTSIZE, tmp, sizeof(tmp))) av->lastlogsize = atoi(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGTIMESTAMP, tmp, sizeof(tmp))) av->timestamp = atoi(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGSOURCE, tmp, sizeof(tmp))) av->source = strdup(tmp); if (SUCCEED == zbx_json_value_by_name(&jp_row, ZBX_PROTO_TAG_LOGSEVERITY, tmp, sizeof(tmp))) av->severity = atoi(tmp); value_num ++; if (value_num == VALUES_MAX) { process_mass_data(sock, proxy_hostid, values, value_num, &processed, proxy_timediff); clean_agent_values(values, value_num); value_num = 0; } } if (value_num > 0) process_mass_data(sock, proxy_hostid, values, value_num, &processed, proxy_timediff); clean_agent_values(values, value_num); zbx_snprintf(info, sizeof(info), "Processed %d Failed %d Total %d Seconds spent " ZBX_FS_DBL, processed, value_num - processed, value_num, zbx_time() - sec); if (send_result(sock, ret, info) != SUCCEED) { zabbix_log( LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } return ret; }
/****************************************************************************** * * * Function: update_item * * * * Purpose: update item info after new value is received * * * * Parameters: item - item data * * value - new value of the item * * now - current timestamp * * * * Author: Alexei Vladishev, Eugene Grigorjev * * * * Comments: * * * ******************************************************************************/ static void update_item(DB_ITEM *item, AGENT_RESULT *value, time_t now) { char *value_esc; zbx_uint64_t value_uint64; double value_double; zabbix_log(LOG_LEVEL_DEBUG, "In update_item()"); item->nextcheck = calculate_item_nextcheck(item->itemid, item->type, item->delay, item->delay_flex, now); switch (item->value_type) { case ITEM_VALUE_TYPE_FLOAT: if (NULL == GET_DBL_RESULT(value)) break; switch (item->delta) { /* Should we store delta or original value? */ case ITEM_STORE_AS_IS: value_double = DBmultiply_value_float(item, value->dbl); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue=NULL," "lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value_double, (int)now, item->itemid); SET_DBL_RESULT(value, value_double); break; case ITEM_STORE_SPEED_PER_SECOND: /* Delta as speed of change */ if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl) { /* In order to continue normal processing, we assume difference 1 second Otherwise function update_functions and update_triggers won't work correctly*/ if (now != item->lastclock) value_double = (value->dbl - item->prevorgvalue_dbl) / (now - item->lastclock); else value_double = value->dbl - item->prevorgvalue_dbl; value_double = DBmultiply_value_float(item, value_double); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_DBL "'," "lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->dbl, value_double, (int)now, item->itemid); SET_DBL_RESULT(value, value_double); } else { DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->dbl, (int)now, item->itemid); } break; case ITEM_STORE_SIMPLE_CHANGE: /* Real delta: simple difference between values */ if (0 == item->prevorgvalue_null && item->prevorgvalue_dbl <= value->dbl) { value_double = DBmultiply_value_float(item, value->dbl - item->prevorgvalue_dbl); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_DBL "'," "lastvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->dbl, value_double, (int)now, item->itemid); SET_DBL_RESULT(value, value_double); } else { DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_DBL "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->dbl, (int)now, item->itemid); } break; } break; case ITEM_VALUE_TYPE_UINT64: if (NULL == GET_UI64_RESULT(value)) break; switch (item->delta) { /* Should we store delta or original value? */ case ITEM_STORE_AS_IS: value_uint64 = DBmultiply_value_uint64(item, value->ui64); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue=NULL," "lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value_uint64, (int)now, item->itemid); SET_UI64_RESULT(value, value_uint64); break; case ITEM_STORE_SPEED_PER_SECOND: /* Delta as speed of change */ if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64) { if (now != item->lastclock) value_uint64 = (zbx_uint64_t)(value->ui64 - item->prevorgvalue_uint64) / (now - item->lastclock); else value_uint64 = value->ui64 - item->prevorgvalue_uint64; value_uint64 = DBmultiply_value_uint64(item, value_uint64); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_UI64 "'," "lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->ui64, value_uint64, (int)now, item->itemid); SET_UI64_RESULT(value, value_uint64); } else { DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->ui64, (int)now, item->itemid); } break; case ITEM_STORE_SIMPLE_CHANGE: /* Real delta: simple difference between values */ if (0 == item->prevorgvalue_null && item->prevorgvalue_uint64 <= value->ui64) { value_uint64 = DBmultiply_value_uint64(item, value->ui64 - item->prevorgvalue_uint64); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,prevorgvalue='" ZBX_FS_UI64 "'," "lastvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->ui64, value_uint64, (int)now, item->itemid); SET_UI64_RESULT(value, value_uint64); } else { DBexecute("update items set nextcheck=%d,prevorgvalue='" ZBX_FS_UI64 "',lastclock=%d where itemid=" ZBX_FS_UI64, item->nextcheck, value->ui64, (int)now, item->itemid); } break; } break; case ITEM_VALUE_TYPE_STR: case ITEM_VALUE_TYPE_TEXT: if (NULL == GET_STR_RESULT(value)) break; value_esc = DBdyn_escape_string_len(value->str, ITEM_LASTVALUE_LEN); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,lastvalue='%s',lastclock=%d" " where itemid=" ZBX_FS_UI64, item->nextcheck, value_esc, (int)now, item->itemid); zbx_free(value_esc); break; case ITEM_VALUE_TYPE_LOG: if (NULL == GET_STR_RESULT(value)) break; value_esc = DBdyn_escape_string_len(value->str, ITEM_LASTVALUE_LEN); DBexecute("update items set nextcheck=%d,prevvalue=lastvalue,lastvalue='%s',lastclock=%d,lastlogsize=%d" " where itemid=" ZBX_FS_UI64, item->nextcheck, value_esc, (int)now, item->lastlogsize, item->itemid); zbx_free(value_esc); break; } item->prevvalue_str = item->lastvalue_str; item->prevvalue_dbl = item->lastvalue_dbl; item->prevvalue_uint64 = item->lastvalue_uint64; item->prevvalue_null = item->lastvalue_null; item->lastvalue_uint64 = value->ui64; item->lastvalue_dbl = value->dbl; item->lastvalue_str = value->str; item->lastvalue_null = 0; /* Required for nodata() */ item->lastclock = now; /* Update item status if required */ if (item->status == ITEM_STATUS_NOTSUPPORTED) { zabbix_log( LOG_LEVEL_WARNING, "Parameter [%s] became supported by agent on host [%s]", item->key, item->host_name); zabbix_syslog("Parameter [%s] became supported by agent on host [%s]", item->key, item->host_name); item->status = ITEM_STATUS_ACTIVE; DBexecute("update items set status=%d,error='' where itemid=" ZBX_FS_UI64, item->status, item->itemid); } zabbix_log(LOG_LEVEL_DEBUG, "End of update_item()"); }
int get_value(DB_ITEM *item, AGENT_RESULT *result) { int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In get_value(key:%s)", item->key); switch (item->type) { case ITEM_TYPE_ZABBIX: alarm(CONFIG_TIMEOUT); res = get_value_agent(item, result); alarm(0); if (SUCCEED != res && GET_MSG_RESULT(result)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(item), result->msg); break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: #ifdef HAVE_SNMP alarm(CONFIG_TIMEOUT); res = get_value_snmp(item, result); alarm(0); #else SET_MSG_RESULT(result, strdup("Support of SNMP parameters was not compiled in")); res = NOTSUPPORTED; #endif if (SUCCEED != res && GET_MSG_RESULT(result)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(item), result->msg); break; case ITEM_TYPE_IPMI: #ifdef HAVE_OPENIPMI res = get_value_ipmi(item, result); #else SET_MSG_RESULT(result, strdup("Support of IPMI parameters was not compiled in")); res = NOTSUPPORTED; #endif break; case ITEM_TYPE_SIMPLE: alarm(CONFIG_TIMEOUT); res = get_value_simple(item, result); alarm(0); break; case ITEM_TYPE_INTERNAL: alarm(CONFIG_TIMEOUT); res = get_value_internal(item, result); alarm(0); break; case ITEM_TYPE_DB_MONITOR: alarm(CONFIG_TIMEOUT); res = get_value_db(item, result); alarm(0); if (SUCCEED != res && GET_MSG_RESULT(result)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(item), result->msg); break; case ITEM_TYPE_AGGREGATE: alarm(CONFIG_TIMEOUT); res = get_value_aggregate(item, result); alarm(0); break; case ITEM_TYPE_EXTERNAL: alarm(CONFIG_TIMEOUT); res = get_value_external(item, result); alarm(0); if (SUCCEED != res && GET_MSG_RESULT(result)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(item), result->msg); break; default: zabbix_log(LOG_LEVEL_WARNING, "Not supported item type:%d", item->type); zabbix_syslog("Not supported item type:%d", item->type); res = NOTSUPPORTED; } zabbix_log(LOG_LEVEL_DEBUG, "End get_value()"); return res; }
/****************************************************************************** * * * Function: execute_action * * * * Purpose: execute an action depending on mediatype * * * * Parameters: alert - alert details * * mediatype - media details * * * * Return value: SUCCESS - action executed sucessfully * * FAIL - otherwise, error will contain error message * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int execute_action(DB_ALERT *alert,DB_MEDIATYPE *mediatype, char *error, int max_error_len) { int res=FAIL; int pid; char full_path[MAX_STRING_LEN]; char env_alertid[128],env_actionid[128],env_clock[128],env_mediatypeid[128], env_status[128]; char *zbxenv[] = { (char *)&env_alertid, (char *)&env_actionid, (char *)&env_clock, (char *)&env_mediatypeid, (char *)&env_status, (char *)0 }; zabbix_log( LOG_LEVEL_DEBUG, "In execute_action(%s)", mediatype->smtp_server); if(mediatype->type==MEDIA_TYPE_EMAIL) { alarm(40); res = send_email(mediatype->smtp_server,mediatype->smtp_helo,mediatype->smtp_email,alert->sendto,alert->subject, alert->message, error, max_error_len); alarm(0); } #if defined (HAVE_JABBER) else if(mediatype->type==MEDIA_TYPE_JABBER) { /* Jabber uses its own timeouts */ res = send_jabber(mediatype->username, mediatype->passwd, alert->sendto, alert->subject, alert->message, error, max_error_len); } #endif /* HAVE_JABBER */ else if(mediatype->type==MEDIA_TYPE_SMS) { /* SMS uses its own timeouts */ res = send_sms(mediatype->gsm_modem,alert->sendto,alert->message, error, max_error_len); } else if(mediatype->type==MEDIA_TYPE_EXEC) { /* if(-1 == execl(CONFIG_ALERT_SCRIPTS_PATH,mediatype->exec_path,alert->sendto,alert->subject,alert->message))*/ zabbix_log( LOG_LEVEL_DEBUG, "Before execl([%s],[%s])", CONFIG_ALERT_SCRIPTS_PATH, mediatype->exec_path); /* if(-1 == execl("/home/zabbix/bin/lmt.sh","lmt.sh",alert->sendto,alert->subject,alert->message,(char *)0))*/ pid = zbx_fork(); if(0 != pid) { waitpid(pid,NULL,0); } else { strscpy(full_path,CONFIG_ALERT_SCRIPTS_PATH); zbx_strlcat(full_path,"/",MAX_STRING_LEN); zbx_strlcat(full_path,mediatype->exec_path,MAX_STRING_LEN); ltrim_spaces(full_path); zabbix_log( LOG_LEVEL_DEBUG, "Before executing [%s]", full_path); zbx_snprintf(env_alertid,127,"ZABBIX_ALERT_ID=%d", alert->alertid); zbx_snprintf(env_actionid,127,"ZABBIX_ACTION_ID=%d", alert->actionid); zbx_snprintf(env_clock,127,"ZABBIX_ALERT_TIME=%d", alert->clock); zbx_snprintf(env_mediatypeid,127,"ZABBIX_ALERT_MEDIATYPEID=%d", alert->mediatypeid); zbx_snprintf(env_status,127,"ZABBIX_ALERT_STATUS=%d", alert->status); /* if(-1 == execl(full_path,mediatype->exec_path,alert->sendto,alert->subject,alert->message,(char *)0))*/ if(-1 == execle(full_path,mediatype->exec_path,alert->sendto,alert->subject,alert->message,(char *)0, zbxenv)) { zabbix_log( LOG_LEVEL_ERR, "Error executing [%s] [%s]", full_path, strerror(errno)); zabbix_syslog("Error executing [%s] [%s]", full_path, strerror(errno)); zbx_snprintf(error,max_error_len,"Error executing [%s] [%s]", full_path, strerror(errno)); res = FAIL; } else { res = SUCCEED; } /* In normal case the program will never reach this point */ zabbix_log( LOG_LEVEL_DEBUG, "After execl()"); exit(0); } res = SUCCEED; } else { zabbix_log( LOG_LEVEL_ERR, "Unsupported media type [%d] for alert ID [%d]", mediatype->type, alert->alertid); zabbix_syslog("Unsupported media type [%d] for alert ID [%d]", mediatype->type, alert->alertid); zbx_snprintf(error,max_error_len,"Unsupported media type [%d]", mediatype->type); res=FAIL; } zabbix_log( LOG_LEVEL_DEBUG, "End execute_action()"); return res; }
/****************************************************************************** * * * Function: main_alerter_loop * * * * Purpose: periodically check table alerts and send notifications if needed * * * * Author: Alexei Vladishev * * * ******************************************************************************/ void main_alerter_loop() { char error[MAX_STRING_LEN], *error_esc; int res; DB_RESULT result; DB_ROW row; DB_ALERT alert; DB_MEDIATYPE mediatype; zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [sending alerts]", get_process_type_string(process_type)); result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid" ",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path" ",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt" " where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE " order by a.clock", ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, DBnode_local("mt.mediatypeid")); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(alert.alertid, row[0]); alert.mediatypeid = atoi(row[1]); alert.sendto = row[2]; alert.subject = row[3]; alert.message = row[4]; alert.status = atoi(row[5]); ZBX_STR2UINT64(mediatype.mediatypeid, row[6]); mediatype.type = atoi(row[7]); mediatype.description = row[8]; mediatype.smtp_server = row[9]; mediatype.smtp_helo = row[10]; mediatype.smtp_email = row[11]; mediatype.exec_path = row[12]; mediatype.gsm_modem = row[13]; mediatype.username = row[14]; mediatype.passwd = row[15]; alert.retries = atoi(row[16]); *error = '\0'; res = execute_action(&alert, &mediatype, error, sizeof(error)); if (SUCCEED == res) { zabbix_log(LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully", alert.alertid); DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64, ALERT_STATUS_SENT, alert.alertid); } else { zabbix_log(LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN); alert.retries++; if (ALERT_MAX_RETRIES > alert.retries) { DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64, alert.retries, error_esc, alert.alertid); } else { DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64, ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid); } zbx_free(error_esc); } } DBfree_result(result); zbx_sleep_loop(CONFIG_SENDER_FREQUENCY); } }
/****************************************************************************** * * * Function: execute_action * * * * Purpose: execute an action depending on mediatype * * * * Parameters: alert - alert details * * mediatype - media details * * * * Return value: SUCCESS - action executed sucessfully * * FAIL - otherwise, error will contain error message * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int execute_action(DB_ALERT *alert, DB_MEDIATYPE *mediatype, char *error, int max_error_len) { const char *__function_name = "execute_action"; int pid, res = FAIL; char full_path[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s(): alertid [" ZBX_FS_UI64 "] mediatype [%d]", __function_name, alert->alertid, mediatype->type); if (MEDIA_TYPE_EMAIL == mediatype->type) { alarm(40); res = send_email(mediatype->smtp_server, mediatype->smtp_helo, mediatype->smtp_email, alert->sendto, alert->subject, alert->message, error, max_error_len); alarm(0); } #if defined(HAVE_JABBER) else if (MEDIA_TYPE_JABBER == mediatype->type) { /* Jabber uses its own timeouts */ res = send_jabber(mediatype->username, mediatype->passwd, alert->sendto, alert->subject, alert->message, error, max_error_len); } #endif else if (MEDIA_TYPE_SMS == mediatype->type) { /* SMS uses its own timeouts */ res = send_sms(mediatype->gsm_modem, alert->sendto, alert->message, error, max_error_len); } else if (MEDIA_TYPE_EZ_TEXTING == mediatype->type) { /* Ez Texting uses its own timeouts */ res = send_ez_texting(mediatype->username, mediatype->passwd, alert->sendto, alert->message, mediatype->exec_path, error, max_error_len); } else if (MEDIA_TYPE_EXEC == mediatype->type) { pid = zbx_fork(); if (0 != pid) { waitpid(pid, NULL, 0); res = SUCCEED; } else { zbx_snprintf(full_path, sizeof(full_path), "%s/%s", CONFIG_ALERT_SCRIPTS_PATH, mediatype->exec_path); zabbix_log(LOG_LEVEL_DEBUG, "Before executing [%s]", full_path); if (-1 == execl(full_path, mediatype->exec_path, alert->sendto, alert->subject, alert->message, (char *)NULL)) { zabbix_log(LOG_LEVEL_ERR, "Error executing [%s] [%s]", full_path, strerror(errno)); zabbix_syslog("Error executing [%s] [%s]", full_path, strerror(errno)); exit(FAIL); } else THIS_SHOULD_NEVER_HAPPEN; } } else { zabbix_log(LOG_LEVEL_ERR, "Unsupported media type [%d] for alert ID [" ZBX_FS_UI64 "]", mediatype->type, alert->alertid); zabbix_syslog("Unsupported media type [%d] for alert ID [" ZBX_FS_UI64 "]", mediatype->type, alert->alertid); zbx_snprintf(error, max_error_len, "Unsupported media type [%d]", mediatype->type); res = FAIL; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s(): %d", __function_name, zbx_result_string(res)); return res; }
static void activate_host(DC_ITEM *item, int now) { char sql[MAX_STRING_LEN], error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (0 == *errors_from && HOST_AVAILABLE_TRUE == *available) return; if (SUCCEED != DCconfig_activate_host(item)) return; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); if (HOST_AVAILABLE_TRUE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Enabling %s host [%s]", type, item->host.host); zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); *available = HOST_AVAILABLE_TRUE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_STATUS_MONITORED, now); /* 0 */ } *errors_from = 0; *disable_until = 0; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,%s=%d,%s='' where hostid=" ZBX_FS_UI64, fld_errors_from, *errors_from, fld_disable_until, *disable_until, fld_error, item->host.hostid); DBbegin(); DBexecute("%s", sql); DBcommit(); }
/****************************************************************************** * * * Function: execute_action * * * * Purpose: execute an action depending on mediatype * * * * Parameters: alert - alert details * * mediatype - media details * * * * Return value: SUCCESS - action executed sucessfully * * FAIL - otherwise, error will contain error message * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int execute_action(DB_ALERT *alert, DB_MEDIATYPE *mediatype, char *error, int max_error_len) { const char *__function_name = "execute_action"; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s(): alertid [" ZBX_FS_UI64 "] mediatype [%d]", __function_name, alert->alertid, mediatype->type); if (MEDIA_TYPE_EMAIL == mediatype->type) { alarm(ALARM_ACTION_TIMEOUT); res = send_email(mediatype->smtp_server, mediatype->smtp_helo, mediatype->smtp_email, alert->sendto, alert->subject, alert->message, error, max_error_len); alarm(0); } #ifdef HAVE_JABBER else if (MEDIA_TYPE_JABBER == mediatype->type) { /* Jabber uses its own timeouts */ res = send_jabber(mediatype->username, mediatype->passwd, alert->sendto, alert->subject, alert->message, error, max_error_len); } #endif else if (MEDIA_TYPE_SMS == mediatype->type) { /* SMS uses its own timeouts */ res = send_sms(mediatype->gsm_modem, alert->sendto, alert->message, error, max_error_len); } else if (MEDIA_TYPE_EZ_TEXTING == mediatype->type) { /* Ez Texting uses its own timeouts */ res = send_ez_texting(mediatype->username, mediatype->passwd, alert->sendto, alert->message, mediatype->exec_path, error, max_error_len); } else if (MEDIA_TYPE_EXEC == mediatype->type) { char full_path[MAX_STRING_LEN], *send_to, *subject, *message, *output = NULL; send_to = zbx_dyn_escape_string(alert->sendto, "\"\\"); subject = zbx_dyn_escape_string(alert->subject, "\"\\"); message = zbx_dyn_escape_string(alert->message, "\"\\"); zbx_snprintf(full_path, sizeof(full_path), "%s/%s \"%s\" \"%s\" \"%s\"", CONFIG_ALERT_SCRIPTS_PATH, mediatype->exec_path, send_to, subject, message); zbx_free(send_to); zbx_free(subject); zbx_free(message); if (SUCCEED == (res = zbx_execute(full_path, &output, error, max_error_len, ALARM_ACTION_TIMEOUT))) { zabbix_log(LOG_LEVEL_DEBUG, "%s output:\n%s", mediatype->exec_path, output); zbx_free(output); } else res = FAIL; } else { zbx_snprintf(error, max_error_len, "unsupported media type [%d]", mediatype->type); zabbix_log(LOG_LEVEL_ERR, "alert ID [" ZBX_FS_UI64 "]: %s", alert->alertid, error); zabbix_syslog("alert ID [" ZBX_FS_UI64 "]: %s", alert->alertid, error); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
static int process_trap(zbx_sock_t *sock, char *s, int max_len) { char *pl, *pr, *data, value_dec[MAX_BUFFER_LEN]; char lastlogsize[11], timestamp[11], source[HISTORY_LOG_SOURCE_LEN_MAX], severity[11]; int sender_nodeid, nodeid; char *answer; int ret = SUCCEED, res; size_t datalen; struct zbx_json_parse jp; char value[MAX_STRING_LEN]; AGENT_VALUE av; memset(&av, 0, sizeof(AGENT_VALUE)); zbx_rtrim(s, " \r\n"); datalen = strlen(s); zabbix_log(LOG_LEVEL_DEBUG, "Trapper got [%s] len " ZBX_FS_SIZE_T, s, (zbx_fs_size_t)datalen); if (0 == strncmp(s, "ZBX_GET_ACTIVE_CHECKS", 21)) /* Request for list of active checks */ { ret = send_list_of_active_checks(sock, s); } else if (strncmp(s, "ZBX_GET_HISTORY_LAST_ID", 23) == 0) /* Request for last ids */ { send_history_last_id(sock, s); return ret; } else /* Process information sent by zabbix_sender */ { /* Node data exchange? */ if (strncmp(s, "Data", 4) == 0) { node_sync_lock(0); res = node_sync(s, &sender_nodeid, &nodeid); if (FAIL == res) { alarm(CONFIG_TIMEOUT); send_data_to_node(sender_nodeid, sock, "FAIL"); alarm(0); } else { res = calculate_checksums(nodeid, NULL, 0); if (SUCCEED == res && NULL != (data = get_config_data(nodeid, ZBX_NODE_SLAVE))) { zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Sending configuration changes" " to slave node %d for node %d datalen " ZBX_FS_SIZE_T, CONFIG_NODEID, sender_nodeid, nodeid, (zbx_fs_size_t)strlen(data)); alarm(CONFIG_TRAPPER_TIMEOUT); res = send_data_to_node(sender_nodeid, sock, data); zbx_free(data); if (SUCCEED == res) res = recv_data_from_node(sender_nodeid, sock, &answer); if (SUCCEED == res && 0 == strcmp(answer, "OK")) res = update_checksums(nodeid, ZBX_NODE_SLAVE, SUCCEED, NULL, 0, NULL); alarm(0); } } node_sync_unlock(0); return ret; } /* Slave node history ? */ if (strncmp(s, "History", 7) == 0) { const char *reply; reply = (SUCCEED == node_history(s, datalen) ? "OK" : "FAIL"); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, reply)) { zabbix_log(LOG_LEVEL_WARNING, "Error sending %s to node", reply); zabbix_syslog("Trapper: error sending %s to node", reply); } alarm(0); return ret; } /* JSON protocol? */ else if (SUCCEED == zbx_json_open(s, &jp)) { if (SUCCEED == zbx_json_value_by_name(&jp, ZBX_PROTO_TAG_REQUEST, value, sizeof(value))) { if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_CONFIG)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) send_proxyconfig(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "Received configuration data from server." " Datalen " ZBX_FS_SIZE_T, (zbx_fs_size_t)datalen); recv_proxyconfig(sock, &jp); } } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AGENT_DATA) || 0 == strcmp(value, ZBX_PROTO_VALUE_SENDER_DATA)) { recv_agenthistory(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HISTORY_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_proxyhistory(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_proxyhistory(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_DISCOVERY_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_discovery_data(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_discovery_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_areg_data(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_areg_data(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_PROXY_HEARTBEAT)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_proxy_heartbeat(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_GET_ACTIVE_CHECKS)) { ret = send_list_of_active_checks_json(sock, &jp); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_HOST_AVAILABILITY)) { if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) recv_host_availability(sock, &jp); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) send_host_availability(sock); } else if (0 == strcmp(value, ZBX_PROTO_VALUE_COMMAND)) { ret = node_process_command(sock, s, &jp); } else { zabbix_log(LOG_LEVEL_WARNING, "Unknown request received [%s]", value); } } return ret; } /* XML protocol? */ else if (*s == '<') { comms_parse_response(s, av.host_name, sizeof(av.host_name), av.key, sizeof(av.key), value_dec, sizeof(value_dec), lastlogsize, sizeof(lastlogsize), timestamp, sizeof(timestamp), source, sizeof(source), severity, sizeof(severity)); av.value = value_dec; av.lastlogsize = atoi(lastlogsize); av.timestamp = atoi(timestamp); av.source = source; av.severity = atoi(severity); } else { pl = s; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.host_name, pl, sizeof(av.host_name)); *pr = ':'; pl = pr + 1; if (NULL == (pr = strchr(pl, ':'))) return FAIL; *pr = '\0'; zbx_strlcpy(av.key, pl, sizeof(av.key)); *pr = ':'; av.value = pr + 1; av.severity = 0; } av.clock = time(NULL); process_mass_data(sock, 0, &av, 1, NULL); alarm(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send_raw(sock, SUCCEED == ret ? "OK" : "NOT OK")) { zabbix_log(LOG_LEVEL_WARNING, "Error sending result back"); zabbix_syslog("Trapper: error sending result back"); } alarm(0); } return ret; }
static int get_value(DC_ITEM *item, AGENT_RESULT *result) { const char *__function_name = "get_value"; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() key:'%s'", __function_name, item->key_orig); switch (item->type) { case ITEM_TYPE_ZABBIX: alarm(CONFIG_TIMEOUT); res = get_value_agent(item, result); alarm(0); break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: #ifdef HAVE_SNMP alarm(CONFIG_TIMEOUT); res = get_value_snmp(item, result); alarm(0); #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for SNMP checks was not compiled in")); res = NOTSUPPORTED; #endif break; case ITEM_TYPE_IPMI: #ifdef HAVE_OPENIPMI res = get_value_ipmi(item, result); #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for IPMI checks was not compiled in")); res = NOTSUPPORTED; #endif break; case ITEM_TYPE_SIMPLE: /* simple checks use their own timeouts */ res = get_value_simple(item, result); break; case ITEM_TYPE_INTERNAL: res = get_value_internal(item, result); break; case ITEM_TYPE_DB_MONITOR: alarm(CONFIG_TIMEOUT); res = get_value_db(item, result); alarm(0); break; case ITEM_TYPE_AGGREGATE: res = get_value_aggregate(item, result); break; case ITEM_TYPE_EXTERNAL: /* external checks use their own timeouts */ res = get_value_external(item, result); break; case ITEM_TYPE_SSH: #ifdef HAVE_SSH2 alarm(CONFIG_TIMEOUT); res = get_value_ssh(item, result); alarm(0); #else SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for SSH checks was not compiled in")); res = NOTSUPPORTED; #endif /* HAVE_SSH2 */ break; case ITEM_TYPE_TELNET: alarm(CONFIG_TIMEOUT); res = get_value_telnet(item, result); alarm(0); break; case ITEM_TYPE_CALCULATED: res = get_value_calculated(item, result); break; default: SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Not supported item type:%d", item->type)); res = NOTSUPPORTED; } if (SUCCEED != res) { if (!ISSET_MSG(result)) SET_MSG_RESULT(result, zbx_strdup(NULL, "ZBX_NOTSUPPORTED")); zabbix_log(LOG_LEVEL_DEBUG, "Item [%s:%s] error: %s", item->host.host, item->key_orig, result->msg); zabbix_syslog("Item [%s:%s] error: %s", item->host.host, item->key_orig, result->msg); } /* remove formatting characters from the end of the result */ /* so it could be checked by "is_uint64" and "is_double" functions */ /* when we try to get "int" or "float" values from "string" result */ if (ISSET_STR(result)) zbx_rtrim(result->str, " \r\n"); if (ISSET_TEXT(result)) zbx_rtrim(result->text, " \r\n"); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: main_alerter_loop * * * * Purpose: periodically check table alerts and send notifications if needed * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ int main_alerter_loop() { char error[MAX_STRING_LEN], *error_esc; int res, now; struct sigaction phan; DB_RESULT result; DB_ROW row; DB_ALERT alert; DB_MEDIATYPE mediatype; /* phan.sa_handler = child_signal_handler;*/ phan.sa_sigaction = child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = SA_SIGINFO; sigaction(SIGALRM, &phan, NULL); zbx_setproctitle("connecting to the database"); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { now = time(NULL); result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid" ",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path" ",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt" " where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE " order by a.clock", ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, DBnode_local("mt.mediatypeid")); while (NULL != (row = DBfetch(result))) { res = FAIL; ZBX_STR2UINT64(alert.alertid, row[0]); alert.mediatypeid = atoi(row[1]); alert.sendto = row[2]; alert.subject = row[3]; alert.message = row[4]; alert.status = atoi(row[5]); ZBX_STR2UINT64(mediatype.mediatypeid, row[6]); mediatype.type = atoi(row[7]); mediatype.description = row[8]; mediatype.smtp_server = row[9]; mediatype.smtp_helo = row[10]; mediatype.smtp_email = row[11]; mediatype.exec_path = row[12]; mediatype.gsm_modem = row[13]; mediatype.username = row[14]; mediatype.passwd = row[15]; alert.retries = atoi(row[16]); *error = '\0'; res = execute_action(&alert, &mediatype, error, sizeof(error)); if (res == SUCCEED) { zabbix_log( LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully", alert.alertid); DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64, ALERT_STATUS_SENT, alert.alertid); } else { zabbix_log( LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]", alert.alertid); error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN); alert.retries++; if(alert.retries < ALERT_MAX_RETRIES) { DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64, alert.retries, error_esc, alert.alertid); } else { DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64, ALERT_STATUS_FAILED, alert.retries, error_esc, alert.alertid); } zbx_free(error_esc); } } DBfree_result(result); zbx_setproctitle("sender [sleeping for %d seconds]", CONFIG_SENDER_FREQUENCY); sleep(CONFIG_SENDER_FREQUENCY); } /* Never reached */ DBclose(); }
/* * Send email */ int send_email(char *smtp_server,char *smtp_helo,char *smtp_email,char *mailto,char *mailsubject,char *mailbody, char *error, int max_error_len) { int ret=SUCCEED; zbx_sock_t s; int i,e; char c[MAX_STRING_LEN], *cp = NULL; char str_time[MAX_STRING_LEN]; struct tm *local_time = NULL; time_t email_time; char *OK_220="220"; char *OK_250="250"; char *OK_251="251"; char *OK_354="354"; zabbix_log( LOG_LEVEL_DEBUG, "In send_email[smtp_server:%s]", smtp_server); if(FAIL == zbx_tcp_connect(&s, smtp_server, 25, 0, NULL)) { zbx_snprintf(error,max_error_len,"Cannot connect to SMTP server [%s] [%s]", smtp_server, zbx_tcp_strerror()); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving initial string from SMTP server [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_220,c,strlen(OK_220)) != 0) { zbx_snprintf(error,max_error_len,"No welcome message 220* from SMTP server [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strlen(smtp_helo) != 0) { memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"HELO %s\r\n",smtp_helo); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending HELO to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on HELO request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on HELO [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s",error); zabbix_syslog("%s",error); ret=FAIL; goto out; } } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"MAIL FROM: <%s>\r\n",smtp_email); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending MAIL FROM to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on MAIL FROM request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on MAIL FROM [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"RCPT TO: <%s>\r\n",mailto); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending RCPT TO to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receiving answer on RCPT TO request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } /* May return 251 as well: User not local; will forward to <forward-path>. See RFC825 */ if( strncmp(OK_250,c,strlen(OK_250)) != 0 && strncmp(OK_251,c,strlen(OK_251)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on RCPT TO [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"DATA\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending DATA to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receivng answer on DATA request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_354,c,strlen(OK_354)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on DATA [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } cp = string_replace(mailsubject, "\r\n", "\n"); mailsubject = string_replace(cp, "\n", "\r\n"); zbx_free(cp); cp = string_replace(mailbody, "\r\n", "\n"); mailbody = string_replace(cp, "\n", "\r\n"); zbx_free(cp); memset(c,0,MAX_STRING_LEN); time(&email_time); local_time = localtime(&email_time); strftime( str_time, MAX_STRING_LEN, "%a, %d %b %Y %H:%M:%S %z", local_time ); cp = zbx_dsprintf(cp,"From:<%s>\r\nTo:<%s>\r\nDate: %s\r\nSubject: %s\r\n\r\n%s",smtp_email,mailto,str_time,mailsubject, mailbody); e=write(s.socket,cp,strlen(cp)); zbx_free(cp); zbx_free(mailsubject); zbx_free(mailbody); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending mail subject and body to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"\r\n.\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending . to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); i=read(s.socket,c,MAX_STRING_LEN); if(i == -1) { zbx_snprintf(error,max_error_len,"Error receivng answer on . request [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s", error); ret=FAIL; goto out; } if(strncmp(OK_250,c,strlen(OK_250)) != 0) { zbx_snprintf(error,max_error_len,"Wrong answer on end of data [%s]", c); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } memset(c,0,MAX_STRING_LEN); zbx_snprintf(c,sizeof(c),"QUIT\r\n"); e=write(s.socket,c,strlen(c)); if(e == -1) { zbx_snprintf(error,max_error_len,"Error sending QUIT to mailserver [%s]", strerror(errno)); zabbix_log(LOG_LEVEL_DEBUG, "%s", error); zabbix_syslog("%s",error); ret=FAIL; goto out; } out: zbx_tcp_close(&s); return ret; }
/****************************************************************************** * * * Function: get_values * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ static int get_values(int now, int *nextcheck) { DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; int delay; int res; DB_ITEM item; AGENT_RESULT agent; int stop = 0, items = 0; static char *unreachable_hosts = NULL; static int unreachable_hosts_alloc = 32; int unreachable_hosts_offset = 0; char istatus[16]; zabbix_log( LOG_LEVEL_DEBUG, "In get_values()"); if (0 != CONFIG_DBSYNCER_FORKS) DCinit_nextchecks(); now = time(NULL); *nextcheck = FAIL; if (NULL == unreachable_hosts) unreachable_hosts = zbx_malloc(unreachable_hosts, unreachable_hosts_alloc); *unreachable_hosts = '\0'; if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf(istatus, sizeof(istatus), "%d,%d", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); else zbx_snprintf(istatus, sizeof(istatus), "%d", ITEM_STATUS_ACTIVE); switch (poller_type) { case ZBX_POLLER_TYPE_UNREACHABLE: result = DBselect("select h.hostid,min(i.itemid) from hosts h,items i" " where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)" " and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from!=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " group by h.hostid", CONFIG_UNREACHABLE_POLLER_FORKS, poller_num-1, now + POLLER_DELAY, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; case ZBX_POLLER_TYPE_IPMI: result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)" " and i.type in (%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, istatus, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, CONFIG_IPMIPOLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; default: /* ZBX_POLLER_TYPE_NORMAL */ result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)" " and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))" " and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, HOST_STATUS_MONITORED, istatus, now, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_INTERNAL, CONFIG_POLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); } /* Do not stop when select is made by poller for unreachable hosts */ while((row=DBfetch(result))&&(stop==0 || poller_type == ZBX_POLLER_TYPE_UNREACHABLE)) { /* This code is just to avoid compilation warining about use of uninitialized result2 */ result2 = result; /* */ /* Poller for unreachable hosts */ if(poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { result2 = DBselect("select %s where h.hostid=i.hostid and h.proxy_hostid=0 and i.itemid=%s" DB_NODE, ZBX_SQL_ITEM_SELECT, row[1], DBnode_local("h.hostid")); row2 = DBfetch(result2); if(!row2) { DBfree_result(result2); continue; } DBget_item_from_db(&item,row2); } else { DBget_item_from_db(&item,row); /* Skip unreachable hosts but do not break the loop. */ if(uint64_in_list(unreachable_hosts,item.hostid) == SUCCEED) { zabbix_log( LOG_LEVEL_DEBUG, "Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", item.hostid,item.key); continue; } } if (item.nextcheck > time(NULL)) { if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) DBfree_result(result2); continue; } init_result(&agent); res = get_value(&item, &agent); now = time(NULL); if (res == SUCCEED) { if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } if (item.host_errors_from != 0) { DBbegin(); DBexecute("update hosts set errors_from=0 where hostid=" ZBX_FS_UI64, item.hostid); stop = 1; DBcommit(); } if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, now); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, now); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (0 != CONFIG_DBSYNCER_FORKS) DCadd_nextcheck(&item, now, 0, NULL); if (poller_type == ZBX_POLLER_TYPE_NORMAL || poller_type == ZBX_POLLER_TYPE_IPMI) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; } else if (res == NOTSUPPORTED || res == AGENT_ERROR) { if (item.status != ITEM_STATUS_NOTSUPPORTED) { zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] is not supported by agent on host [%s] Old status [%d]", item.key, item.host_name, item.status); zabbix_syslog("Parameter [%s] is not supported by agent on host [%s]", item.key, item.host_name); } if (0 == CONFIG_DBSYNCER_FORKS) { DBbegin(); DBupdate_item_status_to_notsupported(&item, now, agent.msg); DBcommit(); } else DCadd_nextcheck(&item, now, 0, agent.msg); if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } } else if (res == NETWORK_ERROR) { DBbegin(); /* First error */ if (item.host_errors_from == 0) { zabbix_log( LOG_LEVEL_WARNING, "Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set errors_from=%d,disable_until=%d where hostid=" ZBX_FS_UI64, now, now + CONFIG_UNREACHABLE_DELAY, item.hostid); item.host_errors_from = now; delay = MIN(4*item.delay, 300); zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] will be checked after %d seconds on host [%s]", item.key, delay, item.host_name); DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64, now + delay, item.itemid); } else { if (now - item.host_errors_from > CONFIG_UNREACHABLE_PERIOD) { disable_host(&item, now, agent.msg); } else { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zabbix_log(LOG_LEVEL_WARNING, "Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set disable_until=%d where hostid=" ZBX_FS_UI64, now + CONFIG_UNREACHABLE_DELAY, item.hostid); } } DBcommit(); zbx_snprintf_alloc(&unreachable_hosts, &unreachable_hosts_alloc, &unreachable_hosts_offset, 32, "%s" ZBX_FS_UI64, 0 == unreachable_hosts_offset ? "" : ",", item.hostid); } else { zabbix_log(LOG_LEVEL_CRIT, "Unknown response code returned."); assert(0==1); } items++; /* Poller for unreachable hosts */ if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { /* We cannot freeit earlier because items has references to the structure */ DBfree_result(result2); } free_result(&agent); } DBfree_result(result); if (0 != CONFIG_DBSYNCER_FORKS) DCflush_nextchecks(); zabbix_log(LOG_LEVEL_DEBUG, "End get_values()"); return items; }
/****************************************************************************** * * * Function: get_values * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ static int get_values(unsigned char poller_type) { const char *__function_name = "get_values"; DC_ITEM items[MAX_REACHABLE_ITEMS]; AGENT_RESULT agent; zbx_uint64_t *ids = NULL, *snmpids = NULL, *ipmiids = NULL; int ids_alloc = 0, snmpids_alloc = 0, ipmiids_alloc = 0, ids_num = 0, snmpids_num = 0, ipmiids_num = 0, i, now, num, res; static char *key = NULL, *ipmi_ip = NULL, *params = NULL, *username = NULL, *publickey = NULL, *privatekey = NULL, *password = NULL, *snmp_community = NULL, *snmp_oid = NULL, *snmpv3_securityname = NULL, *snmpv3_authpassphrase = NULL, *snmpv3_privpassphrase = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); DCinit_nextchecks(); num = DCconfig_get_poller_items(poller_type, items, ZBX_POLLER_TYPE_UNREACHABLE != poller_type ? MAX_REACHABLE_ITEMS : MAX_UNREACHABLE_ITEMS); for (i = 0; i < num; i++) { zbx_free(key); key = strdup(items[i].key_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &key, MACRO_TYPE_ITEM_KEY, NULL, 0); items[i].key = key; switch (items[i].type) { case ITEM_TYPE_SNMPv3: zbx_free(snmpv3_securityname); zbx_free(snmpv3_authpassphrase); zbx_free(snmpv3_privpassphrase); snmpv3_securityname = strdup(items[i].snmpv3_securityname_orig); snmpv3_authpassphrase = strdup(items[i].snmpv3_authpassphrase_orig); snmpv3_privpassphrase = strdup(items[i].snmpv3_privpassphrase_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &snmpv3_securityname, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &snmpv3_authpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &snmpv3_privpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0); items[i].snmpv3_securityname = snmpv3_securityname; items[i].snmpv3_authpassphrase = snmpv3_authpassphrase; items[i].snmpv3_privpassphrase = snmpv3_privpassphrase; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: zbx_free(snmp_community); zbx_free(snmp_oid); snmp_community = strdup(items[i].snmp_community_orig); snmp_oid = strdup(items[i].snmp_oid_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &snmp_community, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &snmp_oid, MACRO_TYPE_ITEM_FIELD, NULL, 0); items[i].snmp_community = snmp_community; items[i].snmp_oid = snmp_oid; break; case ITEM_TYPE_IPMI: zbx_free(ipmi_ip); ipmi_ip = strdup(items[i].host.ipmi_ip_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &ipmi_ip, MACRO_TYPE_HOST_IPMI_IP, NULL, 0); items[i].host.ipmi_ip = ipmi_ip; break; case ITEM_TYPE_DB_MONITOR: zbx_free(params); params = strdup(items[i].params_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, ¶ms, MACRO_TYPE_ITEM_FIELD, NULL, 0); items[i].params = params; break; case ITEM_TYPE_SSH: zbx_free(username); zbx_free(publickey); zbx_free(privatekey); zbx_free(password); zbx_free(params); username = strdup(items[i].username_orig); publickey = strdup(items[i].publickey_orig); privatekey = strdup(items[i].privatekey_orig); password = strdup(items[i].password_orig); params = strdup(items[i].params_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &username, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &publickey, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &privatekey, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &password, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, ¶ms, MACRO_TYPE_ITEM_FIELD, NULL, 0); items[i].username = username; items[i].publickey = publickey; items[i].privatekey = privatekey; items[i].password = password; items[i].params = params; break; case ITEM_TYPE_TELNET: zbx_free(username); zbx_free(password); zbx_free(params); username = strdup(items[i].username_orig); password = strdup(items[i].password_orig); params = strdup(items[i].params_orig); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &username, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, &password, MACRO_TYPE_ITEM_FIELD, NULL, 0); substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL, ¶ms, MACRO_TYPE_ITEM_FIELD, NULL, 0); items[i].username = username; items[i].password = password; items[i].params = params; break; } /* Skip unreachable hosts but do not break the loop. */ switch (items[i].type) { case ITEM_TYPE_ZABBIX: if (SUCCEED == uint64_array_exists(ids, ids_num, items[i].host.hostid)) { DCrequeue_unreachable_item(items[i].itemid); zabbix_log(LOG_LEVEL_DEBUG, "Zabbix Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", items[i].host.hostid, items[i].key_orig); continue; } break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: if (SUCCEED == uint64_array_exists(snmpids, snmpids_num, items[i].host.hostid)) { DCrequeue_unreachable_item(items[i].itemid); zabbix_log(LOG_LEVEL_DEBUG, "SNMP Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", items[i].host.hostid, items[i].key_orig); continue; } break; case ITEM_TYPE_IPMI: if (SUCCEED == uint64_array_exists(ipmiids, ipmiids_num, items[i].host.hostid)) { DCrequeue_unreachable_item(items[i].itemid); zabbix_log(LOG_LEVEL_DEBUG, "IPMI Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", items[i].host.hostid, items[i].key_orig); continue; } break; default: /* nothing to do */; } init_result(&agent); res = get_value(&items[i], &agent); now = time(NULL); if (res == SUCCEED) { activate_host(&items[i], now); dc_add_history(items[i].itemid, items[i].value_type, &agent, now, 0, NULL, 0, 0, 0, 0); DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_ACTIVE, now); } else if (res == NOTSUPPORTED || res == AGENT_ERROR) { if (ITEM_STATUS_NOTSUPPORTED != items[i].status) { zabbix_log(LOG_LEVEL_WARNING, "Item [%s:%s] is not supported", items[i].host.host, items[i].key_orig); zabbix_syslog("Item [%s:%s] is not supported", items[i].host.host, items[i].key_orig); } activate_host(&items[i], now); DCadd_nextcheck(items[i].itemid, now, agent.msg); /* update error & status field in items table */ DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_NOTSUPPORTED, now); } else if (res == NETWORK_ERROR) { deactivate_host(&items[i], now, agent.msg); switch (items[i].type) { case ITEM_TYPE_ZABBIX: uint64_array_add(&ids, &ids_alloc, &ids_num, items[i].host.hostid, 1); break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: uint64_array_add(&snmpids, &snmpids_alloc, &snmpids_num, items[i].host.hostid, 1); break; case ITEM_TYPE_IPMI: uint64_array_add(&ipmiids, &ipmiids_alloc, &ipmiids_num, items[i].host.hostid, 1); break; default: /* nothing to do */; } DCrequeue_unreachable_item(items[i].itemid); } else { zbx_error("unknown response code returned: %d", res); assert(0); } free_result(&agent); } zbx_free(key); zbx_free(ipmi_ip); zbx_free(params); zbx_free(username); zbx_free(publickey); zbx_free(privatekey); zbx_free(password); zbx_free(snmp_community); zbx_free(snmp_oid); zbx_free(snmpv3_securityname); zbx_free(snmpv3_authpassphrase); zbx_free(snmpv3_privpassphrase); zbx_free(ids); zbx_free(snmpids); zbx_free(ipmiids); DCflush_nextchecks(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return num; }