/****************************************************************************** * * * Function: zbx_proc_get_processes * * * * Purpose: get system processes * * * * Parameters: processes - [OUT] the system processes * * flags - [IN] the flags specifying the process properties * * that must be returned * * * * Return value: SUCCEED - the system processes were retrieved successfully * * FAIL - failed to open /proc directory * * * ******************************************************************************/ int zbx_proc_get_processes(zbx_vector_ptr_t *processes, unsigned int flags) { const char *__function_name = "zbx_proc_get_processes"; DIR *dir; struct dirent *entries; int ret = FAIL, pid; zbx_sysinfo_proc_t *proc; zabbix_log(LOG_LEVEL_TRACE, "In %s()", __function_name); if (NULL == (dir = opendir("/proc"))) goto out; while (NULL != (entries = readdir(dir))) { /* skip entries not containing pids */ if (FAIL == is_uint32(entries->d_name, &pid)) continue; if (NULL == (proc = proc_create(pid, flags))) continue; zbx_vector_ptr_append(processes, proc); } closedir(dir); ret = SUCCEED; out: zabbix_log(LOG_LEVEL_TRACE, "End of %s(): %s, processes:%d", __function_name, zbx_result_string(ret), processes->values_num); return ret; }
/****************************************************************************** * * * Function: lld_items_get * * * * Purpose: returns the list of items which are related to the trigger * * prototype * * * * Parameters: parent_triggerid - [IN] trigger prototype identificator * * items - [OUT] sorted list of items * * * ******************************************************************************/ static void lld_items_get(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *items) { const char *__function_name = "lld_items_get"; DB_RESULT result; DB_ROW row; zbx_lld_item_t *item; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect( "select distinct i.itemid,i.flags" " from items i,functions f" " where i.itemid=f.itemid" " and f.triggerid=" ZBX_FS_UI64, parent_triggerid); while (NULL != (row = DBfetch(result))) { item = zbx_malloc(NULL, sizeof(zbx_lld_item_t)); ZBX_STR2UINT64(item->itemid, row[0]); ZBX_STR2UCHAR(item->flags, row[1]); zbx_vector_ptr_append(items, item); } DBfree_result(result); zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void lld_function_make(zbx_lld_function_t *function_proto, zbx_vector_ptr_t *functions, zbx_uint64_t itemid) { int i; zbx_lld_function_t *function; for (i = 0; i < functions->values_num; i++) { function = (zbx_lld_function_t *)functions->values[i]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (function->index == function_proto->index) break; } if (i == functions->values_num) { function = zbx_malloc(NULL, sizeof(zbx_lld_function_t)); function->index = function_proto->index; function->functionid = 0; function->itemid = itemid; function->itemid_orig = 0; function->function = zbx_strdup(NULL, function_proto->function); function->function_orig = NULL; function->parameter = zbx_strdup(NULL, function_proto->parameter); function->parameter_orig = NULL; function->flags = ZBX_FLAG_LLD_FUNCTION_DISCOVERED; zbx_vector_ptr_append(functions, function); } else { if (function->itemid != itemid) { function->itemid_orig = function->itemid; function->itemid = itemid; function->flags |= ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID; } if (0 != strcmp(function->function, function_proto->function)) { function->function_orig = function->function; function->function = zbx_strdup(NULL, function_proto->function); function->flags |= ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION; } if (0 != strcmp(function->parameter, function_proto->parameter)) { function->parameter_orig = function->parameter; function->parameter = zbx_strdup(NULL, function_proto->parameter); function->flags |= ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER; } function->flags |= ZBX_FLAG_LLD_FUNCTION_DISCOVERED; } }
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); }
void add_regexp_ex(zbx_vector_ptr_t *regexps, const char *name, const char *expression, int expression_type, char exp_delimiter, int case_sensitive) { zbx_expression_t *regexp; regexp = zbx_malloc(NULL, sizeof(zbx_expression_t)); regexp->name = zbx_strdup(NULL, name); regexp->expression = zbx_strdup(NULL, expression); regexp->expression_type = expression_type; regexp->exp_delimiter = exp_delimiter; regexp->case_sensitive = case_sensitive; zbx_vector_ptr_append(regexps, regexp); }
/****************************************************************************** * * * Function: db_get_query_tags * * * * Purpose: get event query tags from database * * * ******************************************************************************/ static void db_get_query_tags(zbx_vector_ptr_t *event_queries) { DB_ROW row; DB_RESULT result; int i; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_event_suppress_query_t *query; zbx_vector_uint64_t eventids; zbx_uint64_t eventid; zbx_tag_t *tag; zbx_vector_uint64_create(&eventids); for (i = 0; i < event_queries->values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries->values[i]; zbx_vector_uint64_append(&eventids, query->eventid); } zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select eventid,tag,value from problem_tag where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "eventid", eventids.values, eventids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by eventid"); result = DBselect("%s", sql); zbx_free(sql); i = 0; query = (zbx_event_suppress_query_t *)event_queries->values[0]; while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(eventid, row[0]); while (query->eventid != eventid) query = (zbx_event_suppress_query_t *)event_queries->values[++i]; tag = (zbx_tag_t *)zbx_malloc(NULL, sizeof(zbx_tag_t)); tag->tag = zbx_strdup(NULL, row[1]); tag->value = zbx_strdup(NULL, row[2]); zbx_vector_ptr_append(&query->tags, tag); } DBfree_result(result); zbx_vector_uint64_destroy(&eventids); }
/****************************************************************************** * * * Function: hk_history_delete_queue_append * * * * Purpose: add item to the delete queue if necessary * * * * Parameters: rule - [IN/OUT] the history housekeeping rule * * now - [IN] the current timestmap * * item_record - [IN/OUT] the record from item cache containing * * item to process and its oldest record timestamp * * history - [IN] a number of days the history data for * * item_record must be kept. * * * * Author: Andris Zeila * * * * Comments: If item is added to delete queue, its oldest record timestamp * * (min_clock) is updated to the calculated 'cutoff' value. * * * ******************************************************************************/ static void hk_history_delete_queue_append(zbx_hk_history_rule_t *rule, int now, zbx_hk_item_cache_t *item_record, int history) { int keep_from = now - history * SEC_PER_DAY; if (keep_from > item_record->min_clock) { zbx_hk_delete_queue_t *update_record; /* update oldest timestamp in item cache */ item_record->min_clock = MIN(keep_from, item_record->min_clock + HK_MAX_DELETE_PERIODS * CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR); update_record = zbx_malloc(NULL, sizeof(zbx_hk_delete_queue_t)); update_record->itemid = item_record->itemid; update_record->min_clock = item_record->min_clock; zbx_vector_ptr_append(&rule->delete_queue, update_record); } }
/****************************************************************************** * * * 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_items_get * * * * Purpose: returns the list of items which are related to the graph * * prototype * * * * Parameters: gitems_proto - [IN] graph prototype's graphs_items * * ymin_itemid_proto - [IN] graph prototype's ymin_itemid * * ymax_itemid_proto - [IN] graph prototype's ymax_itemid * * items - [OUT] sorted list of items * * * ******************************************************************************/ static void lld_items_get(zbx_vector_ptr_t *gitems_proto, zbx_uint64_t ymin_itemid_proto, zbx_uint64_t ymax_itemid_proto, zbx_vector_ptr_t *items) { const char *__function_name = "lld_items_get"; DB_RESULT result; DB_ROW row; zbx_lld_gitem_t *gitem; zbx_lld_item_t *item; zbx_vector_uint64_t itemids; int i; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&itemids); for (i = 0; i < gitems_proto->values_num; i++) { gitem = (zbx_lld_gitem_t *)gitems_proto->values[i]; zbx_vector_uint64_append(&itemids, gitem->itemid); } if (0 != ymin_itemid_proto) zbx_vector_uint64_append(&itemids, ymin_itemid_proto); if (0 != ymax_itemid_proto) zbx_vector_uint64_append(&itemids, ymax_itemid_proto); if (0 != itemids.values_num) { char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,flags" " from items" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { item = zbx_malloc(NULL, sizeof(zbx_lld_item_t)); ZBX_STR2UINT64(item->itemid, row[0]); ZBX_STR2UCHAR(item->flags, row[1]); zbx_vector_ptr_append(items, item); } DBfree_result(result); zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } zbx_vector_uint64_destroy(&itemids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static int lld_gitems_make(zbx_vector_ptr_t *gitems_proto, zbx_vector_ptr_t *gitems, zbx_vector_ptr_t *items, zbx_vector_ptr_t *item_links) { const char *__function_name = "lld_gitems_make"; int i, ret = FAIL; zbx_lld_gitem_t *gitem_proto, *gitem; zbx_uint64_t itemid; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); for (i = 0; i < gitems_proto->values_num; i++) { gitem_proto = (zbx_lld_gitem_t *)gitems_proto->values[i]; if (SUCCEED != lld_item_get(gitem_proto->itemid, items, item_links, &itemid)) goto out; if (i == gitems->values_num) { gitem = zbx_malloc(NULL, sizeof(zbx_lld_gitem_t)); gitem->gitemid = 0; gitem->itemid = itemid; gitem->drawtype = gitem_proto->drawtype; gitem->sortorder = gitem_proto->sortorder; gitem->color = zbx_strdup(NULL, gitem_proto->color); gitem->yaxisside = gitem_proto->yaxisside; gitem->calc_fnc = gitem_proto->calc_fnc; gitem->type = gitem_proto->type; gitem->flags = ZBX_FLAG_LLD_GITEM_DISCOVERED; zbx_vector_ptr_append(gitems, gitem); } else { gitem = (zbx_lld_gitem_t *)gitems->values[i]; if (gitem->itemid != itemid) { gitem->itemid = itemid; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_ITEMID; } if (gitem->drawtype != gitem_proto->drawtype) { gitem->drawtype = gitem_proto->drawtype; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_DRAWTYPE; } if (gitem->sortorder != gitem_proto->sortorder) { gitem->sortorder = gitem_proto->sortorder; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_SORTORDER; } if (0 != strcmp(gitem->color, gitem_proto->color)) { gitem->color = zbx_strdup(gitem->color, gitem_proto->color); gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_COLOR; } if (gitem->yaxisside != gitem_proto->yaxisside) { gitem->yaxisside = gitem_proto->yaxisside; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_YAXISSIDE; } if (gitem->calc_fnc != gitem_proto->calc_fnc) { gitem->calc_fnc = gitem_proto->calc_fnc; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_CALC_FNC; } if (gitem->type != gitem_proto->type) { gitem->type = gitem_proto->type; gitem->flags |= ZBX_FLAG_LLD_GITEM_UPDATE_TYPE; } gitem->flags |= ZBX_FLAG_LLD_GITEM_DISCOVERED; } } for (; i < gitems->values_num; i++) { gitem = (zbx_lld_gitem_t *)gitems->values[i]; gitem->flags |= ZBX_FLAG_LLD_GITEM_DELETE; } ret = SUCCEED; out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * 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_gitems_get * * * * Purpose: retrieve graphs_items which are used by the graph prototype and * * by selected graphs * * * ******************************************************************************/ static void lld_gitems_get(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *gitems_proto, zbx_vector_ptr_t *graphs) { const char *__function_name = "lld_gitems_get"; int i, index; zbx_lld_graph_t *graph; zbx_lld_gitem_t *gitem; zbx_uint64_t graphid; zbx_vector_uint64_t graphids; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&graphids); zbx_vector_uint64_append(&graphids, parent_graphid); for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; zbx_vector_uint64_append(&graphids, graph->graphid); } zbx_vector_uint64_sort(&graphids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select gitemid,graphid,itemid,drawtype,sortorder,color,yaxisside,calc_fnc,type" " from graphs_items" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "graphid", graphids.values, graphids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { gitem = zbx_malloc(NULL, sizeof(zbx_lld_gitem_t)); ZBX_STR2UINT64(gitem->gitemid, row[0]); ZBX_STR2UINT64(graphid, row[1]); ZBX_STR2UINT64(gitem->itemid, row[2]); ZBX_STR2UCHAR(gitem->drawtype, row[3]); gitem->sortorder = atoi(row[4]); gitem->color = zbx_strdup(NULL, row[5]); ZBX_STR2UCHAR(gitem->yaxisside, row[6]); ZBX_STR2UCHAR(gitem->calc_fnc, row[7]); ZBX_STR2UCHAR(gitem->type, row[8]); gitem->flags = ZBX_FLAG_LLD_GITEM_UNSET; if (graphid == parent_graphid) { zbx_vector_ptr_append(gitems_proto, gitem); } else if (FAIL != (index = zbx_vector_ptr_bsearch(graphs, &graphid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { graph = (zbx_lld_graph_t *)graphs->values[index]; zbx_vector_ptr_append(&graph->gitems, gitem); } else { THIS_SHOULD_NEVER_HAPPEN; lld_gitem_free(gitem); } } DBfree_result(result); zbx_vector_ptr_sort(gitems_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; zbx_vector_ptr_sort(&graph->gitems, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } zbx_vector_uint64_destroy(&graphids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
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: procstat_build_local_query_vector * * * * Purpose: builds a local copy of the process cpu utilization queries and * * removes expired (not used during last 24 hours) queries * * * * Parameters: queries_ptr - [OUT] local copy of queries copied from queries * * in shared memory segment * * runid - [IN] marker for queries to be processed in the * * current collector iteration * * * * Return value: The flags defining the process properties to be retrieved. * * See ZBX_SYSINFO_PROC_ defines. * * * * Comments: updates queries (runid) in shared memory segment * * * ******************************************************************************/ static int procstat_build_local_query_vector(zbx_vector_ptr_t *queries_ptr, int runid) { zbx_procstat_header_t *header; time_t now; zbx_procstat_query_t *query; zbx_procstat_query_data_t *qdata; int flags = ZBX_SYSINFO_PROC_NONE, *pnext_query; zbx_dshm_lock(&collector->procstat); procstat_reattach(); header = (zbx_procstat_header_t *)procstat_ref.addr; if (PROCSTAT_NULL_OFFSET == header->queries) goto out; flags = ZBX_SYSINFO_PROC_PID; now = time(NULL); pnext_query = &header->queries; for (query = PROCSTAT_QUERY_FIRST(procstat_ref.addr); NULL != query; query = PROCSTAT_QUERY_NEXT(procstat_ref.addr, query)) { /* remove unused queries, the data is still allocated until the next resize */ if (PROCSTAT_MAX_INACTIVITY_PERIOD < now - query->last_accessed) { *pnext_query = query->next; continue; } qdata = (zbx_procstat_query_data_t *)zbx_malloc(NULL, sizeof(zbx_procstat_query_data_t)); zbx_vector_uint64_create(&qdata->pids); /* store the reference to query attributes, which is guaranteed to be */ /* valid until we call process_reattach() */ if (NULL != (qdata->procname = PROCSTAT_PTR_NULL(procstat_ref.addr, query->procname))) flags |= ZBX_SYSINFO_PROC_NAME; if (NULL != (qdata->username = PROCSTAT_PTR_NULL(procstat_ref.addr, query->username))) flags |= ZBX_SYSINFO_PROC_USER; if (NULL != (qdata->cmdline = PROCSTAT_PTR_NULL(procstat_ref.addr, query->cmdline))) flags |= ZBX_SYSINFO_PROC_CMDLINE; qdata->flags = query->flags; qdata->utime = 0; qdata->stime = 0; qdata->error = 0; zbx_vector_ptr_append(queries_ptr, qdata); /* The order of queries can be changed only by collector itself (when removing old */ /* queries), but during statistics gathering the shared memory is unlocked and other */ /* processes might insert queries at the beginning of active queries list. */ /* Mark the queries being processed by current data gathering cycle with id that */ /* is incremented at the end of every data gathering cycle. We can be sure that */ /* our local copy will match the queries in shared memory having the same runid. */ query->runid = runid; pnext_query = &query->next; } out: procstat_try_compress(procstat_ref.addr); zbx_dshm_unlock(&collector->procstat); return flags; }
/****************************************************************************** * * * 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: db_get_query_events * * * * Purpose: get open, recently resolved and resolved problems with suppress * * data from database and prepare event query, event data structures * * * ******************************************************************************/ static void db_get_query_events(zbx_vector_ptr_t *event_queries, zbx_vector_ptr_t *event_data) { DB_ROW row; DB_RESULT result; zbx_event_suppress_query_t *query; zbx_event_suppress_data_t *data = NULL; zbx_uint64_t eventid; zbx_uint64_pair_t pair; zbx_vector_uint64_t eventids; /* get open or recently closed problems */ result = DBselect("select eventid,objectid,r_eventid" " from problem" " where source=%d" " and object=%d" " and " ZBX_SQL_MOD(eventid, %d) "=%d" " order by eventid", EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, CONFIG_TIMER_FORKS, process_num - 1); while (NULL != (row = DBfetch(result))) { query = (zbx_event_suppress_query_t *)zbx_malloc(NULL, sizeof(zbx_event_suppress_query_t)); ZBX_STR2UINT64(query->eventid, row[0]); ZBX_STR2UINT64(query->triggerid, row[1]); ZBX_DBROW2UINT64(query->r_eventid, row[2]); zbx_vector_uint64_create(&query->functionids); zbx_vector_ptr_create(&query->tags); zbx_vector_uint64_pair_create(&query->maintenances); zbx_vector_ptr_append(event_queries, query); } DBfree_result(result); /* get event suppress data */ zbx_vector_uint64_create(&eventids); result = DBselect("select eventid,maintenanceid,suppress_until" " from event_suppress" " where " ZBX_SQL_MOD(eventid, %d) "=%d" " order by eventid", CONFIG_TIMER_FORKS, process_num - 1); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(eventid, row[0]); if (FAIL == zbx_vector_ptr_bsearch(event_queries, &eventid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)) zbx_vector_uint64_append(&eventids, eventid); if (NULL == data || data->eventid != eventid) { data = (zbx_event_suppress_data_t *)zbx_malloc(NULL, sizeof(zbx_event_suppress_data_t)); data->eventid = eventid; zbx_vector_uint64_pair_create(&data->maintenances); zbx_vector_ptr_append(event_data, data); } ZBX_DBROW2UINT64(pair.first, row[1]); pair.second = atoi(row[2]); zbx_vector_uint64_pair_append(&data->maintenances, pair); } DBfree_result(result); /* get missing event data */ if (0 != eventids.values_num) { char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_vector_uint64_uniq(&eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select e.eventid,e.objectid,er.r_eventid" " from events e" " left join event_recovery er" " on e.eventid=er.eventid" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "e.eventid", eventids.values, eventids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { query = (zbx_event_suppress_query_t *)zbx_malloc(NULL, sizeof(zbx_event_suppress_query_t)); ZBX_STR2UINT64(query->eventid, row[0]); ZBX_STR2UINT64(query->triggerid, row[1]); ZBX_DBROW2UINT64(query->r_eventid, row[2]); zbx_vector_uint64_create(&query->functionids); zbx_vector_ptr_create(&query->tags); zbx_vector_uint64_pair_create(&query->maintenances); zbx_vector_ptr_append(event_queries, query); } DBfree_result(result); zbx_vector_ptr_sort(event_queries, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } zbx_vector_uint64_destroy(&eventids); }
/****************************************************************************** * * * Function: get_template_items * * * * Purpose: read template items from database * * * * Parameters: hostid - [IN] host id * * templateids - [IN] array of template IDs * * items - [OUT] the item data * * * * Comments: The itemid and key are set depending on whether the item exists * * for the specified host. * * If item exists itemid will be set to its itemid and key will be * * set to NULL. * * If item does not exist, itemid will be set to 0 and key will be * * set to item key. * * * ******************************************************************************/ static void get_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *templateids, zbx_vector_ptr_t *items) { DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0, i; unsigned char interface_type; zbx_template_item_t *item; zbx_uint64_t interfaceids[4]; memset(&interfaceids, 0, sizeof(interfaceids)); DBget_interfaces_by_hostid(hostid, interfaceids); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select ti.itemid,ti.name,ti.key_,ti.type,ti.value_type,ti.data_type,ti.delay,ti.delay_flex," "ti.history,ti.trends,ti.status,ti.trapper_hosts,ti.units,ti.multiplier,ti.delta," "ti.formula,ti.logtimefmt,ti.valuemapid,ti.params,ti.ipmi_sensor,ti.snmp_community," "ti.snmp_oid,ti.snmpv3_securityname,ti.snmpv3_securitylevel,ti.snmpv3_authprotocol," "ti.snmpv3_authpassphrase,ti.snmpv3_privprotocol,ti.snmpv3_privpassphrase,ti.authtype," "ti.username,ti.password,ti.publickey,ti.privatekey,ti.flags,ti.description," "ti.inventory_link,ti.lifetime,ti.snmpv3_contextname,hi.itemid,ti.evaltype,ti.port" " from items ti" " left join items hi on hi.key_=ti.key_" " and hi.hostid=" ZBX_FS_UI64 " where", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "ti.hostid", templateids->values, templateids->values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { item = zbx_malloc(NULL, sizeof(zbx_template_item_t)); ZBX_STR2UINT64(item->templateid, row[0]); ZBX_STR2UCHAR(item->type, row[3]); ZBX_STR2UCHAR(item->value_type, row[4]); ZBX_STR2UCHAR(item->data_type, row[5]); item->delay = atoi(row[6]); item->history = atoi(row[8]); item->trends = atoi(row[9]); ZBX_STR2UCHAR(item->status, row[10]); ZBX_STR2UCHAR(item->multiplier, row[13]); ZBX_STR2UCHAR(item->delta, row[14]); ZBX_DBROW2UINT64(item->valuemapid, row[17]); ZBX_STR2UCHAR(item->snmpv3_securitylevel, row[23]); ZBX_STR2UCHAR(item->snmpv3_authprotocol, row[24]); ZBX_STR2UCHAR(item->snmpv3_privprotocol, row[26]); ZBX_STR2UCHAR(item->authtype, row[28]); ZBX_STR2UCHAR(item->flags, row[33]); ZBX_STR2UCHAR(item->inventory_link, row[35]); ZBX_STR2UCHAR(item->evaltype, row[39]); switch (interface_type = get_interface_type_by_item_type(item->type)) { case INTERFACE_TYPE_UNKNOWN: item->interfaceid = 0; break; case INTERFACE_TYPE_ANY: for (i = 0; INTERFACE_TYPE_COUNT > i; i++) { if (0 != interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1]) break; } item->interfaceid = interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1]; break; default: item->interfaceid = interfaceids[interface_type - 1]; } item->name = zbx_strdup(NULL, row[1]); item->delay_flex = zbx_strdup(NULL, row[7]); item->trapper_hosts = zbx_strdup(NULL, row[11]); item->units = zbx_strdup(NULL, row[12]); item->formula = zbx_strdup(NULL, row[15]); item->logtimefmt = zbx_strdup(NULL, row[16]); item->params = zbx_strdup(NULL, row[18]); item->ipmi_sensor = zbx_strdup(NULL, row[19]); item->snmp_community = zbx_strdup(NULL, row[20]); item->snmp_oid = zbx_strdup(NULL, row[21]); item->snmpv3_securityname = zbx_strdup(NULL, row[22]); item->snmpv3_authpassphrase = zbx_strdup(NULL, row[25]); item->snmpv3_privpassphrase = zbx_strdup(NULL, row[27]); item->username = zbx_strdup(NULL, row[29]); item->password = zbx_strdup(NULL, row[30]); item->publickey = zbx_strdup(NULL, row[31]); item->privatekey = zbx_strdup(NULL, row[32]); item->description = zbx_strdup(NULL, row[34]); item->lifetime = zbx_strdup(NULL, row[36]); item->snmpv3_contextname = zbx_strdup(NULL, row[37]); item->port = zbx_strdup(NULL, row[40]); if (SUCCEED != DBis_null(row[38])) { item->key = NULL; ZBX_STR2UINT64(item->itemid, row[38]); } else { item->key = zbx_strdup(NULL, row[2]); item->itemid = 0; } zbx_vector_ptr_append(items, item); } DBfree_result(result); zbx_free(sql); zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); }
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: sync_config * * * * Purpose: sync list of medias to send notifications in case if DB is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ static void sync_config() { const char *__function_name = "sync_config"; DB_RESULT result; DB_ROW row; ZBX_RECIPIENT *recipient; int count = 0, old_count; static int no_recipients = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); result = DBselect_once("select mt.mediatypeid,mt.type,mt.description," "mt.smtp_server,mt.smtp_helo,mt.smtp_email," "mt.exec_path,mt.gsm_modem," "mt.username,mt.passwd,m.sendto" " from media m,users_groups u,config c,media_type mt" " where m.userid=u.userid" " and u.usrgrpid=c.alert_usrgrpid" " and m.mediatypeid=mt.mediatypeid" " and m.active=%d", MEDIA_STATUS_ACTIVE); if (NULL == result || (DB_RESULT)ZBX_DB_DOWN == result) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); goto exit; } old_count = recipients.values_num; while (NULL != (row = DBfetch(result))) { /* add the recipients to the list */ if (count >= recipients.values_num) { recipient = zbx_calloc(NULL, 1, sizeof(ZBX_RECIPIENT)); zbx_vector_ptr_append(&recipients, recipient); } else recipient = recipients.values[count]; ZBX_STR2UINT64(recipient->mediatype.mediatypeid, row[0]); recipient->mediatype.type = atoi(row[1]); /* the recipients are likely to be the same, change only what's different */ STR_REPLACE(recipient->mediatype.description, row[2]); STR_REPLACE(recipient->mediatype.smtp_server, row[3]); STR_REPLACE(recipient->mediatype.smtp_helo, row[4]); STR_REPLACE(recipient->mediatype.smtp_email, row[5]); STR_REPLACE(recipient->mediatype.exec_path, row[6]); STR_REPLACE(recipient->mediatype.gsm_modem, row[7]); STR_REPLACE(recipient->mediatype.username, row[8]); STR_REPLACE(recipient->mediatype.passwd, row[9]); STR_REPLACE(recipient->alert.sendto, row[10]); if (NULL == recipient->alert.subject) recipient->alert.message = recipient->alert.subject = zbx_strdup(NULL, "Zabbix database is down."); count++; } DBfree_result(result); if (0 < old_count && 0 == count) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: no recipients found for database down messages"); no_recipients = 1; } else if (1 == no_recipients && 0 < count) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: %d recipient(s) found for database down messages", count); no_recipients = 0; } recipients.values_num = count; while (count < old_count) { /* some recipients have been deleted, free the older entries */ recipient = recipients.values[count++]; zbx_free(recipient->mediatype.description); zbx_free(recipient->mediatype.smtp_server); zbx_free(recipient->mediatype.smtp_helo); zbx_free(recipient->mediatype.smtp_email); zbx_free(recipient->mediatype.exec_path); zbx_free(recipient->mediatype.gsm_modem); zbx_free(recipient->mediatype.username); zbx_free(recipient->mediatype.passwd); zbx_free(recipient->alert.sendto); zbx_free(recipient->alert.subject); zbx_free(recipient); } exit: zabbix_log(LOG_LEVEL_DEBUG, "End of %s() values_num:%d", __function_name, recipients.values_num); }
/****************************************************************************** * * * Function: lld_functions_get * * * * Purpose: retrieve functions which are used by all triggers in the host of * * the trigger prototype * * * ******************************************************************************/ static void lld_functions_get(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *functions_proto, zbx_vector_ptr_t *triggers) { const char *__function_name = "lld_functions_get"; int i; zbx_lld_trigger_t *trigger; zbx_vector_uint64_t triggerids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&triggerids); if (0 != parent_triggerid) zbx_vector_uint64_append(&triggerids, parent_triggerid); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; zbx_vector_uint64_append(&triggerids, trigger->triggerid); } if (0 != triggerids.values_num) { DB_RESULT result; DB_ROW row; zbx_lld_function_t *function; zbx_uint64_t triggerid; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; int index; zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select functionid,triggerid,itemid,function,parameter" " from functions" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values, triggerids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { function = zbx_malloc(NULL, sizeof(zbx_lld_function_t)); function->index = 0; ZBX_STR2UINT64(function->functionid, row[0]); ZBX_STR2UINT64(triggerid, row[1]); ZBX_STR2UINT64(function->itemid, row[2]); function->itemid_orig = 0; function->function = zbx_strdup(NULL, row[3]); function->function_orig = NULL; function->parameter = zbx_strdup(NULL, row[4]); function->parameter_orig = NULL; function->flags = ZBX_FLAG_LLD_FUNCTION_UNSET; if (0 != parent_triggerid && triggerid == parent_triggerid) { zbx_vector_ptr_append(functions_proto, function); } else if (FAIL != (index = zbx_vector_ptr_bsearch(triggers, &triggerid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { trigger = (zbx_lld_trigger_t *)triggers->values[index]; zbx_vector_ptr_append(&trigger->functions, function); } else { THIS_SHOULD_NEVER_HAPPEN; lld_function_free(function); } } DBfree_result(result); if (NULL != functions_proto) zbx_vector_ptr_sort(functions_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; zbx_vector_ptr_sort(&trigger->functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } } zbx_vector_uint64_destroy(&triggerids); 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: 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: 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: 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: sql_writer_add_dbinsert * * * * Purpose: adds bulk insert data to be flushed later * * * * Parameters: db_insert - [IN] bulk insert data * * * ************************************************************************************/ static void sql_writer_add_dbinsert(zbx_db_insert_t *db_insert) { sql_writer_init(); zbx_vector_ptr_append(&writer.dbinserts, db_insert); }
/****************************************************************************** * * * 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: lld_filter_load * * * * Purpose: loads lld filter data * * * * Parameters: filter - [IN] the lld filter * * lld_ruleid - [IN] the lld rule id * * error - [OUT] the error description * * * ******************************************************************************/ static int lld_filter_load(lld_filter_t *filter, zbx_uint64_t lld_ruleid, char **error) { DB_RESULT result; DB_ROW row; lld_condition_t *condition; DC_ITEM item; int errcode, ret = SUCCEED; DCconfig_get_items_by_itemids(&item, &lld_ruleid, &errcode, 1); if (SUCCEED != errcode) { *error = zbx_dsprintf(*error, "Invalid discovery rule ID [" ZBX_FS_UI64 "].", lld_ruleid); ret = FAIL; goto out; } result = DBselect( "select item_conditionid,macro,value" " from item_condition" " where itemid=" ZBX_FS_UI64, lld_ruleid); while (NULL != (row = DBfetch(result))) { condition = zbx_malloc(NULL, sizeof(lld_condition_t)); ZBX_STR2UINT64(condition->id, row[0]); condition->macro = zbx_strdup(NULL, row[1]); condition->regexp = zbx_strdup(NULL, row[2]); zbx_vector_ptr_create(&condition->regexps); zbx_vector_ptr_append(&filter->conditions, condition); if ('@' == *condition->regexp) { DCget_expressions_by_name(&condition->regexps, condition->regexp + 1); if (0 == condition->regexps.values_num) { *error = zbx_dsprintf(*error, "Global regular expression \"%s\" does not exist.", condition->regexp + 1); ret = FAIL; break; } } else { substitute_simple_macros(NULL, NULL, NULL, NULL, NULL, NULL, &item, NULL, &condition->regexp, MACRO_TYPE_LLD_FILTER, NULL, 0); } } DBfree_result(result); if (SUCCEED != ret) lld_conditions_free(&filter->conditions); else if (CONDITION_EVAL_TYPE_AND_OR == filter->evaltype) zbx_vector_ptr_sort(&filter->conditions, lld_condition_compare_by_macro); out: DCconfig_clean_items(&item, &errcode, 1); return ret; }