/****************************************************************************** * * * Function: select_discovered_host * * * * Purpose: select hostid of discovered host * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - existing hostid, 0 - if not found * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t select_discovered_host(const DB_EVENT *event) { const char *__function_name = "select_discovered_host"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char *sql = NULL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64, __function_name, event->eventid); switch (event->object) { case EVENT_OBJECT_DHOST: sql = zbx_dsprintf(sql, "select h.hostid" " from hosts h,interface i,dservices ds,dchecks dc,drules dr" " where h.hostid=i.hostid" " and i.ip=ds.ip" " and ds.dcheckid=dc.dcheckid" " and dc.druleid=dr.druleid" " and " ZBX_SQL_NULLCMP("dr.proxy_hostid", "h.proxy_hostid") " and i.useip=1" " and ds.dhostid=" ZBX_FS_UI64 ZBX_SQL_NODE " order by i.hostid", event->objectid, DBand_node_local("i.interfaceid")); break; case EVENT_OBJECT_DSERVICE: sql = zbx_dsprintf(sql, "select h.hostid" " from hosts h,interface i,dservices ds,dchecks dc,drules dr" " where h.hostid=i.hostid" " and i.ip=ds.ip" " and ds.dcheckid=dc.dcheckid" " and dc.druleid=dr.druleid" " and " ZBX_SQL_NULLCMP("dr.proxy_hostid", "h.proxy_hostid") " and i.useip=1" " and ds.dserviceid =" ZBX_FS_UI64 ZBX_SQL_NODE " order by i.hostid", event->objectid, DBand_node_local("i.interfaceid")); break; default: goto exit; } result = DBselectN(sql, 1); zbx_free(sql); if (NULL != (row = DBfetch(result))) ZBX_STR2UINT64(hostid, row[0]); DBfree_result(result); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():" ZBX_FS_UI64, __function_name, hostid); return hostid; }
/****************************************************************************** * * * Function: op_groups_del * * * * Purpose: delete groups from discovered host * * * * Parameters: event - [IN] event data * * groupids - [IN] IDs of groups to delete * * * * Author: Alexei Vladishev * * * ******************************************************************************/ void op_groups_del(const DB_EVENT *event, zbx_vector_uint64_t *groupids) { const char *__function_name = "op_groups_del"; DB_RESULT result; zbx_uint64_t hostid; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (event->source != EVENT_SOURCE_DISCOVERY) return; if (event->object != EVENT_OBJECT_DHOST && event->object != EVENT_OBJECT_DSERVICE) return; if (0 == (hostid = select_discovered_host(event))) return; sql = zbx_malloc(sql, sql_alloc); /* make sure host belongs to at least one hostgroup */ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select groupid" " from hosts_groups" " where hostid=" ZBX_FS_UI64 " and not", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num); result = DBselectN(sql, 1); if (NULL == DBfetch(result)) { zabbix_log(LOG_LEVEL_WARNING, "cannot remove host \"%s\" from all host groups:" " it must belong to at least one", zbx_host_string(hostid)); } else { sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts_groups" " where hostid=" ZBX_FS_UI64 " and", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num); DBexecute("%s", sql); } DBfree_result(result); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: select hostid of discovered host * * * * Purpose: select discovered host * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - existing hostid, 0 - if not found * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t select_discovered_host(DB_EVENT *event) { const char *__function_name = "select_discovered_host"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char sql[512]; zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64, __function_name, event->eventid); switch (event->object) { case EVENT_OBJECT_DHOST: zbx_snprintf(sql, sizeof(sql), "select h.hostid" " from hosts h,dservices ds" " where ds.ip=h.ip" " and ds.dhostid=" ZBX_FS_UI64 DB_NODE " order by h.hostid", event->objectid, DBnode_local("h.hostid")); break; case EVENT_OBJECT_DSERVICE: zbx_snprintf(sql, sizeof(sql), "select h.hostid" " from hosts h,dservices ds" " where ds.ip=h.ip" " and ds.dserviceid=" ZBX_FS_UI64 DB_NODE " order by h.hostid", event->objectid, DBnode_local("h.hostid")); break; default: goto exit; } result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(hostid, row[0]); } DBfree_result(result); exit: zabbix_log(LOG_LEVEL_DEBUG, "End %s():" ZBX_FS_UI64, __function_name, hostid); return hostid; }
/****************************************************************************** * * * Function: discovery_separate_host * * * * Purpose: separate multiple-IP hosts * * * * Parameters: host ip address * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static void discovery_separate_host(DB_DRULE *drule, DB_DHOST *dhost, const char *ip) { const char *__function_name = "discovery_separate_host"; DB_RESULT result; DB_ROW row; char *ip_esc, *sql = NULL; zbx_uint64_t dhostid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s'", __function_name, ip); ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN); sql = zbx_dsprintf(sql, "select dserviceid" " from dservices" " where dhostid=" ZBX_FS_UI64 " and ip" ZBX_SQL_STRCMP, dhost->dhostid, ZBX_SQL_STRVAL_NE(ip_esc)); result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) { dhostid = DBget_maxid("dhosts"); DBexecute("insert into dhosts (dhostid,druleid)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ")", dhostid, drule->druleid); DBexecute("update dservices" " set dhostid=" ZBX_FS_UI64 " where dhostid=" ZBX_FS_UI64 " and ip" ZBX_SQL_STRCMP, dhostid, dhost->dhostid, ZBX_SQL_STRVAL_EQ(ip_esc)); dhost->dhostid = dhostid; dhost->status = DOBJECT_STATUS_DOWN; dhost->lastup = 0; dhost->lastdown = 0; } DBfree_result(result); zbx_free(sql); zbx_free(ip_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: get_discovered_agent_port * * * * Purpose: return port of the discovered zabbix_agent * * * * Return value: discovered port number, otherwise default port - 10050 * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static unsigned short get_discovered_agent_port(DB_EVENT *event) { const char *__function_name = "get_discovered_agent_port"; DB_RESULT result; DB_ROW row; unsigned short port = 10050; char sql[256]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (event->source != EVENT_SOURCE_DISCOVERY) goto end; switch (event->object) { case EVENT_OBJECT_DHOST: zbx_snprintf(sql, sizeof(sql), "select port from dservices where type=%d and dhostid=" ZBX_FS_UI64 " order by dserviceid", SVC_AGENT, event->objectid); break; case EVENT_OBJECT_DSERVICE: zbx_snprintf(sql, sizeof(sql), "select port from dservices where type=%d and" " dhostid in (select dhostid from dservices where dserviceid=" ZBX_FS_UI64 ")" " order by dserviceid", SVC_AGENT, event->objectid); break; default: goto end; } result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) { port = atoi(row[0]); zabbix_log(LOG_LEVEL_DEBUG, "%s() port:%d", __function_name, (int)port); } DBfree_result(result); end: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return port; }
/****************************************************************************** * * * Function : process_hstory_table_data: * * * * Purpose: process new history data * * * * Parameters: * * * * Return value: * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ void process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid) { DB_RESULT result; DB_ROW row; char *data = NULL, *tmp = NULL; int data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len; int data_found = 0; zbx_uint64_t lastid; int lastclock = 0, clock; zabbix_log( LOG_LEVEL_DEBUG, "In process_history_table_data()"); DBbegin(); if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid)) return; if ((table->flags & ZBX_HISTORY_TRENDS) && FAIL == get_trends_lastid(master_nodeid, nodeid, table, &lastid, &lastclock)) return; data = zbx_malloc(data, data_allocated); tmp = zbx_malloc(tmp, tmp_allocated); data_offset = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s", ZBX_DM_DELIMITER, CONFIG_NODEID, ZBX_DM_DELIMITER, nodeid, ZBX_DM_DELIMITER, table->table); /* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */ /* if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid)) goto exit;*/ tmp_offset = 0; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,", table->recid); } else { /* ZBX_HISTORY, ZBX_HISTORY_TRENDS */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select "); } for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,", table->fields[f].name); } tmp_offset--; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s", table->table, nodeid, table->recid); } else if (table->flags & ZBX_HISTORY_TRENDS) { clock = time(NULL) - 600; /* -10min */ clock -= clock % 3600; zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where" " (itemid>"ZBX_FS_UI64" or (itemid="ZBX_FS_UI64" and clock>%d)) and clock<%d" DB_NODE " order by itemid,clock", table->table, lastid, lastid, lastclock, clock, DBnode("itemid", nodeid)); } else { /* ZBX_HISTORY */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64 DB_NODE " order by %s", table->table, table->recid, lastid, DBnode(table->recid, nodeid), table->recid); } result = DBselectN(tmp, 10000); while (NULL != (row = DBfetch(result))) { if (table->flags & ZBX_HISTORY_SYNC) { ZBX_STR2UINT64(lastid, row[0]); fld = 1; } else fld = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n"); for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s%c", row[fld], ZBX_DM_DELIMITER); } else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */ len = (int)strlen(row[fld]); len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated); zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c", tmp, ZBX_DM_DELIMITER); } fld++; } data_offset--; data_found = 1; } DBfree_result(result); data[data_offset] = '\0'; if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) { if (table->flags & ZBX_HISTORY_SYNC) { DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64, table->table, nodeid, table->recid, lastid); } } DBcommit(); zbx_free(tmp); zbx_free(data); }
/****************************************************************************** * * * Function: add host if not added already * * * * Purpose: add discovered host * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - new/existing hostid * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t add_discovered_host(DB_EVENT *event) { const char *__function_name = "add_discovered_host"; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; zbx_uint64_t hostid = 0, proxy_hostid, host_proxy_hostid; char host[MAX_STRING_LEN], *host_esc, *ip_esc, *host_unique, *host_unique_esc; int port; zbx_uint64_t groupid; zabbix_log(LOG_LEVEL_DEBUG, "In %s(eventid:" ZBX_FS_UI64 ")", __function_name, event->eventid); result = DBselect( "select discovery_groupid" " from config" " where 1=1" DB_NODE, DBnode_local("configid")); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(groupid, row[0]); } else { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined"); return 0; } DBfree_result(result); switch (event->object) { case EVENT_OBJECT_DHOST: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds.dhostid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_DSERVICE: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds,dservices ds1" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds1.dhostid=ds.dhostid" " and ds1.dserviceid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_ZABBIX_ACTIVE: result = DBselect("select proxy_hostid,host from autoreg_host" " where autoreg_hostid=" ZBX_FS_UI64, event->objectid); break; default: return 0; } if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(proxy_hostid, row[0]); if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object) { char sql[512]; host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN); zbx_snprintf(sql, sizeof(sql), "select hostid,proxy_hostid" " from hosts" " where host='%s'" DB_NODE " order by hostid", host_esc, DBnode_local("hostid")); result2 = DBselectN(sql, 1); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,dns)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',0,'%s')", hostid, proxy_hostid, host_esc, host_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[1]); if (host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); } else /* EVENT_OBJECT_DHOST, EVENT_OBJECT_DSERVICE */ { alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(row[1], host, sizeof(host)); alarm(0); host_esc = DBdyn_escape_string_len(host, HOST_HOST_LEN); ip_esc = DBdyn_escape_string_len(row[1], HOST_IP_LEN); port = get_discovered_agent_port(event); result2 = DBselect( "select hostid,dns,port,proxy_hostid" " from hosts" " where ip='%s'" DB_NODE, ip_esc, DBnode_local("hostid")); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); /* for host uniqueness purposes */ if ('\0' != *host) { /* by host name */ make_hostname(host); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(host); } else { /* by ip */ make_hostname(row[1]); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(row[1]); } host_unique_esc = DBdyn_escape_string(host_unique); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,ip,dns,port)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',1,'%s','%s',%d)", hostid, proxy_hostid, host_unique_esc, ip_esc, host_esc, port); zbx_free(host_unique); zbx_free(host_unique_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[3]); if (0 != strcmp(host, row2[1]) || host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set dns='%s',proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, host_esc, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); zbx_free(ip_esc); } } DBfree_result(result); if (0 != hostid) add_discovered_host_group(hostid, groupid); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return hostid; }
/************************************************************************************ * * * Function: db_read_values_by_time_and_count * * * * Purpose: reads item history data from database * * * * Parameters: itemid - [IN] the itemid * * value_type - [IN] the value type (see ITEM_VALUE_TYPE_* defs) * * values - [OUT] the item history data values * * seconds - [IN] the time period to read * * count - [IN] the number of values to read * * end_timestamp - [IN] the value timestamp to start reading with * * * * Return value: SUCCEED - the history data were read successfully * * FAIL - otherwise * * * * Comments: this function reads <count> values from <seconds> period before * * <count_timestamp> (including) plus all values in range: * * count_timestamp < <value timestamp> <= read_timestamp * * * ************************************************************************************/ static int db_read_values_by_time_and_count(zbx_uint64_t itemid, int value_type, zbx_vector_history_record_t *values, int seconds, int count, int end_timestamp) { int ret = FAIL; char *sql = NULL; size_t sql_alloc = 0, sql_offset; DB_RESULT result; DB_ROW row; zbx_vc_history_table_t *table = &vc_history_tables[value_type]; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select clock,ns,%s" " from %s" " where itemid=" ZBX_FS_UI64, table->fields, table->name, itemid); if (1 == seconds) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock=%d", end_timestamp); } else { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock>%d and clock<=%d order by clock desc", end_timestamp - seconds, end_timestamp); } result = DBselectN(sql, count); zbx_free(sql); if (NULL == result) goto out; while (NULL != (row = DBfetch(result)) && 0 < count--) { zbx_history_record_t value; value.timestamp.sec = atoi(row[0]); value.timestamp.ns = atoi(row[1]); table->rtov(&value.value, row + 2); zbx_vector_history_record_append_ptr(values, &value); } DBfree_result(result); if (0 < count) { /* no more data in the specified time period, return success */ ret = SUCCEED; goto out; } /* Drop data from the last second and read the whole second again */ /* to ensure that data is cached by seconds. */ /* Because the initial select has limit option (DBselectN()) we have */ /* to perform another select to read the last second data. */ end_timestamp = values->values[values->values_num - 1].timestamp.sec; while (0 < values->values_num && values->values[values->values_num - 1].timestamp.sec == end_timestamp) { values->values_num--; zbx_history_record_clear(&values->values[values->values_num], value_type); } ret = db_read_values_by_time(itemid, value_type, values, 1, end_timestamp); out: zbx_free(sql); return ret; }
/************************************************************************************ * * * Function: db_read_values_by_count * * * * Purpose: reads item history data from database * * * * Parameters: itemid - [IN] the itemid * * value_type - [IN] the value type (see ITEM_VALUE_TYPE_* defs) * * values - [OUT] the item history data values * * count - [IN] the number of values to read * * end_timestamp - [IN] the value timestamp to start reading with * * * * Return value: SUCCEED - the history data were read successfully * * FAIL - otherwise * * * * Comments: this function reads <count> values before <count_timestamp> (including)* * plus all values in range: * * count_timestamp < <value timestamp> <= read_timestamp * * * * To speed up the reading time with huge data loads, data is read by * * smaller time segments (hours, day, week, month) and the next (larger) * * time segment is read only if the requested number of values (<count>) * * is not yet retrieved. * * * ************************************************************************************/ static int db_read_values_by_count(zbx_uint64_t itemid, int value_type, zbx_vector_history_record_t *values, int count, int end_timestamp) { char *sql = NULL; size_t sql_alloc = 0, sql_offset; int clock_to, clock_from, step = 0, ret = FAIL; DB_RESULT result; DB_ROW row; zbx_vc_history_table_t *table = &vc_history_tables[value_type]; const int periods[] = {SEC_PER_HOUR, SEC_PER_DAY, SEC_PER_WEEK, SEC_PER_MONTH, 0, -1}; clock_to = end_timestamp; while (-1 != periods[step] && 0 < count) { if (0 > (clock_from = clock_to - periods[step])) { clock_from = clock_to; step = 4; } sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select clock,ns,%s" " from %s" " where itemid=" ZBX_FS_UI64 " and clock<=%d", table->fields, table->name, itemid, clock_to); if (clock_from != clock_to) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and clock>%d", clock_from); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by clock desc"); result = DBselectN(sql, count); if (NULL == result) goto out; while (NULL != (row = DBfetch(result))) { zbx_history_record_t value; value.timestamp.sec = atoi(row[0]); value.timestamp.ns = atoi(row[1]); table->rtov(&value.value, row + 2); zbx_vector_history_record_append_ptr(values, &value); count--; } DBfree_result(result); clock_to -= periods[step]; step++; } if (0 < count) { /* no more data in database, return success */ ret = SUCCEED; goto out; } /* drop data from the last second and read the whole second again */ /* to ensure that data is cached by seconds */ end_timestamp = values->values[values->values_num - 1].timestamp.sec; while (0 < values->values_num && values->values[values->values_num - 1].timestamp.sec == end_timestamp) { values->values_num--; zbx_history_record_clear(&values->values[values->values_num], value_type); } ret = db_read_values_by_time(itemid, value_type, values, 1, end_timestamp); out: zbx_free(sql); return ret; }
/****************************************************************************** * * * Function: add_discovered_host * * * * Purpose: add discovered host if it was not added already * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - new/existing hostid * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t add_discovered_host(const DB_EVENT *event) { const char *__function_name = "add_discovered_host"; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; zbx_uint64_t dhostid, hostid = 0, proxy_hostid; char *host = NULL, *host_esc, *host_unique; unsigned short port; zbx_uint64_t groupid; zbx_vector_uint64_t groupids; unsigned char svc_type, interface_type; zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64, __function_name, event->eventid); zbx_vector_uint64_create(&groupids); if (0 == *(zbx_uint64_t *)DCconfig_get_config_data(&groupid, CONFIG_DISCOVERY_GROUPID)) { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined"); goto clean; } zbx_vector_uint64_append(&groupids, groupid); if (EVENT_OBJECT_DHOST == event->object || EVENT_OBJECT_DSERVICE == event->object) { if (EVENT_OBJECT_DHOST == event->object) { result = DBselect( "select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type" " from drules dr,dchecks dc,dservices ds" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds.dhostid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); } else { result = DBselect( "select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type" " from drules dr,dchecks dc,dservices ds,dservices ds1" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds1.dhostid=ds.dhostid" " and ds1.dserviceid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); } while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(dhostid, row[0]); ZBX_DBROW2UINT64(proxy_hostid, row[1]); svc_type = (unsigned char)atoi(row[5]); switch (svc_type) { case SVC_AGENT: port = (unsigned short)atoi(row[4]); interface_type = INTERFACE_TYPE_AGENT; break; case SVC_SNMPv1: case SVC_SNMPv2c: case SVC_SNMPv3: port = (unsigned short)atoi(row[4]); interface_type = INTERFACE_TYPE_SNMP; break; default: port = ZBX_DEFAULT_AGENT_PORT; interface_type = INTERFACE_TYPE_AGENT; } if (0 == hostid) { result2 = DBselect( "select distinct h.hostid" " from hosts h,interface i,dservices ds" " where h.hostid=i.hostid" " and i.ip=ds.ip" " and h.proxy_hostid%s" " and ds.dhostid=" ZBX_FS_UI64 ZBX_SQL_NODE " order by h.hostid", DBsql_id_cmp(proxy_hostid), dhostid, DBand_node_local("h.hostid")); if (NULL != (row2 = DBfetch(result2))) ZBX_STR2UINT64(hostid, row2[0]); DBfree_result(result2); } if (0 == hostid) { hostid = DBget_maxid("hosts"); /* for host uniqueness purposes */ host = zbx_strdup(host, '\0' != *row[3] ? row[3] : row[2]); make_hostname(host); /* replace not-allowed symbols */ host_unique = DBget_unique_hostname_by_sample(host); host_esc = DBdyn_escape_string(host_unique); zbx_free(host); DBexecute("insert into hosts" " (hostid,proxy_hostid,host,name)" " values" " (" ZBX_FS_UI64 ",%s,'%s','%s')", hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc); DBadd_interface(hostid, interface_type, 1, row[2], row[3], port); zbx_free(host_unique); zbx_free(host_esc); add_discovered_host_groups(hostid, &groupids); } else { DBadd_interface(hostid, interface_type, 1, row[2], row[3], port); } } DBfree_result(result); } else if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object) { result = DBselect( "select proxy_hostid,host,listen_ip,listen_dns,listen_port" " from autoreg_host" " where autoreg_hostid=" ZBX_FS_UI64, event->objectid); if (NULL != (row = DBfetch(result))) { char *sql = NULL; zbx_uint64_t host_proxy_hostid; ZBX_DBROW2UINT64(proxy_hostid, row[0]); host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN); port = (unsigned short)atoi(row[4]); result2 = DBselect( "select null" " from hosts" " where host='%s'" " and status=%d", host_esc, HOST_STATUS_TEMPLATE); if (NULL != (row2 = DBfetch(result2))) { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host \"%s\":" " template with the same name already exists", row[1]); DBfree_result(result2); goto out; } DBfree_result(result2); sql = zbx_dsprintf(sql, "select hostid,proxy_hostid" " from hosts" " where host='%s'" " and flags<>%d" " and status in (%d,%d)" ZBX_SQL_NODE " order by hostid", host_esc, ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, DBand_node_local("hostid")); result2 = DBselectN(sql, 1); zbx_free(sql); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); DBexecute("insert into hosts" " (hostid,proxy_hostid,host,name)" " values" " (" ZBX_FS_UI64 ",%s,'%s','%s')", hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc); DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port); add_discovered_host_groups(hostid, &groupids); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_DBROW2UINT64(host_proxy_hostid, row2[1]); if (host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set proxy_hostid=%s" " where hostid=" ZBX_FS_UI64, DBsql_id_ins(proxy_hostid), hostid); } DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port); } DBfree_result(result2); out: zbx_free(host_esc); } DBfree_result(result); } clean: zbx_vector_uint64_destroy(&groupids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return hostid; }
/****************************************************************************** * * * Function: get_trigger_values * * * * Purpose: get trigger values for specified period * * * * Parameters: triggerid - [IN] trigger identifier from database * * maintenance_from - [IN] maintenance period start * * maintenance_to - [IN] maintenance period stop * * value_before - [OUT] trigger value before maintenance * * value_inside - [OUT] trigger value inside maintenance * * (only if value_before=value_after) * * value_after - [OUT] trigger value after maintenance * * * * Return value: SUCCEED if found event with OK or PROBLEM statuses * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void get_trigger_values(zbx_uint64_t triggerid, int maintenance_from, int maintenance_to, unsigned char *value_before, unsigned char *value_inside, unsigned char *value_after) { const char *__function_name = "get_trigger_values"; DB_RESULT result; DB_ROW row; char sql[256]; int clock; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zabbix_log(LOG_LEVEL_DEBUG, "%s() from:'%s %s'", __function_name, zbx_date2str(maintenance_from), zbx_time2str(maintenance_from)); zabbix_log(LOG_LEVEL_DEBUG, "%s() to:'%s %s'", __function_name, zbx_date2str(maintenance_to), zbx_time2str(maintenance_to)); /* check for value after maintenance period */ zbx_snprintf(sql, sizeof(sql), "select clock,value" " from events" " where source=%d" " and object=%d" " and objectid=" ZBX_FS_UI64 " and clock<%d" " order by clock desc,eventid desc", EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, triggerid, maintenance_to); result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) { clock = atoi(row[0]); *value_after = atoi(row[1]); } else { clock = 0; *value_after = TRIGGER_VALUE_UNKNOWN; } DBfree_result(result); /* if no events inside maintenance */ if (clock < maintenance_from) { *value_before = *value_after; *value_inside = *value_after; goto out; } /* check for value before maintenance period */ zbx_snprintf(sql, sizeof(sql), "select value" " from events" " where source=%d" " and object=%d" " and objectid=" ZBX_FS_UI64 " and clock<%d" " order by clock desc,eventid desc", EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, triggerid, maintenance_from); result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) *value_before = atoi(row[0]); else *value_before = TRIGGER_VALUE_UNKNOWN; DBfree_result(result); if (*value_after != *value_before) { *value_inside = TRIGGER_VALUE_UNKNOWN; /* not important what value is here */ goto out; } /* check for value inside maintenance period */ result = DBselect( "select value" " from events" " where source=%d" " and object=%d" " and objectid=" ZBX_FS_UI64 " and clock between %d and %d" " and value=%d" " order by object desc,objectid desc,eventid desc", EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, triggerid, maintenance_from, maintenance_to - 1, *value_after == TRIGGER_VALUE_OK ? TRIGGER_VALUE_PROBLEM : TRIGGER_VALUE_OK); if (NULL != (row = DBfetch(result))) *value_inside = atoi(row[0]); else *value_inside = *value_before; DBfree_result(result); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s() before:%d inside:%d after:%d", __function_name, (int)*value_before, (int)*value_inside, (int)*value_after); }