/****************************************************************************** * * * Function: op_groups_del * * * * Purpose: delete groups from discovered host * * * * Parameters: event - [IN] event data * * groupids - [IN] IDs of groups to delete * * * * Author: Alexei Vladishev * * * ******************************************************************************/ void op_groups_del(const DB_EVENT *event, zbx_vector_uint64_t *groupids) { const char *__function_name = "op_groups_del"; DB_RESULT result; zbx_uint64_t hostid; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (event->source != EVENT_SOURCE_DISCOVERY) return; if (event->object != EVENT_OBJECT_DHOST && event->object != EVENT_OBJECT_DSERVICE) return; if (0 == (hostid = select_discovered_host(event))) return; sql = zbx_malloc(sql, sql_alloc); /* make sure host belongs to at least one hostgroup */ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select groupid" " from hosts_groups" " where hostid=" ZBX_FS_UI64 " and not", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num); result = DBselectN(sql, 1); if (NULL == DBfetch(result)) { zabbix_log(LOG_LEVEL_WARNING, "cannot remove host \"%s\" from all host groups:" " it must belong to at least one", zbx_host_string(hostid)); } else { sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from hosts_groups" " where hostid=" ZBX_FS_UI64 " and", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num); DBexecute("%s", sql); } DBfree_result(result); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: tm_process_check_now * * * * Purpose: process check now tasks for item rescheduling * * * * Return value: The number of successfully processed tasks * * * ******************************************************************************/ static int tm_process_check_now(zbx_vector_uint64_t *taskids) { DB_ROW row; DB_RESULT result; int processed_num; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_vector_uint64_t itemids; zbx_uint64_t itemid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() tasks_num:%d", __func__, taskids->values_num); zbx_vector_uint64_create(&itemids); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select itemid from task_check_now where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids->values, taskids->values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); zbx_vector_uint64_append(&itemids, itemid); } DBfree_result(result); if (0 != (processed_num = itemids.values_num)) zbx_dc_reschedule_items(&itemids, time(NULL), NULL); if (0 != taskids->values_num) { sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update task set status=%d where", ZBX_TM_STATUS_DONE); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "taskid", taskids->values, taskids->values_num); DBexecute("%s", sql); } zbx_free(sql); zbx_vector_uint64_destroy(&itemids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s() processed:%d", __func__, processed_num); return processed_num; }
/****************************************************************************** * * * 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); }
static void make_delete_sql(char **sql, size_t *sql_alloc, size_t *sql_offset, const ZBX_TABLE *table, zbx_uint64_t *ids, int *ids_num) { if (NULL == table) return; if (0 == *ids_num) return; zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "delete from %s where", table->table); DBadd_condition_alloc(sql, sql_alloc, sql_offset, table->recid, ids, *ids_num); zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n"); DBexecute_overflowed_sql(sql, sql_alloc, sql_offset); *ids_num = 0; }
/****************************************************************************** * * * 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); }
/****************************************************************************** * * * 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); }
/****************************************************************************** * * * Function: process_record * * * * Purpose: process record update * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int process_record(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid, const ZBX_TABLE *table, const char *record, int lastrecord, int acknowledges, zbx_vector_uint64_t *ack_eventids) { const char *r; int f, res = FAIL; char *value_esc; zabbix_log(LOG_LEVEL_DEBUG, "In process_record()"); if (0 == *sql_offset) { DBbegin_multiple_update(sql, sql_alloc, sql_offset); #ifdef HAVE_MULTIROW_INSERT begin_history_sql(sql, sql_alloc, sql_offset, table); #endif } #if !defined(HAVE_MULTIROW_INSERT) begin_history_sql(sql, sql_alloc, sql_offset, table); #endif zbx_chrcpy_alloc(sql, sql_alloc, sql_offset, '('); if (0 != (table->flags & ZBX_HISTORY_SYNC)) zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%d,", nodeid); for (r = record, f = 0; table->fields[f].name != 0; f++) { if (0 != (table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; if (NULL == r) goto error; zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); if (0 != acknowledges && 0 == strcmp(table->fields[f].name, "eventid")) { zbx_uint64_t eventid; ZBX_STR2UINT64(eventid, buffer); zbx_vector_uint64_append(ack_eventids, eventid); } if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%s,", buffer); } else if (table->fields[f].type == ZBX_TYPE_BLOB) { if ('\0' == *buffer) zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "'',"); else { #ifdef HAVE_POSTGRESQL size_t len; len = zbx_hex2binary(buffer); zbx_pg_escape_bytea((u_char *)buffer, len, &tmp, &tmp_alloc); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", tmp); #else zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "0x%s,", buffer); #endif } } else /* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */ { zbx_hex2binary(buffer); value_esc = DBdyn_escape_string(buffer); zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", value_esc); zbx_free(value_esc); } } (*sql_offset)--; #ifdef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "),"); #else zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ");\n"); #endif if (0 != lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE) { #ifdef HAVE_MULTIROW_INSERT (*sql_offset)--; zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n"); #endif DBend_multiple_update(sql, sql_alloc, sql_offset); if (ZBX_DB_OK <= DBexecute("%s", *sql)) res = SUCCEED; *sql_offset = 0; if (SUCCEED == res && 0 != lastrecord && 0 != acknowledges && 0 != ack_eventids->values_num) { zbx_vector_uint64_sort(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_uniq(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "update events" " set acknowledged=1" " where"); DBadd_condition_alloc(sql, sql_alloc, sql_offset, "eventid", ack_eventids->values, ack_eventids->values_num); if (ZBX_DB_OK > DBexecute("%s", *sql)) res = FAIL; *sql_offset = 0; } } else res = SUCCEED; return res; error: zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]", CONFIG_NODEID, sender_nodeid, nodeid, record); return FAIL; }
/****************************************************************************** * * * Function: evaluate_aggregate * * * * Parameters: grpfunc - grpavg, grpmax, grpmin, grpsum * * groups - list of comma-separated host groups * * itemkey - item key to aggregate * * itemfunc - avg, count, last, max, min, sum * * param - itemfunc parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(AGENT_RESULT *res, const char *grpfunc, const char *groups, const char *itemkey, const char *itemfunc, const char *param) { const char *__function_name = "evaluate_aggregate"; char *sql = NULL; size_t sql_alloc = 1024, sql_offset = 0; zbx_uint64_t itemid, *ids = NULL; int ids_alloc = 0, ids_num = 0; DB_RESULT result; DB_ROW row; unsigned char value_type; double d = 0; int num = 0; int item_func, grp_func; int ret = FAIL; int grpany_offset = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grpfunc:'%s' groups:'%s' itemkey:'%s' function:'%s(%s)'", __function_name, grpfunc, groups, itemkey, itemfunc, param); if (0 == strcmp(grpfunc, "grpmin")) grp_func = ZBX_GRP_FUNC_MIN; else if (0 == strcmp(grpfunc, "grpavg")) grp_func = ZBX_GRP_FUNC_AVG; else if (0 == strcmp(grpfunc, "grpmax")) grp_func = ZBX_GRP_FUNC_MAX; else if (0 == strcmp(grpfunc, "grpsum")) grp_func = ZBX_GRP_FUNC_SUM; else if (0 == strcmp(grpfunc, "grpany")) grp_func = ZBX_GRP_FUNC_ANY; else goto clean; if (0 == strcmp(itemfunc, "min")) item_func = ZBX_DB_GET_HIST_MIN; else if (0 == strcmp(itemfunc, "avg")) item_func = ZBX_DB_GET_HIST_AVG; else if (0 == strcmp(itemfunc, "max")) item_func = ZBX_DB_GET_HIST_MAX; else if (0 == strcmp(itemfunc, "sum")) item_func = ZBX_DB_GET_HIST_SUM; else if (0 == strcmp(itemfunc, "count")) item_func = ZBX_DB_GET_HIST_COUNT; else if (0 == strcmp(itemfunc, "last")) item_func = ZBX_DB_GET_HIST_VALUE; else { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid third parameter")); goto clean; } aggregate_get_items(&ids, &ids_alloc, &ids_num, groups, itemkey); if (0 == ids_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_ANY == grp_func) { /* * * * Adding linked host-level itemids into historyitems * so it will insert the data into history for trigger * * Also disabled the grpany item(group level item) writting * We do not need to duplicate the values * As we changed the evalfunc and expression * to expand the group and eval the trigger value from history table directly * */ for (grpany_offset = 0; grpany_offset < ids_num ; ++grpany_offset) { itemid = ids[grpany_offset]; DCadd_historyitems(itemid); } SET_DBL_RESULT(res, 1); grp_func = ZBX_GRP_FUNC_ANY; ret = SUCCEED; goto clean; } sql = zbx_malloc(sql, sql_alloc); if (ZBX_DB_GET_HIST_VALUE == item_func) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select value_type,lastvalue" " from items" " where lastvalue is not null" " and value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", ids, ids_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { value_type = (unsigned char)atoi(row[0]); evaluate_one(&d, &num, grp_func, row[1], value_type); } DBfree_result(result); } else { int clock_from; unsigned int period; char **h_value; if (FAIL == is_uint_suffix(param, &period)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter")); goto clean; } clock_from = time(NULL) - period; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,value_type" " from items" " where value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", ids, ids_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); value_type = (unsigned char)atoi(row[1]); h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0); if (NULL != h_value[0]) { evaluate_one(&d, &num, grp_func, h_value[0], value_type); } DBfree_history(h_value); } DBfree_result(result); } if (0 == num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key [%s] in group [%s]", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_AVG == grp_func) d = d / num; SET_DBL_RESULT(res, d); zabbix_log(LOG_LEVEL_DEBUG, "%s() result:" ZBX_FS_DBL, __function_name, d); ret = SUCCEED; clean: zbx_free(ids); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * 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: save_template_lld_rules * * * * Purpose: saves template lld rule item conditions to the target host in * * database * * * * Parameters: items - [IN] the template items * * rules - [IN] the ldd rule mapping * * new_conditions - [IN] the number of new item conditions to * * be inserted * * * ******************************************************************************/ static void save_template_lld_rules(zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules, int new_conditions) { char *macro_esc, *value_esc; int i, j, index; zbx_db_insert_t db_insert; zbx_lld_rule_map_t *rule; zbx_lld_rule_condition_t *condition; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_vector_uint64_t item_conditionids; if (0 == rules->values_num) return; zbx_vector_uint64_create(&item_conditionids); if (0 != new_conditions) { zbx_db_insert_prepare(&db_insert, "item_condition", "item_conditionid", "itemid", "operator", "macro", "value", NULL); /* insert lld rule conditions for new items */ for (i = 0; i < items->values_num; i++) { zbx_template_item_t *item = items->values[i]; if (NULL == item->key) continue; if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags)) continue; index = zbx_vector_ptr_bsearch(rules, &item->templateid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); if (FAIL == index) { THIS_SHOULD_NEVER_HAPPEN; continue; } rule = rules->values[index]; for (j = 0; j < rule->conditions.values_num; j++) { condition = rule->conditions.values[j]; zbx_db_insert_add_values(&db_insert, rule->conditionid++, item->itemid, (int)condition->operator, condition->macro, condition->value); } } } DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); /* update lld rule conditions for existing items */ for (i = 0; i < rules->values_num; i++) { rule = rules->values[i]; /* skip lld rules of new items */ if (0 == rule->itemid) continue; index = MIN(rule->conditions.values_num, rule->conditionids.values_num); /* update intersecting rule conditions */ for (j = 0; j < index; j++) { condition = rule->conditions.values[j]; macro_esc = DBdyn_escape_string(condition->macro); value_esc = DBdyn_escape_string(condition->value); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update item_condition" " set operator=%d,macro='%s',value='%s'" " where item_conditionid=" ZBX_FS_UI64 ";\n", (int)condition->operator, macro_esc, value_esc, rule->conditionids.values[j]); DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset); zbx_free(value_esc); zbx_free(macro_esc); } /* delete removed rule conditions */ for (j = index; j < rule->conditionids.values_num; j++) zbx_vector_uint64_append(&item_conditionids, rule->conditionids.values[j]); /* insert new rule conditions */ for (j = index; j < rule->conditions.values_num; j++) { condition = rule->conditions.values[j]; zbx_db_insert_add_values(&db_insert, rule->conditionid++, rule->itemid, (int)condition->operator, condition->macro, condition->value); } } /* delete removed item conditions */ if (0 != item_conditionids.values_num) { zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_condition where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "item_conditionid", item_conditionids.values, item_conditionids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); } DBend_multiple_update(&sql, &sql_alloc, &sql_offset); if (16 < sql_offset) DBexecute("%s", sql); if (0 != new_conditions) { zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); } zbx_free(sql); zbx_vector_uint64_destroy(&item_conditionids); }
/****************************************************************************** * * * 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); }
/****************************************************************************** * * * Function: housekeeping_cleanup * * * * Purpose: remove deleted items data * * * * Return value: number of rows deleted * * * * Author: Alexei Vladishev, Dmitry Borovikov * * * * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all * * * ******************************************************************************/ static int housekeeping_cleanup() { const char *__function_name = "housekeeping_cleanup"; DB_HOUSEKEEPER housekeeper; DB_RESULT result; DB_ROW row; int d, deleted = 0; zbx_vector_uint64_t housekeeperids; char *sql = NULL, *table_name_esc; size_t sql_alloc = 0, sql_offset = 0; zbx_hk_cleanup_table_t *table; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* first handle the trivial case when history and trend housekeeping is disabled */ if (ZBX_HK_OPTION_DISABLED == hk_config.history_mode && ZBX_HK_OPTION_DISABLED == hk_config.trends_mode) goto out; zbx_vector_uint64_create(&housekeeperids); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select housekeeperid,tablename,field,value" " from housekeeper" " where tablename in ("); /* assemble list of tables excluded from housekeeping procedure */ for (table = hk_cleanup_tables; NULL != table->name; table++) { if (ZBX_HK_OPTION_ENABLED != *table->poption_mode) continue; table_name_esc = DBdyn_escape_string(table->name); zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, '\''); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table_name_esc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "',"); zbx_free(table_name_esc); } sql_offset--; /* order by tablename to effectively use DB cache */ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ") order by tablename"); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]); housekeeper.tablename = row[1]; housekeeper.field = row[2]; ZBX_STR2UINT64(housekeeper.value, row[3]); if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE) { d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64, housekeeper.tablename, housekeeper.field, housekeeper.value); } else { #if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE) d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " and rownum<=%d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_MYSQL) d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " limit %d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_POSTGRESQL) d = DBexecute( "delete from %s" " where ctid = any(array(select ctid from %s" " where %s=" ZBX_FS_UI64 " limit %d))", housekeeper.tablename, housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_SQLITE3) d = 0; #endif } if (ZBX_DB_OK <= d) { if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d) zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid); deleted += d; } } DBfree_result(result); if (0 != housekeeperids.values_num) { zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql_offset = 0; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from housekeeper where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid", housekeeperids.values, housekeeperids.values_num); DBexecute("%s", sql); } zbx_free(sql); zbx_vector_uint64_destroy(&housekeeperids); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted); return deleted; }
/****************************************************************************** * * * Function: lld_graphs_validate * * * * Parameters: graphs - [IN] sorted list of graphs * * * ******************************************************************************/ static void lld_graphs_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *graphs, char **error) { const char *__function_name = "lld_graphs_validate"; int i, j; zbx_lld_graph_t *graph, *graph_b; zbx_vector_uint64_t graphids; zbx_vector_str_t names; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&graphids); zbx_vector_str_create(&names); /* list of graph names */ /* checking a validity of the fields */ for (i = 0; i < graphs->values_num; i++) { graph = (zbx_lld_graph_t *)graphs->values[i]; lld_validate_graph_field(graph, &graph->name, &graph->name_orig, ZBX_FLAG_LLD_GRAPH_UPDATE_NAME, GRAPH_NAME_LEN, error); } /* checking duplicated graph names */ 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; /* only new graphs or graphs with changed name will be validated */ if (0 != graph->graphid && 0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME)) continue; for (j = 0; j < graphs->values_num; j++) { graph_b = (zbx_lld_graph_t *)graphs->values[j]; if (0 == (graph_b->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED) || i == j) continue; if (0 != strcmp(graph->name, graph_b->name)) continue; *error = zbx_strdcatf(*error, "Cannot %s graph:" " graph with the same name \"%s\" already exists.\n", (0 != graph->graphid ? "update" : "create"), graph->name); if (0 != graph->graphid) { lld_field_str_rollback(&graph->name, &graph->name_orig, &graph->flags, ZBX_FLAG_LLD_GRAPH_UPDATE_NAME); } else graph->flags &= ~ZBX_FLAG_LLD_GRAPH_DISCOVERED; break; } } /* checking duplicated graphs in DB */ 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_vector_uint64_append(&graphids, graph->graphid); if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME)) continue; } zbx_vector_str_append(&names, graph->name); } if (0 != names.values_num) { DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; sql = zbx_malloc(sql, sql_alloc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select g.name" " from graphs g,graphs_items gi,items i" " where g.graphid=gi.graphid" " and gi.itemid=i.itemid" " and i.hostid=" ZBX_FS_UI64 " and", hostid); DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "g.name", (const char **)names.values, names.values_num); if (0 != graphids.values_num) { zbx_vector_uint64_sort(&graphids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "g.graphid", graphids.values, graphids.values_num); } result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { 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 == strcmp(graph->name, row[0])) { *error = zbx_strdcatf(*error, "Cannot %s graph:" " graph with the same name \"%s\" already exists.\n", (0 != graph->graphid ? "update" : "create"), graph->name); if (0 != graph->graphid) { lld_field_str_rollback(&graph->name, &graph->name_orig, &graph->flags, ZBX_FLAG_LLD_GRAPH_UPDATE_NAME); } else graph->flags &= ~ZBX_FLAG_LLD_GRAPH_DISCOVERED; continue; } } } DBfree_result(result); zbx_free(sql); } zbx_vector_str_destroy(&names); zbx_vector_uint64_destroy(&graphids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: add_discovered_host_groups * * * * Purpose: add group to host if not added already * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static void add_discovered_host_groups(zbx_uint64_t hostid, zbx_vector_uint64_t *groupids) { const char *__function_name = "add_discovered_host_groups"; DB_RESULT result; DB_ROW row; zbx_uint64_t groupid; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; int i; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sql = zbx_malloc(sql, sql_alloc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select groupid" " from hosts_groups" " where hostid=" ZBX_FS_UI64 " and", hostid); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "groupid", groupids->values, groupids->values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(groupid, row[0]); if (FAIL == (i = zbx_vector_uint64_bsearch(groupids, groupid, ZBX_DEFAULT_UINT64_COMPARE_FUNC))) { THIS_SHOULD_NEVER_HAPPEN; continue; } zbx_vector_uint64_remove_noorder(groupids, i); } DBfree_result(result); if (0 != groupids->values_num) { const char *ins_hosts_groups_sql = "insert into hosts_groups (hostgroupid,hostid,groupid) values "; zbx_uint64_t hostgroupid; hostgroupid = DBget_maxid_num("hosts_groups", groupids->values_num); sql_offset = 0; DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); #ifdef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_hosts_groups_sql); #endif for (i = 0; i < groupids->values_num; i++) { #ifndef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_hosts_groups_sql); #endif zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "(" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ")" ZBX_ROW_DL, hostgroupid++, hostid, groupids->values[i]); } #ifdef HAVE_MULTIROW_INSERT sql_offset--; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); #endif DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); } zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void update_maintenance_hosts(zbx_host_maintenance_t *hm, int hm_count, int now) { typedef struct { zbx_uint64_t hostid; int maintenance_from; void *next; } maintenance_t; const char *__function_name = "update_maintenance_hosts"; int i; zbx_uint64_t *ids = NULL, hostid; int ids_alloc = 0, ids_num = 0; DB_RESULT result; DB_ROW row; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset; maintenance_t *maintenances = NULL, *m; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); sql = zbx_malloc(sql, sql_alloc); DBbegin(); for (i = 0; i < hm_count; i++) { if (SUCCEED == uint64_array_exists(ids, ids_num, hm[i].hostid)) continue; if (hm[i].host_maintenanceid != hm[i].maintenanceid || HOST_MAINTENANCE_STATUS_ON != hm[i].host_maintenance_status || hm[i].host_maintenance_type != hm[i].maintenance_type || 0 == hm[i].host_maintenance_from) { zabbix_log(LOG_LEVEL_WARNING, "putting host [%s] into maintenance (with%s data collection)", hm[i].host, MAINTENANCE_TYPE_NORMAL == hm[i].maintenance_type ? "" : "out"); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update hosts" " set maintenanceid=" ZBX_FS_UI64 "," "maintenance_status=%d," "maintenance_type=%d", hm[i].maintenanceid, HOST_MAINTENANCE_STATUS_ON, hm[i].maintenance_type); if (0 == hm[i].host_maintenance_from) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",maintenance_from=%d", hm[i].maintenance_from); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where hostid=" ZBX_FS_UI64, hm[i].hostid); DBexecute("%s", sql); DCconfig_set_maintenance(&hm[i].hostid, 1, HOST_MAINTENANCE_STATUS_ON, hm[i].maintenance_type, hm[i].maintenance_from); } uint64_array_add(&ids, &ids_alloc, &ids_num, hm[i].hostid, 4); } sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select hostid,host,maintenance_type,maintenance_from" " from hosts" " where status=%d" " and flags<>%d" " and maintenance_status=%d", HOST_STATUS_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_MAINTENANCE_STATUS_ON); if (NULL != ids && 0 != ids_num) { zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num); } result = DBselect("%s", sql); ids_num = 0; while (NULL != (row = DBfetch(result))) { zabbix_log(LOG_LEVEL_WARNING, "taking host [%s] out of maintenance", row[1]); ZBX_STR2UINT64(hostid, row[0]); uint64_array_add(&ids, &ids_alloc, &ids_num, hostid, 4); if (MAINTENANCE_TYPE_NORMAL != atoi(row[2])) continue; m = zbx_malloc(NULL, sizeof(maintenance_t)); m->hostid = hostid; m->maintenance_from = atoi(row[3]); m->next = maintenances; maintenances = m; } DBfree_result(result); sql_offset = 0; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update hosts" " set maintenanceid=null," "maintenance_status=%d," "maintenance_type=0," "maintenance_from=0" " where", HOST_MAINTENANCE_STATUS_OFF); if (NULL != ids && 0 != ids_num) { DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num); DBexecute("%s", sql); DCconfig_set_maintenance(ids, ids_num, HOST_MAINTENANCE_STATUS_OFF, 0, 0); } DBcommit(); zbx_free(sql); zbx_free(ids); for (m = maintenances; NULL != m; m = m->next) generate_events(m->hostid, m->maintenance_from, now); for (m = maintenances; NULL != m; m = maintenances) { maintenances = m->next; zbx_free(m); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: db_get_query_functions * * * * Purpose: get event query functionids from database * * * ******************************************************************************/ static void db_get_query_functions(zbx_vector_ptr_t *event_queries) { DB_ROW row; DB_RESULT result; int i; zbx_vector_uint64_t triggerids; zbx_hashset_t triggers; zbx_hashset_iter_t iter; char *sql = NULL; size_t sql_alloc = 0, sql_offset = 0; zbx_trigger_functions_t *trigger = NULL, trigger_local; zbx_uint64_t triggerid, functionid; zbx_event_suppress_query_t *query; /* cache functionids by triggerids */ zbx_hashset_create(&triggers, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_create(&triggerids); for (i = 0; i < event_queries->values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries->values[i]; zbx_vector_uint64_append(&triggerids, query->triggerid); } zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_uniq(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select functionid,triggerid from functions where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values, triggerids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by triggerid"); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(functionid, row[0]); ZBX_STR2UINT64(triggerid, row[1]); if (NULL == trigger || trigger->triggerid != triggerid) { trigger_local.triggerid = triggerid; trigger = (zbx_trigger_functions_t *)zbx_hashset_insert(&triggers, &trigger_local, sizeof(trigger_local)); zbx_vector_uint64_create(&trigger->functionids); } zbx_vector_uint64_append(&trigger->functionids, functionid); } DBfree_result(result); /* copy functionids to event queries */ for (i = 0; i < event_queries->values_num; i++) { query = (zbx_event_suppress_query_t *)event_queries->values[i]; if (NULL == (trigger = (zbx_trigger_functions_t *)zbx_hashset_search(&triggers, &query->triggerid))) continue; zbx_vector_uint64_append_array(&query->functionids, trigger->functionids.values, trigger->functionids.values_num); } zbx_hashset_iter_reset(&triggers, &iter); while (NULL != (trigger = (zbx_trigger_functions_t *)zbx_hashset_iter_next(&iter))) zbx_vector_uint64_destroy(&trigger->functionids); zbx_hashset_destroy(&triggers); zbx_vector_uint64_destroy(&triggerids); }
/****************************************************************************** * * * 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: DCflush_nextchecks * * * * Purpose: add item nextcheck to the array * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev, Dmitry Borovikov * * * * Comments: * * * ******************************************************************************/ void DCflush_nextchecks() { const char *__function_name = "DCflush_nextchecks"; int i, sql_offset = 0, sql_allocated = 4096; char *sql = NULL; DB_RESULT result; DB_ROW row; zbx_uint64_t triggerid; zbx_uint64_t itemid; zbx_uint64_t events_maxid = 0; char *error_msg_esc = NULL; char *sql_select = NULL; int sql_select_offset = 0, sql_select_allocated = 512; /* a crutch for the function `DBadd_condition_alloc' */ zbx_uint64_t *ids = NULL; int ids_allocated = 0, ids_num = 0; zbx_uint64_t *triggerids = NULL; int triggerids_allocated = 0, triggerids_num = 0; struct event_objectid_clock *events = NULL; int events_num = 0, events_allocated = 32; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (nextcheck_num == 0) return; sql = zbx_malloc(sql, sql_allocated); DBbegin(); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif /* dealing with items */ for (i = 0; i < nextcheck_num; i++) { if (NULL == nextchecks[i].error_msg) continue; uint64_array_add(&ids, &ids_allocated, &ids_num, nextchecks[i].itemid, 64); error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update items set status=%d,lastclock=%d,error='%s' where itemid=" ZBX_FS_UI64 ";\n", ITEM_STATUS_NOTSUPPORTED, (int)nextchecks[i].now, error_msg_esc, nextchecks[i].itemid); zbx_free(error_msg_esc); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } /* dealing with notsupported items */ if (ids_num > 0) { sql_select = zbx_malloc(sql_select, sql_select_allocated); events = zbx_malloc(events, events_allocated * sizeof(struct event_objectid_clock)); /* preparing triggers */ zbx_snprintf_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, 256, "select t.triggerid,i.itemid" " from triggers t,functions f,items i" " where t.triggerid=f.triggerid" " and f.itemid=i.itemid" " and t.status in (%d)" " and t.value not in (%d)" " and", TRIGGER_STATUS_ENABLED, TRIGGER_VALUE_UNKNOWN); DBadd_condition_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, "i.itemid", ids, ids_num); result = DBselect("%s", sql_select); zbx_free(sql_select); /* processing triggers */ while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(triggerid, row[0]); ZBX_STR2UINT64(itemid, row[1]); /* do not generate multiple unknown events for a trigger */ if (SUCCEED == uint64_array_exists(triggerids, triggerids_num, triggerid)) continue; uint64_array_add(&triggerids, &triggerids_allocated, &triggerids_num, triggerid, 64); /* index `i' will surely contain necessary itemid */ i = get_nearestindex(nextchecks, sizeof(ZBX_DC_NEXTCHECK), nextcheck_num, itemid); if (i == nextcheck_num || nextchecks[i].itemid != itemid) { THIS_SHOULD_NEVER_HAPPEN; continue; } error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, TRIGGER_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update triggers set value=%d,lastchange=%d,error='%s' where triggerid=" ZBX_FS_UI64";\n", TRIGGER_VALUE_UNKNOWN, nextchecks[i].now, error_msg_esc, triggerid); zbx_free(error_msg_esc); if (events_num == events_allocated) { events_allocated += 32; events = zbx_realloc(events, events_allocated * sizeof(struct event_objectid_clock)); } events[events_num].objectid = triggerid; events[events_num].clock = nextchecks[i].now; events_num++; DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } DBfree_result(result); /* dealing with events */ for (i = 0; i < events_num; i++) { events_maxid = DBget_maxid("events"); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 256, "insert into events (eventid,source,object,objectid,clock,value) " "values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d);\n", events_maxid, EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, events[i].objectid, events[i].clock, TRIGGER_VALUE_UNKNOWN); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } zbx_free(events); } #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif if (sql_offset > 16) /* In ORACLE always present begin..end; */ DBexecute("%s", sql); zbx_free(sql); zbx_free(ids); zbx_free(triggerids); DCrelease_nextchecks(); DBcommit(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
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: process_deleted_records * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void process_deleted_records(int nodeid, char *data) { const char *__function_name = "process_deleted_records"; typedef struct { const ZBX_TABLE *table; zbx_vector_uint64_t recids; void *next; } zbx_records_t; char *r, *lf; zbx_uint64_t recid; char *sql = NULL; size_t sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0; zbx_records_t *first = NULL, *rec; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); for (r = data; '\0' != *r;) { if (NULL != (lf = strchr(r, '\n'))) *lf = '\0'; zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); /* table name */ if (NULL == first || 0 != strcmp(first->table->table, buf)) { rec = zbx_malloc(NULL, sizeof(zbx_records_t)); if (NULL == (rec->table = DBget_table(buf))) { zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot find table [%s]", __function_name, buf); zbx_free(rec); goto next; } zbx_vector_uint64_create(&rec->recids); rec->next = first; first = rec; } zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); /* record id */ ZBX_STR2UINT64(recid, buf); zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER); /* operation type */ if ('2' == *buf) /* deleted record */ zbx_vector_uint64_append(&rec->recids, recid); next: if (lf != NULL) { *lf++ = '\n'; r = lf; } else break; } sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); for (rec = first; NULL != rec; rec = rec->next) { if (0 == rec->recids.values_num) continue; zbx_vector_uint64_sort(&rec->recids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from %s where", rec->table->table); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, rec->table->recid, rec->recids.values, rec->recids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset); } DBend_multiple_update(&sql, &sql_alloc, &sql_offset); if (sql_offset > 16) /* in ORACLE always present begin..end; */ DBexecute("%s", sql); zbx_free(sql); while (NULL != first) { rec = first; first = rec->next; zbx_vector_uint64_destroy(&rec->recids); zbx_free(rec); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: housekeeping_cleanup * * * * Purpose: remove deleted items data * * * * Return value: number of rows deleted * * * * Author: Alexei Vladishev, Dmitry Borovikov * * * * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all * * * ******************************************************************************/ static int housekeeping_cleanup() { const char *__function_name = "housekeeping_cleanup"; DB_HOUSEKEEPER housekeeper; DB_RESULT result; DB_ROW row; int d, deleted = 0; zbx_vector_uint64_t housekeeperids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&housekeeperids); /* order by tablename to effectively use DB cache */ result = DBselect( "select housekeeperid,tablename,field,value" " from housekeeper" " order by tablename"); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]); housekeeper.tablename = row[1]; housekeeper.field = row[2]; ZBX_STR2UINT64(housekeeper.value, row[3]); if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE) { d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64, housekeeper.tablename, housekeeper.field, housekeeper.value); } else { #if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE) d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " and rownum<=%d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_MYSQL) d = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " limit %d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_POSTGRESQL) d = DBexecute( "delete from %s" " where ctid = any(array(select ctid from %s" " where %s=" ZBX_FS_UI64 " limit %d))", housekeeper.tablename, housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_SQLITE3) d = 0; #endif } if (0 == d || 0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d) zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid); deleted += d; } DBfree_result(result); if (0 != housekeeperids.values_num) { char *sql = NULL; size_t sql_alloc = 512, sql_offset = 0; sql = zbx_malloc(sql, sql_alloc); zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from housekeeper where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid", housekeeperids.values, housekeeperids.values_num); DBexecute("%s", sql); zbx_free(sql); } zbx_vector_uint64_destroy(&housekeeperids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted); return deleted; }
/****************************************************************************** * * * 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: 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_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: 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: 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: evaluate_aggregate * * * * Parameters: item - [IN] aggregated item * * grp_func - [IN] one of ZBX_GRP_FUNC_* * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * item_func - [IN] one of ZBX_DB_GET_HIST_* * * param - [IN] item_func parameter (optional) * * * * Return value: SUCCEED - aggregate item evaluated successfully * * FAIL - otherwise * * * ******************************************************************************/ static int evaluate_aggregate(DC_ITEM *item, AGENT_RESULT *res, int grp_func, const char *groups, const char *itemkey, int item_func, const char *param) { const char *__function_name = "evaluate_aggregate"; char *sql = NULL; size_t sql_alloc = 1024, sql_offset = 0; zbx_uint64_t itemid; zbx_vector_uint64_t itemids; DB_RESULT result; DB_ROW row; unsigned char value_type; history_value_t value; int num = 0, ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() grp_func:%d groups:'%s' itemkey:'%s' item_func:%d param:'%s'", __function_name, grp_func, groups, itemkey, item_func, param); memset(&value, 0, sizeof(value)); zbx_vector_uint64_create(&itemids); aggregate_get_items(&itemids, groups, itemkey); if (0 == itemids.values_num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups)); goto clean; } sql = zbx_malloc(sql, sql_alloc); if (ZBX_DB_GET_HIST_VALUE == item_func) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select value_type,lastvalue" " from items" " where lastvalue is not null" " and value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { value_type = (unsigned char)atoi(row[0]); evaluate_one(item, &value, &num, grp_func, row[1], value_type); } DBfree_result(result); } else { int clock_from; unsigned int period; char **h_value; if (FAIL == is_uint_suffix(param, &period)) { SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter")); goto clean; } clock_from = time(NULL) - period; zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select itemid,value_type" " from items" " where value_type in (%d,%d)" " and", ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64); 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[0]); value_type = (unsigned char)atoi(row[1]); h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0); if (NULL != h_value[0]) evaluate_one(item, &value, &num, grp_func, h_value[0], value_type); DBfree_history(h_value); } DBfree_result(result); } if (0 == num) { SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups)); goto clean; } if (ZBX_GRP_FUNC_AVG == grp_func) { switch (item->value_type) { case ITEM_VALUE_TYPE_FLOAT: value.dbl = value.dbl / num; break; case ITEM_VALUE_TYPE_UINT64: value.ui64 = value.ui64 / num; break; default: assert(0); } } if (ITEM_VALUE_TYPE_FLOAT == item->value_type) SET_DBL_RESULT(res, value.dbl); else SET_UI64_RESULT(res, value.ui64); ret = SUCCEED; clean: zbx_vector_uint64_destroy(&itemids); zbx_free(sql); zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: housekeeping_process_log * * * * Purpose: process table 'housekeeper' and remove data if required * * * * Parameters: * * * * Return value: SUCCEED - information removed successfully * * FAIL - otherwise * * * * Author: Alexei Vladishev, Dmitry Borovikov * * * * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all * * * ******************************************************************************/ static int housekeeping_process_log() { const char *__function_name = "housekeeping_process_log"; DB_HOUSEKEEPER housekeeper; DB_RESULT result; DB_ROW row; long deleted; char *sql = NULL; int sql_alloc = 512, sql_offset = 0; zbx_uint64_t *ids = NULL; int ids_alloc = 0, ids_num = 0; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); /* order by tablename to effectively use DB cache */ result = DBselect( "select housekeeperid,tablename,field,value" " from housekeeper" " order by tablename"); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]); housekeeper.tablename = row[1]; housekeeper.field = row[2]; ZBX_STR2UINT64(housekeeper.value, row[3]); if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE) { deleted = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64, housekeeper.tablename, housekeeper.field, housekeeper.value); } else { #ifdef HAVE_ORACLE deleted = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " and rownum<=%d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_POSTGRESQL) deleted = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " and oid in (select oid from %s" " where %s=" ZBX_FS_UI64 " limit %d)", housekeeper.tablename, housekeeper.field, housekeeper.value, housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #elif defined(HAVE_MYSQL) deleted = DBexecute( "delete from %s" " where %s=" ZBX_FS_UI64 " limit %d", housekeeper.tablename, housekeeper.field, housekeeper.value, CONFIG_MAX_HOUSEKEEPER_DELETE); #else /* HAVE_SQLITE3 */ deleted = 0; #endif } if (0 == deleted || 0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > deleted) uint64_array_add(&ids, &ids_alloc, &ids_num, housekeeper.housekeeperid, 64); if (deleted > 0) { zabbix_log( LOG_LEVEL_DEBUG, "Deleted [%ld] records from table [%s]", deleted, housekeeper.tablename); } } DBfree_result(result); if (NULL != ids) { sql = zbx_malloc(sql, sql_alloc * sizeof(char)); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 32, "delete from housekeeper where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid", ids, ids_num); DBexecute("%s", sql); zbx_free(sql); zbx_free(ids); } return SUCCEED; }