/****************************************************************************** * * * Function: DBcopy_template_items * * * * Purpose: copy template items to host * * * * Parameters: hostid - [IN] host id * * templateids - [IN] array of template IDs * * * ******************************************************************************/ void DBcopy_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *templateids) { const char *__function_name = "DBcopy_template_items"; zbx_vector_ptr_t items, lld_rules; int new_conditions = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&items); zbx_vector_ptr_create(&lld_rules); get_template_items(hostid, templateids, &items); if (0 == items.values_num) goto out; get_template_lld_rule_map(&items, &lld_rules); new_conditions = calculate_template_lld_rule_conditionids(&lld_rules); update_template_lld_rule_formulas(&items, &lld_rules); save_template_items(hostid, &items); save_template_lld_rules(&items, &lld_rules, new_conditions); save_template_item_applications(&items); save_template_discovery_prototypes(hostid, &items); out: zbx_vector_ptr_clear_ext(&lld_rules, (zbx_clean_func_t)free_lld_rule_map); zbx_vector_ptr_destroy(&lld_rules); zbx_vector_ptr_clear_ext(&items, (zbx_clean_func_t)free_template_item); zbx_vector_ptr_destroy(&items); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ void main_watchdog_loop() { int now, nextsync = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_watchdog_loop()"); /* disable writing to database in zabbix_syslog() */ CONFIG_ENABLE_LOG = 0; zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; } DBclose(); zbx_sleep_loop(DB_PING_FREQUENCY); } }
/****************************************************************************** * * * Function: process_time_functions * * * * Purpose: re-calculate and update values of time-driven functions * * * * Author: Alexei Vladishev, Aleksandrs Saveljevs * * * ******************************************************************************/ static void process_time_functions(int *triggers_count, int *events_count) { const char *__function_name = "process_time_functions"; DC_TRIGGER *trigger_info = NULL; zbx_vector_ptr_t trigger_order; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&trigger_order); DCconfig_get_time_based_triggers(&trigger_info, &trigger_order, process_num, triggers_count); if (0 == trigger_order.values_num) goto clean; evaluate_expressions(&trigger_order); DBbegin(); process_triggers(&trigger_order); DCfree_triggers(&trigger_order); *events_count = process_events(); DBcommit(); clean: zbx_free(trigger_info); zbx_vector_ptr_destroy(&trigger_order); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: hk_history_prepare * * * * Purpose: prepares history housekeeping rule * * * * Parameters: rule - [IN/OUT] the history housekeeping rule * * now - [IN] the current timestmap * * * * Author: Andris Zeila * * * * Comments: This function is called to initialize history rule data either * * at start or when housekeeping is enabled for this rule. * * It caches item history data and also prepares delete queue to be * * processed during the first run. * * * ******************************************************************************/ static void hk_history_prepare(zbx_hk_history_rule_t *rule, int now) { DB_RESULT result; DB_ROW row; zbx_hashset_create(&rule->item_cache, 1024, zbx_default_uint64_hash_func, zbx_default_uint64_compare_func); zbx_vector_ptr_create(&rule->delete_queue); zbx_vector_ptr_reserve(&rule->delete_queue, HK_INITIAL_DELETE_QUEUE_SIZE); result = DBselect("select itemid,min(clock) from %s group by itemid", rule->table); while (NULL != (row = DBfetch(result))) { zbx_uint64_t itemid; int min_clock; zbx_hk_item_cache_t item_record; ZBX_STR2UINT64(itemid, row[0]); min_clock = atoi(row[1]); item_record.itemid = itemid; item_record.min_clock = min_clock; zbx_hashset_insert(&rule->item_cache, &item_record, sizeof(zbx_hk_item_cache_t)); } DBfree_result(result); }
/****************************************************************************** * * * Function: DCflush_nextchecks * * * * Purpose: update triggers to UNKNOWN and generate events * * * ******************************************************************************/ void DCflush_nextchecks(zbx_vector_ptr_t *trigger_diff) { const char *__function_name = "DCflush_nextchecks"; int i; zbx_uint64_t *itemids = NULL; zbx_timespec_t *timespecs = NULL; char **errors = NULL; zbx_hashset_t trigger_info; zbx_vector_ptr_t trigger_order; DC_TRIGGER *trigger; zabbix_log(LOG_LEVEL_DEBUG, "In %s() nextcheck_num:%d", __function_name, nextcheck_num); if (0 == nextcheck_num) goto exit; itemids = zbx_malloc(itemids, nextcheck_num * sizeof(zbx_uint64_t)); timespecs = zbx_malloc(timespecs, nextcheck_num * sizeof(zbx_timespec_t)); errors = zbx_malloc(errors, nextcheck_num * sizeof(char *)); for (i = 0; i < nextcheck_num; i++) { itemids[i] = nextchecks[i].itemid; timespecs[i] = nextchecks[i].ts; errors[i] = nextchecks[i].error_msg; } zbx_hashset_create(&trigger_info, MAX(100, 2 * nextcheck_num), ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_ptr_create(&trigger_order); zbx_vector_ptr_reserve(&trigger_order, nextcheck_num); DCconfig_get_triggers_by_itemids(&trigger_info, &trigger_order, itemids, timespecs, errors, nextcheck_num, 0); zbx_free(errors); zbx_free(timespecs); zbx_free(itemids); for (i = 0; i < trigger_order.values_num; i++) { trigger = (DC_TRIGGER *)trigger_order.values[i]; trigger->new_value = TRIGGER_VALUE_UNKNOWN; } zbx_process_triggers(&trigger_order, trigger_diff); DCfree_triggers(&trigger_order); zbx_hashset_destroy(&trigger_info); zbx_vector_ptr_destroy(&trigger_order); DCclean_nextchecks(); exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/************************************************************************************ * * * Function: sql_writer_init * * * * Purpose: initializes sql writer for a new batch of history values * * * ************************************************************************************/ static void sql_writer_init(void) { if (0 != writer.initialized) return; zbx_vector_ptr_create(&writer.dbinserts); writer.initialized = 1; }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ ZBX_THREAD_ENTRY(watchdog_thread, args) { int now, nextsync = 0, action; double sec; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); sec = zbx_time(); action = 0; if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); action = 1; } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; action = 2; } DBclose(); sec = zbx_time() - sec; if (1 == action) { zbx_setproctitle("%s [database is down, checking took " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } else if (2 == action) { zbx_setproctitle("%s [synced alerts config in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } zbx_sleep_loop(DB_PING_FREQUENCY); } }
static int lld_rows_get(char *value, lld_filter_t *filter, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_rows_get"; struct zbx_json_parse jp, jp_data, jp_row; const char *p; zbx_lld_row_t *lld_row; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != zbx_json_open(value, &jp)) { *error = zbx_strdup(*error, "Value should be a JSON object."); goto out; } /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^-------------------------------------------^ */ if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { *error = zbx_dsprintf(*error, "Cannot find the \"%s\" array in the received JSON object.", ZBX_PROTO_TAG_DATA); goto out; } p = NULL; /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^ */ while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^------------------^ */ if (FAIL == zbx_json_brackets_open(p, &jp_row)) continue; if (SUCCEED != filter_evaluate(filter, &jp_row)) continue; lld_row = zbx_malloc(NULL, sizeof(zbx_lld_row_t)); lld_row->jp_row = jp_row; zbx_vector_ptr_create(&lld_row->item_links); zbx_vector_ptr_append(lld_rows, lld_row); } ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: lld_triggers_get * * * * Purpose: retrieve triggers which were created by the specified trigger * * prototype * * * * Parameters: parent_triggerid - [IN] trigger prototype identificator * * triggers - [OUT] sorted list of triggers * * * ******************************************************************************/ static void lld_triggers_get(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *triggers, unsigned char type, unsigned char priority, const char *url) { const char *__function_name = "lld_triggers_get"; DB_RESULT result; DB_ROW row; zbx_lld_trigger_t *trigger; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect( "select t.triggerid,t.description,t.expression,t.type,t.priority,t.comments,t.url" " from triggers t,trigger_discovery td" " where t.triggerid=td.triggerid" " and td.parent_triggerid=" ZBX_FS_UI64, parent_triggerid); while (NULL != (row = DBfetch(result))) { trigger = zbx_malloc(NULL, sizeof(zbx_lld_trigger_t)); ZBX_STR2UINT64(trigger->triggerid, row[0]); trigger->description = zbx_strdup(NULL, row[1]); trigger->description_orig = NULL; trigger->expression = zbx_strdup(NULL, row[2]); trigger->expression_orig = NULL; trigger->flags = ZBX_FLAG_LLD_TRIGGER_UNSET; if ((unsigned char)atoi(row[3]) != type) trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_TYPE; if ((unsigned char)atoi(row[4]) != priority) trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_PRIORITY; trigger->comments = zbx_strdup(NULL, row[5]); trigger->comments_orig = NULL; if (0 != strcmp(row[6], url)) trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_URL; zbx_vector_ptr_create(&trigger->functions); zbx_vector_ptr_append(triggers, trigger); } DBfree_result(result); zbx_vector_ptr_sort(triggers, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: db_update_host_maintenances * * * * Purpose: update host maintenance parameters in cache and database * * * ******************************************************************************/ static int update_host_maintenances(void) { zbx_vector_uint64_t maintenanceids; zbx_vector_ptr_t updates; int hosts_num = 0; int tnx_error; zbx_vector_uint64_create(&maintenanceids); zbx_vector_ptr_create(&updates); zbx_vector_ptr_reserve(&updates, 100); do { DBbegin(); if (SUCCEED == zbx_dc_get_running_maintenanceids(&maintenanceids)) zbx_db_lock_maintenanceids(&maintenanceids); /* host maintenance update must be called even with no maintenances running */ /* to reset host maintenance status if necessary */ zbx_dc_get_host_maintenance_updates(&maintenanceids, &updates); if (0 != updates.values_num) db_update_host_maintenances(&updates); if (ZBX_DB_OK == (tnx_error = DBcommit()) && 0 != (hosts_num = updates.values_num)) zbx_dc_flush_host_maintenance_updates(&updates); zbx_vector_ptr_clear_ext(&updates, (zbx_clean_func_t)zbx_ptr_free); zbx_vector_uint64_clear(&maintenanceids); } while (ZBX_DB_DOWN == tnx_error); zbx_vector_ptr_destroy(&updates); zbx_vector_uint64_destroy(&maintenanceids); return hosts_num; }
static void init_active_metrics(void) { size_t sz; zabbix_log(LOG_LEVEL_DEBUG, "In init_active_metrics()"); active_metrics = zbx_malloc(active_metrics, sizeof(ZBX_ACTIVE_METRIC)); active_metrics->key = NULL; if (NULL == buffer.data) { zabbix_log(LOG_LEVEL_DEBUG, "buffer: first allocation for %d elements", CONFIG_BUFFER_SIZE); sz = CONFIG_BUFFER_SIZE * sizeof(ZBX_ACTIVE_BUFFER_ELEMENT); buffer.data = zbx_malloc(buffer.data, sz); memset(buffer.data, 0, sz); buffer.count = 0; buffer.pcount = 0; buffer.lastsent = (int)time(NULL); buffer.first_error = 0; } zbx_vector_ptr_create(®exps); }
static void lld_graphs_save(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *graphs, int width, int height, double yaxismin, double yaxismax, unsigned char show_work_period, unsigned char show_triggers, unsigned char graphtype, unsigned char show_legend, unsigned char show_3d, double percent_left, double percent_right, unsigned char ymin_type, unsigned char ymax_type) { const char *__function_name = "lld_graphs_save"; int i, j, new_graphs = 0, upd_graphs = 0, new_gitems = 0; zbx_lld_graph_t *graph; zbx_lld_gitem_t *gitem; zbx_vector_ptr_t upd_gitems; /* the ordered list of graphs_items which will be updated */ zbx_vector_uint64_t del_gitemids; zbx_uint64_t graphid = 0, graphdiscoveryid = 0, gitemid = 0; char *sql = NULL, *name_esc, *color_esc; size_t sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0; zbx_db_insert_t db_insert, db_insert_gdiscovery, db_insert_gitems; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&upd_gitems); zbx_vector_uint64_create(&del_gitemids); for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED)) continue; if (0 == graph->graphid) new_graphs++; else if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE)) upd_graphs++; for (j = 0; j < graph->gitems.values_num; j++) { gitem = (zbx_lld_gitem_t *)graph->gitems.values[j]; if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_DELETE)) { zbx_vector_uint64_append(&del_gitemids, gitem->gitemid); continue; } if (0 == (gitem->flags & ZBX_FLAG_LLD_GITEM_DISCOVERED)) continue; if (0 == gitem->gitemid) new_gitems++; else if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE)) zbx_vector_ptr_append(&upd_gitems, gitem); } } if (0 == new_graphs && 0 == new_gitems && 0 == upd_graphs && 0 == upd_gitems.values_num && 0 == del_gitemids.values_num) { goto out; } DBbegin(); if (0 != new_graphs) { graphid = DBget_maxid_num("graphs", new_graphs); graphdiscoveryid = DBget_maxid_num("graph_discovery", new_graphs); zbx_db_insert_prepare(&db_insert, "graphs", "graphid", "name", "width", "height", "yaxismin", "yaxismax", "show_work_period", "show_triggers", "graphtype", "show_legend", "show_3d", "percent_left", "percent_right", "ymin_type", "ymin_itemid", "ymax_type", "ymax_itemid", "flags", NULL); zbx_db_insert_prepare(&db_insert_gdiscovery, "graph_discovery", "graphdiscoveryid", "graphid", "parent_graphid", NULL); } if (0 != new_gitems) { gitemid = DBget_maxid_num("graphs_items", new_gitems); zbx_db_insert_prepare(&db_insert_gitems, "graphs_items", "gitemid", "graphid", "itemid", "drawtype", "sortorder", "color", "yaxisside", "calc_fnc", "type", NULL); } if (0 != upd_graphs || 0 != upd_gitems.values_num || 0 != del_gitemids.values_num) { sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); } for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED)) continue; if (0 == graph->graphid) { zbx_db_insert_add_values(&db_insert, graphid, graph->name, width, height, yaxismin, yaxismax, (int)show_work_period, (int)show_triggers, (int)graphtype, (int)show_legend, (int)show_3d, percent_left, percent_right, (int)ymin_type, graph->ymin_itemid, (int)ymax_type, graph->ymax_itemid, (int)ZBX_FLAG_DISCOVERY_CREATED); zbx_db_insert_add_values(&db_insert_gdiscovery, graphdiscoveryid, graphid, parent_graphid); graph->graphid = graphid++; graphdiscoveryid++; } else if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE)) { const char *d = ""; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update graphs set "); if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME)) { name_esc = DBdyn_escape_string(graph->name); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "name='%s'", name_esc); zbx_free(name_esc); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_WIDTH)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%swidth=%d", d, width); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_HEIGHT)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sheight=%d", d, height); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMIN)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxismin=" ZBX_FS_DBL, d, yaxismin); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMAX)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxismax=" ZBX_FS_DBL, d, yaxismax); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_WORK_PERIOD)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_work_period=%d", d, (int)show_work_period); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_TRIGGERS)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_triggers=%d", d, (int)show_triggers); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_GRAPHTYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sgraphtype=%d", d, (int)graphtype); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_LEGEND)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_legend=%d", d, (int)show_legend); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_3D)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_3d=%d", d, (int)show_3d); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_LEFT)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spercent_left=" ZBX_FS_DBL, d, percent_left); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_RIGHT)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spercent_right=" ZBX_FS_DBL, d, percent_right); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_TYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symin_type=%d", d, (int)ymin_type); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symin_itemid=%s", d, DBsql_id_ins(graph->ymin_itemid)); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_TYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symax_type=%d", d, (int)ymax_type); d = ","; } if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symax_itemid=%s", d, DBsql_id_ins(graph->ymax_itemid)); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where graphid=" ZBX_FS_UI64 ";\n", graph->graphid); } for (j = 0; j < graph->gitems.values_num; j++) { gitem = (zbx_lld_gitem_t *)graph->gitems.values[j]; if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_DELETE)) continue; if (0 == (gitem->flags & ZBX_FLAG_LLD_GITEM_DISCOVERED)) continue; if (0 == gitem->gitemid) { zbx_db_insert_add_values(&db_insert_gitems, gitemid, graph->graphid, gitem->itemid, (int)gitem->drawtype, gitem->sortorder, gitem->color, (int)gitem->yaxisside, (int)gitem->calc_fnc, (int)gitem->type); gitem->gitemid = gitemid++; } } } for (i = 0; i < upd_gitems.values_num; i++) { const char *d = ""; gitem = (zbx_lld_gitem_t *)upd_gitems.values[i]; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update graphs_items set "); if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64, gitem->itemid); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_DRAWTYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdrawtype=%d", d, (int)gitem->drawtype); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_SORTORDER)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%ssortorder=%d", d, gitem->sortorder); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_COLOR)) { color_esc = DBdyn_escape_string(gitem->color); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scolor='%s'", d, color_esc); zbx_free(color_esc); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_YAXISSIDE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxisside=%d", d, (int)gitem->yaxisside); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_CALC_FNC)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scalc_fnc=%d", d, (int)gitem->calc_fnc); d = ","; } if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_TYPE)) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)gitem->type); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where gitemid=" ZBX_FS_UI64 ";\n", gitem->gitemid); } if (0 != del_gitemids.values_num) { zbx_vector_uint64_sort(&del_gitemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from graphs_items where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "gitemid", del_gitemids.values, del_gitemids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); } if (0 != upd_graphs || 0 != upd_gitems.values_num || 0 != del_gitemids.values_num) { DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); zbx_free(sql); } if (0 != new_graphs) { zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); zbx_db_insert_execute(&db_insert_gdiscovery); zbx_db_insert_clean(&db_insert_gdiscovery); } if (0 != new_gitems) { zbx_db_insert_execute(&db_insert_gitems); zbx_db_insert_clean(&db_insert_gitems); } DBcommit(); out: zbx_vector_uint64_destroy(&del_gitemids); zbx_vector_ptr_destroy(&upd_gitems); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_graph_make * * * * Purpose: create a graph based on lld rule and add it to the list * * * ******************************************************************************/ static void lld_graph_make(zbx_vector_ptr_t *gitems_proto, zbx_vector_ptr_t *graphs, zbx_vector_ptr_t *items, const char *name_proto, zbx_uint64_t ymin_itemid_proto, zbx_uint64_t ymax_itemid_proto, zbx_lld_row_t *lld_row) { const char *__function_name = "lld_graph_make"; zbx_lld_graph_t *graph = NULL; char *buffer = NULL; struct zbx_json_parse *jp_row = &lld_row->jp_row; zbx_uint64_t ymin_itemid, ymax_itemid; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (0 == ymin_itemid_proto) ymin_itemid = 0; else if (SUCCEED != lld_item_get(ymin_itemid_proto, items, &lld_row->item_links, &ymin_itemid)) goto out; if (0 == ymax_itemid_proto) ymax_itemid = 0; else if (SUCCEED != lld_item_get(ymax_itemid_proto, items, &lld_row->item_links, &ymax_itemid)) goto out; if (NULL != (graph = lld_graph_get(gitems_proto, graphs, &lld_row->item_links))) { buffer = zbx_strdup(buffer, name_proto); substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_SIMPLE, NULL, 0); zbx_lrtrim(buffer, ZBX_WHITESPACE); if (0 != strcmp(graph->name, buffer)) { graph->name_orig = graph->name; graph->name = buffer; buffer = NULL; graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_NAME; } if (graph->ymin_itemid != ymin_itemid) { graph->ymin_itemid = ymin_itemid; graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_ITEMID; } if (graph->ymax_itemid != ymax_itemid) { graph->ymax_itemid = ymax_itemid; graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_ITEMID; } } else { graph = zbx_malloc(NULL, sizeof(zbx_lld_graph_t)); graph->graphid = 0; graph->name = zbx_strdup(NULL, name_proto); graph->name_orig = NULL; substitute_discovery_macros(&graph->name, jp_row, ZBX_MACRO_SIMPLE, NULL, 0); zbx_lrtrim(graph->name, ZBX_WHITESPACE); graph->ymin_itemid = ymin_itemid; graph->ymax_itemid = ymax_itemid; zbx_vector_ptr_create(&graph->gitems); graph->flags = ZBX_FLAG_LLD_GRAPH_UNSET; zbx_vector_ptr_append(graphs, graph); } zbx_free(buffer); if (SUCCEED != lld_gitems_make(gitems_proto, &graph->gitems, items, &lld_row->item_links)) return; graph->flags |= ZBX_FLAG_LLD_GRAPH_DISCOVERED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_graphs_get * * * * Purpose: retrieve graphs which were created by the specified graph * * prototype * * * * Parameters: parent_graphid - [IN] graph prototype identificator * * graphs - [OUT] sorted list of graphs * * * ******************************************************************************/ static void lld_graphs_get(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *graphs, int width, int height, double yaxismin, double yaxismax, unsigned char show_work_period, unsigned char show_triggers, unsigned char graphtype, unsigned char show_legend, unsigned char show_3d, double percent_left, double percent_right, unsigned char ymin_type, unsigned char ymax_type) { const char *__function_name = "lld_graphs_get"; DB_RESULT result; DB_ROW row; zbx_lld_graph_t *graph; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect( "select g.graphid,g.name,g.width,g.height,g.yaxismin,g.yaxismax,g.show_work_period," "g.show_triggers,g.graphtype,g.show_legend,g.show_3d,g.percent_left,g.percent_right," "g.ymin_type,g.ymin_itemid,g.ymax_type,g.ymax_itemid" " from graphs g,graph_discovery gd" " where g.graphid=gd.graphid" " and gd.parent_graphid=" ZBX_FS_UI64, parent_graphid); while (NULL != (row = DBfetch(result))) { graph = zbx_malloc(NULL, sizeof(zbx_lld_graph_t)); ZBX_STR2UINT64(graph->graphid, row[0]); graph->name = zbx_strdup(NULL, row[1]); graph->name_orig = NULL; graph->flags = ZBX_FLAG_LLD_GRAPH_UNSET; if (atoi(row[2]) != width) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_WIDTH; if (atoi(row[3]) != height) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_HEIGHT; if (atof(row[4]) != yaxismin) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMIN; if (atof(row[5]) != yaxismax) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMAX; if ((unsigned char)atoi(row[6]) != show_work_period) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_WORK_PERIOD; if ((unsigned char)atoi(row[7]) != show_triggers) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_TRIGGERS; if ((unsigned char)atoi(row[8]) != graphtype) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_GRAPHTYPE; if ((unsigned char)atoi(row[9]) != show_legend) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_LEGEND; if ((unsigned char)atoi(row[10]) != show_3d) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_3D; if (atof(row[11]) != percent_left) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_LEFT; if (atof(row[12]) != percent_right) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_RIGHT; if ((unsigned char)atoi(row[13]) != ymin_type) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_TYPE; ZBX_DBROW2UINT64(graph->ymin_itemid, row[14]); if ((unsigned char)atoi(row[15]) != ymax_type) graph->flags |= ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_TYPE; ZBX_DBROW2UINT64(graph->ymax_itemid, row[16]); zbx_vector_ptr_create(&graph->gitems); zbx_vector_ptr_append(graphs, graph); } DBfree_result(result); zbx_vector_ptr_sort(graphs, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_update_graphs * * * * Purpose: add or update graphs for discovery item * * * * Parameters: hostid - [IN] host identificator from database * * agent - [IN] discovery item identificator from database * * jp_data - [IN] received data * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void lld_update_graphs(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_update_graphs"; DB_RESULT result; DB_ROW row; zbx_vector_ptr_t graphs; zbx_vector_ptr_t gitems_proto; zbx_vector_ptr_t items; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&graphs); /* list of graphs which were created or will be created or */ /* updated by the graph prototype */ zbx_vector_ptr_create(&gitems_proto); /* list of graphs_items which are used by the graph prototype */ zbx_vector_ptr_create(&items); /* list of items which are related to the graph prototype */ result = DBselect( "select distinct g.graphid,g.name,g.width,g.height,g.yaxismin,g.yaxismax,g.show_work_period," "g.show_triggers,g.graphtype,g.show_legend,g.show_3d,g.percent_left,g.percent_right," "g.ymin_type,g.ymin_itemid,g.ymax_type,g.ymax_itemid" " from graphs g,graphs_items gi,items i,item_discovery id" " where g.graphid=gi.graphid" " and gi.itemid=i.itemid" " and i.itemid=id.itemid" " and id.parent_itemid=" ZBX_FS_UI64, lld_ruleid); while (NULL != (row = DBfetch(result))) { zbx_uint64_t parent_graphid, ymin_itemid_proto, ymax_itemid_proto; const char *name_proto; int width, height; double yaxismin, yaxismax, percent_left, percent_right; unsigned char show_work_period, show_triggers, graphtype, show_legend, show_3d, ymin_type, ymax_type; ZBX_STR2UINT64(parent_graphid, row[0]); name_proto = row[1]; width = atoi(row[2]); height = atoi(row[3]); yaxismin = atof(row[4]); yaxismax = atof(row[5]); ZBX_STR2UCHAR(show_work_period, row[6]); ZBX_STR2UCHAR(show_triggers, row[7]); ZBX_STR2UCHAR(graphtype, row[8]); ZBX_STR2UCHAR(show_legend, row[9]); ZBX_STR2UCHAR(show_3d, row[10]); percent_left = atof(row[11]); percent_right = atof(row[12]); ZBX_STR2UCHAR(ymin_type, row[13]); ZBX_DBROW2UINT64(ymin_itemid_proto, row[14]); ZBX_STR2UCHAR(ymax_type, row[15]); ZBX_DBROW2UINT64(ymax_itemid_proto, row[16]); lld_graphs_get(parent_graphid, &graphs, width, height, yaxismin, yaxismax, show_work_period, show_triggers, graphtype, show_legend, show_3d, percent_left, percent_right, ymin_type, ymax_type); lld_gitems_get(parent_graphid, &gitems_proto, &graphs); lld_items_get(&gitems_proto, ymin_itemid_proto, ymax_itemid_proto, &items); /* making graphs */ lld_graphs_make(&gitems_proto, &graphs, &items, name_proto, ymin_itemid_proto, ymax_itemid_proto, lld_rows); lld_graphs_validate(hostid, &graphs, error); lld_graphs_save(parent_graphid, &graphs, width, height, yaxismin, yaxismax, show_work_period, show_triggers, graphtype, show_legend, show_3d, percent_left, percent_right, ymin_type, ymax_type); lld_items_free(&items); lld_gitems_free(&gitems_proto); lld_graphs_free(&graphs); } DBfree_result(result); zbx_vector_ptr_destroy(&items); zbx_vector_ptr_destroy(&gitems_proto); zbx_vector_ptr_destroy(&graphs); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: zbx_procstat_collect * * * * Purpose: performs process statistics collection * * * ******************************************************************************/ void zbx_procstat_collect() { /* identifies current collection iteration */ static int runid = 1; /* number of (non-unique) pids that match queries */ int pids_num = 0; /* flags specifying what process properties must be retrieved */ int flags; /* local, working copy of queries */ zbx_vector_ptr_t queries; /* data about all processes on system */ zbx_vector_ptr_t processes; /* pids (unique) for which to collect data in this iteration */ zbx_vector_uint64_t pids; /* current reading of the per-pid cpu usage statistics (array, items correspond to pids) */ zbx_procstat_util_t *stats; /* time of the per-pid usage statistics collection */ zbx_timespec_t snapshot_timestamp; if (FAIL == zbx_procstat_collector_started() || FAIL == procstat_running()) goto out; zbx_vector_ptr_create(&queries); zbx_vector_ptr_create(&processes); zbx_vector_uint64_create(&pids); if (ZBX_SYSINFO_PROC_NONE == (flags = procstat_build_local_query_vector(&queries, runid))) goto clean; if (SUCCEED != zbx_proc_get_processes(&processes, flags)) goto clean; pids_num = procstat_scan_query_pids(&queries, &processes); procstat_get_monitored_pids(&pids, &queries, pids_num); stats = (zbx_procstat_util_t *)zbx_malloc(NULL, sizeof(zbx_procstat_util_t) * pids.values_num); snapshot_timestamp = procstat_get_cpu_util_snapshot_for_pids(stats, &pids); procstat_calculate_cpu_util_for_queries(&queries, &pids, stats); procstat_update_query_statistics(&queries, runid, &snapshot_timestamp); /* replace the current snapshot with the new stats */ zbx_free(procstat_snapshot); procstat_snapshot = stats; procstat_snapshot_num = pids.values_num; clean: zbx_vector_uint64_destroy(&pids); zbx_proc_free_processes(&processes); zbx_vector_ptr_destroy(&processes); zbx_vector_ptr_clear_ext(&queries, (zbx_mem_free_func_t)procstat_free_query_data); zbx_vector_ptr_destroy(&queries); out: runid++; }
static int lld_rows_get(char *value, char *filter, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_rows_get"; struct zbx_json_parse jp, jp_data, jp_row; char *f_macro = NULL, *f_regexp = NULL; const char *p; zbx_vector_ptr_t regexps; zbx_lld_row_t *lld_row; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (SUCCEED != zbx_json_open(value, &jp)) { *error = zbx_strdup(*error, "Value should be a JSON object."); goto out; } /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^-------------------------------------------^ */ if (SUCCEED != zbx_json_brackets_by_name(&jp, ZBX_PROTO_TAG_DATA, &jp_data)) { *error = zbx_dsprintf(*error, "Cannot find the \"%s\" array in the received JSON object.", ZBX_PROTO_TAG_DATA); goto out; } zbx_vector_ptr_create(®exps); if (NULL != (f_regexp = strchr(filter, ':'))) { f_macro = filter; *f_regexp++ = '\0'; if ('@' == *f_regexp) DCget_expressions_by_name(®exps, f_regexp + 1); zabbix_log(LOG_LEVEL_DEBUG, "%s() f_macro:'%s' f_regexp:'%s'", __function_name, f_macro, f_regexp); } p = NULL; /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^ */ while (NULL != (p = zbx_json_next(&jp_data, p))) { /* {"data":[{"{#IFNAME}":"eth0"},{"{#IFNAME}":"lo"},...]} */ /* ^------------------^ */ if (FAIL == zbx_json_brackets_open(p, &jp_row)) continue; if (NULL != f_macro && SUCCEED != lld_check_record(&jp_row, f_macro, f_regexp, ®exps)) continue; lld_row = zbx_malloc(NULL, sizeof(zbx_lld_row_t)); memcpy(&lld_row->jp_row, &jp_row, sizeof(struct zbx_json_parse)); zbx_vector_ptr_create(&lld_row->item_links); zbx_vector_ptr_append(lld_rows, lld_row); } zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: db_update_event_suppress_data * * * * Purpose: create/update event suppress data to reflect latest maintenance * * changes in cache * * * * Parameters: suppressed_num - [OUT] the number of suppressed events * * * ******************************************************************************/ static void db_update_event_suppress_data(int *suppressed_num) { zbx_vector_ptr_t event_queries, event_data; *suppressed_num = 0; zbx_vector_ptr_create(&event_queries); zbx_vector_ptr_create(&event_data); db_get_query_events(&event_queries, &event_data); if (0 != event_queries.values_num) { zbx_db_insert_t db_insert; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; int i, j, k; zbx_event_suppress_query_t *query; zbx_event_suppress_data_t *data; zbx_vector_uint64_pair_t del_event_maintenances; zbx_vector_uint64_t maintenanceids; zbx_uint64_pair_t pair; zbx_vector_uint64_create(&maintenanceids); zbx_vector_uint64_pair_create(&del_event_maintenances); db_get_query_functions(&event_queries); db_get_query_tags(&event_queries); zbx_dc_get_running_maintenanceids(&maintenanceids); DBbegin(); if (0 != maintenanceids.values_num && SUCCEED == zbx_db_lock_maintenanceids(&maintenanceids)) zbx_dc_get_event_maintenances(&event_queries, &maintenanceids); zbx_db_insert_prepare(&db_insert, "event_suppress", "event_suppressid", "eventid", "maintenanceid", "suppress_until", NULL); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); for (i = 0; i < event_queries.values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries.values[i]; zbx_vector_uint64_pair_sort(&query->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC); k = 0; if (FAIL != (j = zbx_vector_ptr_bsearch(&event_data, &query->eventid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { data = (zbx_event_suppress_data_t *)event_data.values[j]; zbx_vector_uint64_pair_sort(&data->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC); j = 0; while (j < data->maintenances.values_num && k < query->maintenances.values_num) { if (data->maintenances.values[j].first < query->maintenances.values[k].first) { pair.first = query->eventid; pair.second = data->maintenances.values[j].first; zbx_vector_uint64_pair_append(&del_event_maintenances, pair); j++; continue; } if (data->maintenances.values[j].first > query->maintenances.values[k].first) { if (0 == query->r_eventid) { zbx_db_insert_add_values(&db_insert, __UINT64_C(0), query->eventid, query->maintenances.values[k].first, (int)query->maintenances.values[k].second); (*suppressed_num)++; } k++; continue; } if (data->maintenances.values[j].second != query->maintenances.values[k].second) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update event_suppress" " set suppress_until=%d" " where eventid=" ZBX_FS_UI64 " and maintenanceid=" ZBX_FS_UI64 ";\n", (int)query->maintenances.values[k].second, query->eventid, query->maintenances.values[k].first); if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) goto cleanup; } j++; k++; } for (;j < data->maintenances.values_num; j++) { pair.first = query->eventid; pair.second = data->maintenances.values[j].first; zbx_vector_uint64_pair_append(&del_event_maintenances, pair); } } if (0 == query->r_eventid) { for (;k < query->maintenances.values_num; k++) { zbx_db_insert_add_values(&db_insert, __UINT64_C(0), query->eventid, query->maintenances.values[k].first, (int)query->maintenances.values[k].second); (*suppressed_num)++; } } } for (i = 0; i < del_event_maintenances.values_num; i++) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from event_suppress" " where eventid=" ZBX_FS_UI64 " and maintenanceid=" ZBX_FS_UI64 ";\n", del_event_maintenances.values[i].first, del_event_maintenances.values[i].second); if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) goto cleanup; } DBend_multiple_update(&sql, &sql_alloc, &sql_offset); if (16 < sql_offset) { if (ZBX_DB_OK > DBexecute("%s", sql)) goto cleanup; } zbx_db_insert_autoincrement(&db_insert, "event_suppressid"); zbx_db_insert_execute(&db_insert); cleanup: DBcommit(); zbx_db_insert_clean(&db_insert); zbx_free(sql); zbx_vector_uint64_pair_destroy(&del_event_maintenances); zbx_vector_uint64_destroy(&maintenanceids); } zbx_vector_ptr_clear_ext(&event_data, (zbx_clean_func_t)event_suppress_data_free); zbx_vector_ptr_destroy(&event_data); zbx_vector_ptr_clear_ext(&event_queries, (zbx_clean_func_t)zbx_event_suppress_query_free); zbx_vector_ptr_destroy(&event_queries); }
/****************************************************************************** * * * Function: save_template_item_applications * * * * Purpose: saves new item applications links in database * * * * Parameters: items - [IN] the template items * * * ******************************************************************************/ void save_template_item_applications(zbx_vector_ptr_t *items) { typedef struct { zbx_uint64_t itemid; zbx_uint64_t applicationid; } zbx_itemapp_t; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_vector_uint64_t itemids; zbx_vector_ptr_t itemapps; zbx_itemapp_t *itemapp; int i; zbx_db_insert_t db_insert; zbx_vector_ptr_create(&itemapps); zbx_vector_uint64_create(&itemids); for (i = 0; i < items->values_num; i++) { zbx_template_item_t *item = items->values[i]; zbx_vector_uint64_append(&itemids, item->itemid); } zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select hi.itemid,ha.applicationid" " from items_applications tia" " join items hi on hi.templateid=tia.itemid" " and"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hi.itemid", itemids.values, itemids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " join application_template hat on hat.templateid=tia.applicationid" " join applications ha on ha.applicationid=hat.applicationid" " and ha.hostid=hi.hostid" " left join items_applications hia on hia.applicationid=ha.applicationid" " and hia.itemid=hi.itemid" " where hia.itemappid is null"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { itemapp = zbx_malloc(NULL, sizeof(zbx_itemapp_t)); ZBX_STR2UINT64(itemapp->itemid, row[0]); ZBX_STR2UINT64(itemapp->applicationid, row[1]); zbx_vector_ptr_append(&itemapps, itemapp); } DBfree_result(result); if (0 == itemapps.values_num) goto out; zbx_db_insert_prepare(&db_insert, "items_applications", "itemappid", "itemid", "applicationid", NULL); for (i = 0; i < itemapps.values_num; i++) { itemapp = itemapps.values[i]; zbx_db_insert_add_values(&db_insert, __UINT64_C(0), itemapp->itemid, itemapp->applicationid); } zbx_db_insert_autoincrement(&db_insert, "itemappid"); zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); out: zbx_free(sql); zbx_vector_uint64_destroy(&itemids); zbx_vector_ptr_clear_ext(&itemapps, zbx_ptr_free); zbx_vector_ptr_destroy(&itemapps); }
/****************************************************************************** * * * Function: recv_getqueue * * * * Purpose: process queue request * * * * Parameters: sock - [IN] the request socket * * jp - [IN] the request data * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * ******************************************************************************/ static int recv_getqueue(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "recv_getqueue"; int ret = FAIL, request_type = -1, now, i; char type[MAX_STRING_LEN], sessionid[MAX_STRING_LEN]; zbx_vector_ptr_t queue; struct zbx_json json; zbx_hashset_t queue_stats; zbx_queue_stats_t *stats; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_SID, sessionid, sizeof(sessionid)) || FAIL == zbx_session_validate(sessionid, USER_TYPE_SUPER_ADMIN)) { zbx_send_response_raw(sock, ret, "Permission denied.", CONFIG_TIMEOUT); goto out; } if (FAIL != zbx_json_value_by_name(jp, ZBX_PROTO_TAG_TYPE, type, sizeof(type))) { if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_OVERVIEW)) request_type = ZBX_GET_QUEUE_OVERVIEW; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_PROXY)) request_type = ZBX_GET_QUEUE_PROXY; else if (0 == strcmp(type, ZBX_PROTO_VALUE_GET_QUEUE_DETAILS)) request_type = ZBX_GET_QUEUE_DETAILS; } if (-1 == request_type) { zbx_send_response_raw(sock, ret, "Unsupported request type.", CONFIG_TIMEOUT); goto out; } now = time(NULL); zbx_vector_ptr_create(&queue); DCget_item_queue(&queue, 6, -1); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); switch (request_type) { case ZBX_GET_QUEUE_OVERVIEW: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by item type */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->type; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "itemtype", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_PROXY: zbx_hashset_create(&queue_stats, 32, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); /* gather queue stats by proxy hostid */ for (i = 0; i < queue.values_num; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_uint64_t id = item->proxy_hostid; if (NULL == (stats = zbx_hashset_search(&queue_stats, &id))) { zbx_queue_stats_t data = {id}; stats = zbx_hashset_insert(&queue_stats, &data, sizeof(data)); } queue_stats_update(stats, now - item->nextcheck); } zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); queue_stats_export(&queue_stats, "proxyid", &json); zbx_hashset_destroy(&queue_stats); break; case ZBX_GET_QUEUE_DETAILS: zbx_vector_ptr_sort(&queue, (zbx_compare_func_t)queue_compare_by_nextcheck_asc); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); for (i = 0; i < queue.values_num && i <= 500; i++) { zbx_queue_item_t *item = queue.values[i]; zbx_json_addobject(&json, NULL); zbx_json_adduint64(&json, "itemid", item->itemid); zbx_json_adduint64(&json, "nextcheck", item->nextcheck); zbx_json_close(&json); } zbx_json_close(&json); break; } zabbix_log(LOG_LEVEL_DEBUG, "%s() json.buffer:'%s'", __function_name, json.buffer); zbx_tcp_send_raw(sock, json.buffer); DCfree_item_queue(&queue); zbx_vector_ptr_destroy(&queue); zbx_json_free(&json); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return ret; }
/****************************************************************************** * * * Function: lld_update_triggers * * * * Purpose: add or update triggers for discovered items * * * ******************************************************************************/ void lld_update_triggers(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *lld_rows, char **error) { const char *__function_name = "lld_update_triggers"; DB_RESULT result; DB_ROW row; zbx_vector_ptr_t triggers; zbx_vector_ptr_t functions_proto; zbx_vector_ptr_t items; zbx_lld_trigger_t *trigger; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&triggers); /* list of triggers which were created or will be created or */ /* updated by the trigger prototype */ zbx_vector_ptr_create(&functions_proto); /* list of functions which are used by the trigger prototype */ zbx_vector_ptr_create(&items); /* list of items which are related to the trigger prototype */ result = DBselect( "select distinct t.triggerid,t.description,t.expression,t.status,t.type,t.priority,t.comments," "t.url" " from triggers t,functions f,items i,item_discovery id" " where t.triggerid=f.triggerid" " and f.itemid=i.itemid" " and i.itemid=id.itemid" " and id.parent_itemid=" ZBX_FS_UI64, lld_ruleid); /* run through trigger prototypes */ while (NULL != (row = DBfetch(result))) { zbx_uint64_t parent_triggerid; const char *description_proto, *comments_proto, *url; char *expression_proto; unsigned char status, type, priority; int i; ZBX_STR2UINT64(parent_triggerid, row[0]); description_proto = row[1]; expression_proto = zbx_strdup(NULL, row[2]); ZBX_STR2UCHAR(status, row[3]); ZBX_STR2UCHAR(type, row[4]); ZBX_STR2UCHAR(priority, row[5]); comments_proto = row[6]; url = row[7]; lld_triggers_get(parent_triggerid, &triggers, type, priority, url); lld_functions_get(parent_triggerid, &functions_proto, &triggers); lld_items_get(parent_triggerid, &items); /* simplifying trigger expressions */ lld_expression_simplify(&expression_proto, &functions_proto); for (i = 0; i < triggers.values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers.values[i]; lld_expression_simplify(&trigger->expression, &trigger->functions); } /* making triggers */ lld_triggers_make(&functions_proto, &triggers, &items, description_proto, expression_proto, comments_proto, lld_rows, error); lld_triggers_validate(hostid, &triggers, error); lld_triggers_save(parent_triggerid, &triggers, status, type, priority, url); /* cleaning */ zbx_vector_ptr_clean(&items, (zbx_mem_free_func_t)lld_item_free); zbx_vector_ptr_clean(&functions_proto, (zbx_mem_free_func_t)lld_function_free); zbx_vector_ptr_clean(&triggers, (zbx_mem_free_func_t)lld_trigger_free); zbx_free(expression_proto); } DBfree_result(result); zbx_vector_ptr_destroy(&items); zbx_vector_ptr_destroy(&functions_proto); zbx_vector_ptr_destroy(&triggers); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_triggers_save * * * * Purpose: add or update triggers in database based on discovery rule * * * ******************************************************************************/ static void lld_triggers_save(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *triggers, unsigned char status, unsigned char type, unsigned char priority, const char *url) { const char *__function_name = "lld_triggers_save"; int i, j, new_triggers = 0, upd_triggers = 0, new_functions = 0; zbx_lld_trigger_t *trigger; zbx_lld_function_t *function; zbx_vector_ptr_t upd_functions; /* the ordered list of functions which will be updated */ zbx_vector_uint64_t del_functionids; zbx_uint64_t triggerid = 0, functionid = 0; unsigned char flags = ZBX_FLAG_LLD_TRIGGER_UNSET; char *sql = NULL, *url_esc = NULL, *function_esc, *parameter_esc; size_t sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0; zbx_db_insert_t db_insert, db_insert_tdiscovery, db_insert_tfunctions; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&upd_functions); zbx_vector_uint64_create(&del_functionids); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; if (0 == trigger->triggerid) { new_triggers++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { upd_triggers++; flags |= trigger->flags; } for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) { zbx_vector_uint64_append(&del_functionids, function->functionid); continue; } if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) new_functions++; else if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE)) zbx_vector_ptr_append(&upd_functions, function); } } if (0 == new_triggers && 0 == new_functions && 0 == upd_triggers && 0 == upd_functions.values_num && 0 == del_functionids.values_num) { goto out; } DBbegin(); if (0 != new_triggers) { triggerid = DBget_maxid_num("triggers", new_triggers); zbx_db_insert_prepare(&db_insert, "triggers", "triggerid", "description", "expression", "priority", "status", "comments", "url", "type", "value", "state", "flags", NULL); zbx_db_insert_prepare(&db_insert_tdiscovery, "trigger_discovery", "triggerid", "parent_triggerid", NULL); } if (0 != new_functions) { functionid = DBget_maxid_num("functions", new_functions); zbx_db_insert_prepare(&db_insert_tfunctions, "functions", "functionid", "itemid", "triggerid", "function", "parameter", NULL); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); } if (0 != (flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) url_esc = DBdyn_escape_string(url); for (i = 0; i < triggers->values_num; i++) { char *description_esc, *expression_esc, *comments_esc; trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) continue; if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) { zbx_db_insert_add_values(&db_insert_tfunctions, functionid, function->itemid, (0 == trigger->triggerid ? triggerid : trigger->triggerid), function->function, function->parameter); function->functionid = functionid++; } } if (0 == trigger->triggerid || 0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) lld_expression_create(&trigger->expression, &trigger->functions); if (0 == trigger->triggerid) { zbx_db_insert_add_values(&db_insert, triggerid, trigger->description, trigger->expression, (int)priority, (int)status, trigger->comments, url, (int)type, (int)TRIGGER_VALUE_OK, (int)TRIGGER_STATE_NORMAL, (int)ZBX_FLAG_DISCOVERY_CREATED); zbx_db_insert_add_values(&db_insert_tdiscovery, triggerid, parent_triggerid); trigger->triggerid = triggerid++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { const char *d = ""; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update triggers set "); if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION)) { description_esc = DBdyn_escape_string(trigger->description); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "description='%s'", description_esc); zbx_free(description_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) { expression_esc = DBdyn_escape_string(trigger->expression); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sexpression='%s'", d, expression_esc); zbx_free(expression_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_TYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)type); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_PRIORITY)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spriority=%d", d, (int)priority); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS)) { comments_esc = DBdyn_escape_string(trigger->comments); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scomments='%s'", d, comments_esc); zbx_free(comments_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%surl='%s'", d, url_esc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where triggerid=" ZBX_FS_UI64 ";\n", trigger->triggerid); } } zbx_free(url_esc); zbx_vector_ptr_sort(&upd_functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < upd_functions.values_num; i++) { const char *d = ""; function = (zbx_lld_function_t *)upd_functions.values[i]; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update functions set "); if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64, function->itemid); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION)) { function_esc = DBdyn_escape_string(function->function); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sfunction='%s'", d, function_esc); zbx_free(function_esc); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER)) { parameter_esc = DBdyn_escape_string(function->parameter); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sparameter='%s'", d, parameter_esc); zbx_free(parameter_esc); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where functionid=" ZBX_FS_UI64 ";\n", function->functionid); } if (0 != del_functionids.values_num) { zbx_vector_uint64_sort(&del_functionids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from functions where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "functionid", del_functionids.values, del_functionids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); zbx_free(sql); } if (0 != new_triggers) { zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); zbx_db_insert_execute(&db_insert_tdiscovery); zbx_db_insert_clean(&db_insert_tdiscovery); } if (0 != new_functions) { zbx_db_insert_execute(&db_insert_tfunctions); zbx_db_insert_clean(&db_insert_tfunctions); } DBcommit(); out: zbx_vector_uint64_destroy(&del_functionids); zbx_vector_ptr_destroy(&upd_functions); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_trap_for_interface * * * * Purpose: add trap to all matching items for the specified interface * * * * Return value: SUCCEED - a matching item was found * * FAIL - no matching item was found (including fallback items) * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ static int process_trap_for_interface(zbx_uint64_t interfaceid, char *trap, zbx_timespec_t *ts) { DC_ITEM *items = NULL; const char *regex; char error[ITEM_ERROR_LEN_MAX]; size_t num, i; int ret = FAIL, fb = -1, *lastclocks = NULL, *errcodes = NULL; zbx_uint64_t *itemids = NULL; unsigned char *states = NULL; AGENT_RESULT *results = NULL; AGENT_REQUEST request; zbx_vector_ptr_t regexps; zbx_vector_ptr_create(®exps); num = DCconfig_get_snmp_items_by_interfaceid(interfaceid, &items); itemids = zbx_malloc(itemids, sizeof(zbx_uint64_t) * num); states = zbx_malloc(states, sizeof(unsigned char) * num); lastclocks = zbx_malloc(lastclocks, sizeof(int) * num); errcodes = zbx_malloc(errcodes, sizeof(int) * num); results = zbx_malloc(results, sizeof(AGENT_RESULT) * num); for (i = 0; i < num; i++) { init_result(&results[i]); errcodes[i] = FAIL; items[i].key = zbx_strdup(items[i].key, items[i].key_orig); if (SUCCEED != substitute_key_macros(&items[i].key, NULL, &items[i], NULL, MACRO_TYPE_ITEM_KEY, error, sizeof(error))) { SET_MSG_RESULT(&results[i], zbx_strdup(NULL, error)); errcodes[i] = NOTSUPPORTED; continue; } if (0 == strcmp(items[i].key, "snmptrap.fallback")) { fb = i; continue; } init_request(&request); if (SUCCEED != parse_item_key(items[i].key, &request)) goto next; if (0 != strcmp(get_rkey(&request), "snmptrap")) goto next; if (1 < get_rparams_num(&request)) goto next; if (NULL != (regex = get_rparam(&request, 0))) { if ('@' == *regex) { DCget_expressions_by_name(®exps, regex + 1); if (0 == regexps.values_num) { SET_MSG_RESULT(&results[i], zbx_dsprintf(NULL, "Global regular expression \"%s\" does not exist.", regex + 1)); errcodes[i] = NOTSUPPORTED; goto next; } } if (SUCCEED != regexp_match_ex(®exps, trap, regex, ZBX_CASE_SENSITIVE)) goto next; } if (SUCCEED == set_result_type(&results[i], items[i].value_type, items[i].data_type, trap)) errcodes[i] = SUCCEED; else errcodes[i] = NOTSUPPORTED; ret = SUCCEED; next: free_request(&request); } if (FAIL == ret && -1 != fb) { if (SUCCEED == set_result_type(&results[fb], items[fb].value_type, items[fb].data_type, trap)) errcodes[fb] = SUCCEED; else errcodes[fb] = NOTSUPPORTED; ret = SUCCEED; } for (i = 0; i < num; i++) { switch (errcodes[i]) { case SUCCEED: if (ITEM_VALUE_TYPE_LOG == items[i].value_type) { calc_timestamp(results[i].log->value, &results[i].log->timestamp, items[i].logtimefmt); } items[i].state = ITEM_STATE_NORMAL; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, &results[i], ts, items[i].state, NULL); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; case NOTSUPPORTED: items[i].state = ITEM_STATE_NOTSUPPORTED; dc_add_history(items[i].itemid, items[i].value_type, items[i].flags, NULL, ts, items[i].state, results[i].msg); itemids[i] = items[i].itemid; states[i] = items[i].state; lastclocks[i] = ts->sec; break; } zbx_free(items[i].key); free_result(&results[i]); } zbx_free(results); DCrequeue_items(itemids, states, lastclocks, NULL, NULL, errcodes, num); zbx_free(errcodes); zbx_free(lastclocks); zbx_free(states); zbx_free(itemids); DCconfig_clean_items(items, NULL, num); zbx_free(items); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); dc_flush_history(); return ret; }
/****************************************************************************** * * * Function: lld_process_discovery_rule * * * * Purpose: add or update items, triggers and graphs for discovery item * * * * Parameters: lld_ruleid - [IN] discovery item identificator from database * * value - [IN] received value from agent * * * ******************************************************************************/ void lld_process_discovery_rule(zbx_uint64_t lld_ruleid, char *value, zbx_timespec_t *ts) { const char *__function_name = "lld_process_discovery_rule"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char *discovery_key = NULL, *filter = NULL, *error = NULL, *db_error = NULL, *error_esc; unsigned char state = 0; unsigned short lifetime; zbx_vector_ptr_t lld_rows; char *sql = NULL; size_t sql_alloc = 128, sql_offset = 0; const char *sql_start = "update items set ", *sql_continue = ","; zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, lld_ruleid); zbx_vector_ptr_create(&lld_rows); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select hostid,key_,state,filter,error,lifetime" " from items" " where itemid=" ZBX_FS_UI64, lld_ruleid); if (NULL != (row = DBfetch(result))) { char *lifetime_str; ZBX_STR2UINT64(hostid, row[0]); discovery_key = zbx_strdup(discovery_key, row[1]); state = (unsigned char)atoi(row[2]); filter = zbx_strdup(filter, row[3]); db_error = zbx_strdup(db_error, row[4]); lifetime_str = zbx_strdup(NULL, row[5]); substitute_simple_macros(NULL, NULL, NULL, NULL, &hostid, NULL, NULL, &lifetime_str, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != is_ushort(lifetime_str, &lifetime)) { zabbix_log(LOG_LEVEL_WARNING, "cannot process lost resources for the discovery rule \"%s:%s\":" " \"%s\" is not a valid value", zbx_host_string(hostid), discovery_key, lifetime_str); lifetime = 3650; /* max value for the field */ } zbx_free(lifetime_str); } else zabbix_log(LOG_LEVEL_WARNING, "invalid discovery rule ID [" ZBX_FS_UI64 "]", lld_ruleid); DBfree_result(result); if (0 == hostid) goto clean; if (SUCCEED != lld_rows_get(value, filter, &lld_rows, &error)) goto error; error = zbx_strdup(error, ""); lld_update_items(hostid, lld_ruleid, &lld_rows, &error, lifetime, ts->sec); lld_update_triggers(hostid, lld_ruleid, &lld_rows, &error); lld_update_graphs(hostid, lld_ruleid, &lld_rows, &error); lld_update_hosts(lld_ruleid, &lld_rows, &error, lifetime, ts->sec); if (ITEM_STATE_NOTSUPPORTED == state) { zabbix_log(LOG_LEVEL_WARNING, "discovery rule [" ZBX_FS_UI64 "][%s] became supported", lld_ruleid, zbx_host_key_string(lld_ruleid)); add_event(0, EVENT_SOURCE_INTERNAL, EVENT_OBJECT_LLDRULE, lld_ruleid, ts, ITEM_STATE_NORMAL, NULL, NULL, 0, 0); process_events(); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sstate=%d", sql_start, ITEM_STATE_NORMAL); sql_start = sql_continue; } error: if (NULL != error && 0 != strcmp(error, db_error)) { error_esc = DBdyn_escape_string_len(error, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%serror='%s'", sql_start, error_esc); sql_start = sql_continue; zbx_free(error_esc); } if (sql_start == sql_continue) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64, lld_ruleid); DBbegin(); DBexecute("%s", sql); DBcommit(); } clean: zbx_free(error); zbx_free(db_error); zbx_free(filter); zbx_free(discovery_key); zbx_free(sql); zbx_vector_ptr_clean(&lld_rows, (zbx_mem_free_func_t)lld_row_free); zbx_vector_ptr_destroy(&lld_rows); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_trigger_make * * * * Purpose: create a trigger based on lld rule and add it to the list * * * ******************************************************************************/ static void lld_trigger_make(zbx_vector_ptr_t *functions_proto, zbx_vector_ptr_t *triggers, zbx_vector_ptr_t *items, const char *description_proto, const char *expression_proto, const char *comments_proto, zbx_lld_row_t *lld_row, char **error) { const char *__function_name = "lld_trigger_make"; zbx_lld_trigger_t *trigger = NULL; char *buffer = NULL, *expression = NULL, err[64]; struct zbx_json_parse *jp_row = &lld_row->jp_row; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); trigger = lld_trigger_get(triggers, &lld_row->item_links); expression = zbx_strdup(expression, expression_proto); if (SUCCEED != substitute_discovery_macros(&expression, jp_row, ZBX_MACRO_NUMERIC, err, sizeof(err))) { *error = zbx_strdcatf(*error, "Cannot %s trigger: %s.\n", (NULL != trigger ? "update" : "create"), err); goto out; } if (NULL != trigger) { buffer = zbx_strdup(buffer, description_proto); substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0); zbx_lrtrim(buffer, ZBX_WHITESPACE); if (0 != strcmp(trigger->description, buffer)) { trigger->description_orig = trigger->description; trigger->description = buffer; buffer = NULL; trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION; } if (0 != strcmp(trigger->expression, expression)) { trigger->expression_orig = trigger->expression; trigger->expression = expression; expression = NULL; trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION; } buffer = zbx_strdup(buffer, comments_proto); substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0); zbx_lrtrim(buffer, ZBX_WHITESPACE); if (0 != strcmp(trigger->comments, buffer)) { trigger->comments_orig = trigger->comments; trigger->comments = buffer; buffer = NULL; trigger->flags |= ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS; } } else { trigger = zbx_malloc(NULL, sizeof(zbx_lld_trigger_t)); trigger->triggerid = 0; trigger->description = zbx_strdup(NULL, description_proto); trigger->description_orig = NULL; substitute_discovery_macros(&trigger->description, jp_row, ZBX_MACRO_ANY, NULL, 0); zbx_lrtrim(trigger->description, ZBX_WHITESPACE); trigger->expression = expression; trigger->expression_orig = NULL; expression = NULL; trigger->comments = zbx_strdup(NULL, comments_proto); trigger->comments_orig = NULL; substitute_discovery_macros(&trigger->comments, jp_row, ZBX_MACRO_ANY, NULL, 0); zbx_lrtrim(trigger->comments, ZBX_WHITESPACE); zbx_vector_ptr_create(&trigger->functions); trigger->flags = ZBX_FLAG_LLD_TRIGGER_UNSET; zbx_vector_ptr_append(triggers, trigger); } zbx_free(buffer); if (SUCCEED != lld_functions_make(functions_proto, &trigger->functions, items, &lld_row->item_links)) goto out; trigger->flags |= ZBX_FLAG_LLD_TRIGGER_DISCOVERED; out: zbx_free(expression); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: send_list_of_active_checks_json * * * * Purpose: send list of active checks to the host * * * * Parameters: sock - open socket of server-agent connection * * json - request buffer * * * * Return value: SUCCEED - list of active checks sent successfully * * FAIL - an error occurred * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ int send_list_of_active_checks_json(zbx_socket_t *sock, struct zbx_json_parse *jp) { const char *__function_name = "send_list_of_active_checks_json"; char host[HOST_HOST_LEN_MAX], tmp[MAX_STRING_LEN], ip[INTERFACE_IP_LEN_MAX], error[MAX_STRING_LEN], *host_metadata = NULL; struct zbx_json json; int ret = FAIL, i; zbx_uint64_t hostid; size_t host_metadata_alloc = 1; /* for at least NUL-termination char */ unsigned short port; zbx_vector_uint64_t itemids; zbx_vector_ptr_t regexps; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(®exps); zbx_vector_str_create(&names); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) { zbx_snprintf(error, MAX_STRING_LEN, "%s", zbx_json_strerror()); goto error; } host_metadata = zbx_malloc(host_metadata, host_metadata_alloc); if (FAIL == zbx_json_value_by_name_dyn(jp, ZBX_PROTO_TAG_HOST_METADATA, &host_metadata, &host_metadata_alloc)) { *host_metadata = '\0'; } if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_IP, ip, sizeof(ip))) strscpy(ip, sock->peer); if (FAIL == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_PORT, tmp, sizeof(tmp))) *tmp = '\0'; if (FAIL == is_ushort(tmp, &port)) port = ZBX_DEFAULT_AGENT_PORT; if (FAIL == get_hostid_by_host(sock, host, ip, port, host_metadata, &hostid, error)) goto error; zbx_vector_uint64_create(&itemids); get_list_of_active_checks(hostid, &itemids); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_SUCCESS, ZBX_JSON_TYPE_STRING); zbx_json_addarray(&json, ZBX_PROTO_TAG_DATA); if (0 != itemids.values_num) { DC_ITEM *dc_items; int *errcodes, now; zbx_config_t cfg; dc_items = zbx_malloc(NULL, sizeof(DC_ITEM) * itemids.values_num); errcodes = zbx_malloc(NULL, sizeof(int) * itemids.values_num); DCconfig_get_items_by_itemids(dc_items, itemids.values, errcodes, itemids.values_num); zbx_config_get(&cfg, ZBX_CONFIG_FLAGS_REFRESH_UNSUPPORTED); now = time(NULL); for (i = 0; i < itemids.values_num; i++) { if (SUCCEED != errcodes[i]) { zabbix_log(LOG_LEVEL_DEBUG, "%s() Item [" ZBX_FS_UI64 "] was not found in the" " server cache. Not sending now.", __function_name, itemids.values[i]); continue; } if (ITEM_STATUS_ACTIVE != dc_items[i].status) continue; if (HOST_STATUS_MONITORED != dc_items[i].host.status) continue; if (ITEM_STATE_NOTSUPPORTED == dc_items[i].state) { if (0 == cfg.refresh_unsupported) continue; if (dc_items[i].lastclock + cfg.refresh_unsupported > now) continue; } dc_items[i].key = zbx_strdup(dc_items[i].key, dc_items[i].key_orig); substitute_key_macros(&dc_items[i].key, NULL, &dc_items[i], NULL, MACRO_TYPE_ITEM_KEY, NULL, 0); zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY, dc_items[i].key, ZBX_JSON_TYPE_STRING); if (0 != strcmp(dc_items[i].key, dc_items[i].key_orig)) { zbx_json_addstring(&json, ZBX_PROTO_TAG_KEY_ORIG, dc_items[i].key_orig, ZBX_JSON_TYPE_STRING); } zbx_json_adduint64(&json, ZBX_PROTO_TAG_DELAY, dc_items[i].delay); /* The agent expects ALWAYS to have lastlogsize and mtime tags. */ /* Removing those would cause older agents to fail. */ zbx_json_adduint64(&json, ZBX_PROTO_TAG_LASTLOGSIZE, dc_items[i].lastlogsize); zbx_json_adduint64(&json, ZBX_PROTO_TAG_MTIME, dc_items[i].mtime); zbx_json_close(&json); zbx_itemkey_extract_global_regexps(dc_items[i].key, &names); zbx_free(dc_items[i].key); } zbx_config_clean(&cfg); DCconfig_clean_items(dc_items, errcodes, itemids.values_num); zbx_free(errcodes); zbx_free(dc_items); } zbx_vector_uint64_destroy(&itemids); zbx_json_close(&json); DCget_expressions_by_names(®exps, (const char * const *)names.values, names.values_num); if (0 < regexps.values_num) { char buffer[32]; zbx_json_addarray(&json, ZBX_PROTO_TAG_REGEXP); for (i = 0; i < regexps.values_num; i++) { zbx_expression_t *regexp = regexps.values[i]; zbx_json_addobject(&json, NULL); zbx_json_addstring(&json, "name", regexp->name, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, "expression", regexp->expression, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->expression_type); zbx_json_addstring(&json, "expression_type", buffer, ZBX_JSON_TYPE_INT); zbx_snprintf(buffer, sizeof(buffer), "%c", regexp->exp_delimiter); zbx_json_addstring(&json, "exp_delimiter", buffer, ZBX_JSON_TYPE_STRING); zbx_snprintf(buffer, sizeof(buffer), "%d", regexp->case_sensitive); zbx_json_addstring(&json, "case_sensitive", buffer, ZBX_JSON_TYPE_INT); zbx_json_close(&json); } zbx_json_close(&json); } zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); zbx_alarm_on(CONFIG_TIMEOUT); if (SUCCEED != zbx_tcp_send(sock, json.buffer)) strscpy(error, zbx_socket_strerror()); else ret = SUCCEED; zbx_alarm_off(); zbx_json_free(&json); goto out; error: zabbix_log(LOG_LEVEL_WARNING, "cannot send list of active checks to \"%s\": %s", sock->peer, error); zbx_json_init(&json, ZBX_JSON_STAT_BUF_LEN); zbx_json_addstring(&json, ZBX_PROTO_TAG_RESPONSE, ZBX_PROTO_VALUE_FAILED, ZBX_JSON_TYPE_STRING); zbx_json_addstring(&json, ZBX_PROTO_TAG_INFO, error, ZBX_JSON_TYPE_STRING); zabbix_log(LOG_LEVEL_DEBUG, "%s() sending [%s]", __function_name, json.buffer); ret = zbx_tcp_send(sock, json.buffer); zbx_json_free(&json); out: for (i = 0; i < names.values_num; i++) zbx_free(names.values[i]); zbx_vector_str_destroy(&names); zbx_regexp_clean_expressions(®exps); zbx_vector_ptr_destroy(®exps); zbx_free(host_metadata); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: get_template_lld_rule_map * * * * Purpose: reads template lld rule conditions and host lld_rule identifiers * * from database * * * * Parameters: items - [IN] the host items including lld rules * * rules - [OUT] the ldd rule mapping * * * ******************************************************************************/ static void get_template_lld_rule_map(const zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules) { zbx_template_item_t *item; zbx_lld_rule_map_t *rule; zbx_lld_rule_condition_t *condition; int i, index; zbx_vector_uint64_t itemids; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_uint64_t itemid, item_conditionid; zbx_vector_uint64_create(&itemids); /* prepare discovery rules */ for (i = 0; i < items->values_num; i++) { item = items->values[i]; if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags)) continue; rule = zbx_malloc(NULL, sizeof(zbx_lld_rule_map_t)); rule->itemid = item->itemid; rule->templateid = item->templateid; rule->conditionid = 0; zbx_vector_uint64_create(&rule->conditionids); zbx_vector_ptr_create(&rule->conditions); zbx_vector_ptr_append(rules, rule); if (0 != rule->itemid) zbx_vector_uint64_append(&itemids, rule->itemid); zbx_vector_uint64_append(&itemids, rule->templateid); } if (0 != itemids.values_num) { zbx_vector_ptr_sort(rules, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select item_conditionid,itemid,operator,macro,value from item_condition where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[1]); index = zbx_vector_ptr_bsearch(rules, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); if (FAIL != index) { /* read template lld conditions */ rule = (zbx_lld_rule_map_t *)rules->values[index]; condition = zbx_malloc(NULL, sizeof(zbx_lld_rule_condition_t)); ZBX_STR2UINT64(condition->item_conditionid, row[0]); ZBX_STR2UCHAR(condition->operator, row[2]); condition->macro = zbx_strdup(NULL, row[3]); condition->value = zbx_strdup(NULL, row[4]); zbx_vector_ptr_append(&rule->conditions, condition); } else { /* read host lld conditions identifiers */ for (i = 0; i < rules->values_num; i++) { rule = (zbx_lld_rule_map_t *)rules->values[i]; if (itemid != rule->itemid) continue; ZBX_STR2UINT64(item_conditionid, row[0]); zbx_vector_uint64_append(&rule->conditionids, item_conditionid); break; } if (i == rules->values_num) THIS_SHOULD_NEVER_HAPPEN; } } DBfree_result(result); zbx_free(sql); } zbx_vector_uint64_destroy(&itemids); }
/****************************************************************************** * * * Function: lld_triggers_validate * * * * Parameters: triggers - [IN] sorted list of triggers * * * ******************************************************************************/ static void lld_triggers_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *triggers, char **error) { const char *__function_name = "lld_triggers_validate"; int i, j, k; zbx_lld_trigger_t *trigger; zbx_lld_function_t *function; zbx_vector_uint64_t triggerids; zbx_vector_str_t descriptions; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&triggerids); zbx_vector_str_create(&descriptions); /* checking a validity of the fields */ for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; lld_validate_trigger_field(trigger, &trigger->description, &trigger->description_orig, ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION, TRIGGER_DESCRIPTION_LEN, error); lld_validate_trigger_field(trigger, &trigger->comments, &trigger->comments_orig, ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS, TRIGGER_COMMENTS_LEN, error); } /* checking duplicated triggers in DB */ for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; if (0 != trigger->triggerid) { zbx_vector_uint64_append(&triggerids, trigger->triggerid); if (SUCCEED != lld_trigger_changed(trigger)) continue; } zbx_vector_str_append(&descriptions, trigger->description); } if (0 != descriptions.values_num) { char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; DB_RESULT result; DB_ROW row; zbx_vector_ptr_t db_triggers; zbx_lld_trigger_t *db_trigger; zbx_vector_ptr_create(&db_triggers); zbx_vector_str_sort(&descriptions, ZBX_DEFAULT_STR_COMPARE_FUNC); zbx_vector_str_uniq(&descriptions, ZBX_DEFAULT_STR_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select distinct t.triggerid,t.description,t.expression" " from triggers t,functions f,items i" " where t.triggerid=f.triggerid" " and f.itemid=i.itemid" " and i.hostid=" ZBX_FS_UI64 " and", hostid); DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.description", (const char **)descriptions.values, descriptions.values_num); if (0 != triggerids.values_num) { zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.triggerid", triggerids.values, triggerids.values_num); } result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { db_trigger = zbx_malloc(NULL, sizeof(zbx_lld_trigger_t)); ZBX_STR2UINT64(db_trigger->triggerid, row[0]); db_trigger->description = zbx_strdup(NULL, row[1]); db_trigger->description_orig = NULL; db_trigger->expression = zbx_strdup(NULL, row[2]); db_trigger->expression_orig = NULL; db_trigger->comments = NULL; db_trigger->comments_orig = NULL; db_trigger->flags = ZBX_FLAG_LLD_TRIGGER_UNSET; zbx_vector_ptr_create(&db_trigger->functions); zbx_vector_ptr_append(&db_triggers, db_trigger); } DBfree_result(result); zbx_vector_ptr_sort(&db_triggers, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); lld_functions_get(0, NULL, &db_triggers); for (i = 0; i < db_triggers.values_num; i++) { db_trigger = (zbx_lld_trigger_t *)db_triggers.values[i]; lld_expression_simplify(&db_trigger->expression, &db_trigger->functions); for (j = 0; j < triggers->values_num; j++) { trigger = (zbx_lld_trigger_t *)triggers->values[j]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; if (SUCCEED != lld_triggers_equal(trigger, db_trigger)) continue; *error = zbx_strdcatf(*error, "Cannot %s trigger: trigger \"%s\" already exists.\n", (0 != trigger->triggerid ? "update" : "create"), trigger->description); if (0 != trigger->triggerid) { lld_field_str_rollback(&trigger->description, &trigger->description_orig, &trigger->flags, ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION); lld_field_str_rollback(&trigger->expression, &trigger->expression_orig, &trigger->flags, ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION); for (k = 0; k < trigger->functions.values_num; k++) { function = (zbx_lld_function_t *)trigger->functions.values[k]; if (0 != function->functionid) { lld_field_uint64_rollback(&function->itemid, &function->itemid_orig, &function->flags, ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID); lld_field_str_rollback(&function->function, &function->function_orig, &function->flags, ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION); lld_field_str_rollback(&function->parameter, &function->parameter_orig, &function->flags, ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER); function->flags &= ~ZBX_FLAG_LLD_FUNCTION_DELETE; } else function->flags &= ~ZBX_FLAG_LLD_FUNCTION_DISCOVERED; } } else trigger->flags &= ~ZBX_FLAG_LLD_TRIGGER_DISCOVERED; break; /* only one same trigger can be here */ } } zbx_vector_ptr_clean(&db_triggers, (zbx_mem_free_func_t)lld_trigger_free); zbx_vector_ptr_destroy(&db_triggers); zbx_free(sql); } zbx_vector_str_destroy(&descriptions); zbx_vector_uint64_destroy(&triggerids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: save_template_discovery_prototypes * * * * Purpose: saves host item prototypes in database * * * * Parameters: hostid - [IN] the target host * * items - [IN] the template items * * * ******************************************************************************/ void save_template_discovery_prototypes(zbx_uint64_t hostid, zbx_vector_ptr_t *items) { typedef struct { zbx_uint64_t itemid; zbx_uint64_t parent_itemid; } zbx_proto_t; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_vector_uint64_t itemids; zbx_vector_ptr_t prototypes; zbx_proto_t *proto; int i; zbx_db_insert_t db_insert; zbx_vector_ptr_create(&prototypes); zbx_vector_uint64_create(&itemids); for (i = 0; i < items->values_num; i++) { zbx_template_item_t *item = items->values[i]; /* process only new prototype items */ if (NULL == item->key || 0 == (ZBX_FLAG_DISCOVERY_PROTOTYPE & item->flags)) continue; zbx_vector_uint64_append(&itemids, item->itemid); } if (0 == itemids.values_num) goto out; zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select i.itemid,r.itemid" " from items i,item_discovery id,items r" " where i.templateid=id.itemid" " and id.parent_itemid=r.templateid" " and r.hostid=" ZBX_FS_UI64 " and", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "i.itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { proto = zbx_malloc(NULL, sizeof(zbx_proto_t)); ZBX_STR2UINT64(proto->itemid, row[0]); ZBX_STR2UINT64(proto->parent_itemid, row[1]); zbx_vector_ptr_append(&prototypes, proto); } DBfree_result(result); if (0 == prototypes.values_num) goto out; zbx_db_insert_prepare(&db_insert, "item_discovery", "itemdiscoveryid", "itemid", "parent_itemid", NULL); for (i = 0; i < prototypes.values_num; i++) { proto = prototypes.values[i]; zbx_db_insert_add_values(&db_insert, __UINT64_C(0), proto->itemid, proto->parent_itemid); } zbx_db_insert_autoincrement(&db_insert, "itemdiscoveryid"); zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); out: zbx_free(sql); zbx_vector_uint64_destroy(&itemids); zbx_vector_ptr_clear_ext(&prototypes, zbx_ptr_free); zbx_vector_ptr_destroy(&prototypes); }
/****************************************************************************** * * * Function: zbx_mock_test_entry * * * ******************************************************************************/ void zbx_mock_test_entry(void **state) { const char *filter; zbx_prometheus_condition_test_t *metric = NULL, *value = NULL; zbx_vector_ptr_t labels; int ret, expected_ret, index; char *error = NULL; zbx_mock_handle_t hmetric, hvalue, hlabels, hlabel; zbx_mock_error_t mock_ret; ZBX_UNUSED(state); zbx_vector_ptr_create(&labels); filter = zbx_mock_get_parameter_string("in.filter"); ret = zbx_prometheus_filter_parse(filter, &metric, &labels, &value, &error); expected_ret = zbx_mock_str_to_return_code(zbx_mock_get_parameter_string("out.return")); zbx_mock_assert_result_eq("prometheus filter parsing", expected_ret, ret); if (SUCCEED == ret) { if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.metric", &hmetric)) hmetric = -1; test_match("metric", hmetric, metric); if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.value", &hvalue)) hvalue = -1; test_match("value", hvalue, value); if (ZBX_MOCK_SUCCESS != zbx_mock_parameter("out.labels", &hlabels)) hlabels = -1; if (-1 != hlabels && 0 == labels.values_num) fail_msg("expected to parse label filters"); if (-1 == hlabels && 0 != labels.values_num) fail_msg("did not expect to parse label filters"); if (-1 != hlabels) { index = 0; while (ZBX_MOCK_END_OF_VECTOR != (mock_ret = zbx_mock_vector_element(hlabels, &hlabel)) && index < labels.values_num) { test_match("label", hlabel, labels.values[index]); index++; } if (ZBX_MOCK_END_OF_VECTOR != mock_ret) fail_msg("expected more than %d filter labels", index); if (index != labels.values_num) fail_msg("got more than the expected %d filter labels", index); } } if (NULL != metric) zbx_prometheus_condition_test_free(metric); if (NULL != value) zbx_prometheus_condition_test_free(value); zbx_vector_ptr_clear_ext(&labels, (zbx_clean_func_t)zbx_prometheus_condition_test_free); zbx_vector_ptr_destroy(&labels); zbx_free(error); }