int DBpatch_3020001(void) { DB_RESULT result; zbx_vector_uint64_t eventids; DB_ROW row; zbx_uint64_t eventid; int sources[] = {EVENT_SOURCE_TRIGGERS, EVENT_SOURCE_INTERNAL}; int objects[] = {EVENT_OBJECT_ITEM, EVENT_OBJECT_LLDRULE}, i; zbx_vector_uint64_create(&eventids); for (i = 0; i < (int)ARRSIZE(sources); i++) { result = DBselect( "select p.eventid" " from problem p" " where p.source=%d and p.object=%d and not exists (" "select null" " from triggers t" " where t.triggerid=p.objectid" ")", sources[i], EVENT_OBJECT_TRIGGER); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(eventid, row[0]); zbx_vector_uint64_append(&eventids, eventid); } DBfree_result(result); } for (i = 0; i < (int)ARRSIZE(objects); i++) { result = DBselect( "select p.eventid" " from problem p" " where p.source=%d and p.object=%d and not exists (" "select null" " from items i" " where i.itemid=p.objectid" ")", EVENT_SOURCE_INTERNAL, objects[i]); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(eventid, row[0]); zbx_vector_uint64_append(&eventids, eventid); } DBfree_result(result); } zbx_vector_uint64_sort(&eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); if (0 != eventids.values_num) DBexecute_multiple_query("delete from problem where", "eventid", &eventids); zbx_vector_uint64_destroy(&eventids); return SUCCEED; }
/****************************************************************************** * * * Function: procstat_get_monitored_pids * * * * Purpose: creates a list of unique pids that are monitored by current data * * gathering cycle * * * * Parameters: pids - [OUT] a sorted vector of unique pids * * queries - [IN] local, working copy of queries * * pids_num - [IN] the total number of pids monitored by queries * * (might contain duplicated pids) * * * ******************************************************************************/ static void procstat_get_monitored_pids(zbx_vector_uint64_t *pids, const zbx_vector_ptr_t *queries, int pids_num) { zbx_procstat_query_data_t *qdata; int i; zbx_vector_uint64_reserve(pids, pids_num); for (i = 0; i < queries->values_num; i++) { qdata = (zbx_procstat_query_data_t *)queries->values[i]; if (SUCCEED != qdata->error) continue; memcpy(pids->values + pids->values_num, qdata->pids.values, sizeof(zbx_uint64_t) * qdata->pids.values_num); pids->values_num += qdata->pids.values_num; } zbx_vector_uint64_sort(pids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_vector_uint64_uniq(pids, ZBX_DEFAULT_UINT64_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; 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: 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; }
static void process_escalations(int now) { const char *__function_name = "process_escalations"; DB_RESULT result; DB_ROW row; DB_ESCALATION escalation, last_escalation; zbx_vector_uint64_t escalationids; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&escalationids); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select escalationid,actionid,triggerid,eventid,r_eventid,esc_step,status,nextcheck" " from escalations" " where 1=1" DB_NODE " order by actionid,triggerid,escalationid", DBnode_local("escalationid")); memset(&escalation, 0, sizeof(escalation)); do { memset(&last_escalation, 0, sizeof(last_escalation)); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(last_escalation.escalationid, row[0]); ZBX_STR2UINT64(last_escalation.actionid, row[1]); ZBX_DBROW2UINT64(last_escalation.triggerid, row[2]); ZBX_DBROW2UINT64(last_escalation.eventid, row[3]); ZBX_DBROW2UINT64(last_escalation.r_eventid, row[4]); last_escalation.esc_step = atoi(row[5]); last_escalation.status = atoi(row[6]); last_escalation.nextcheck = atoi(row[7]); /* just delete on the next cycle */ if (0 != last_escalation.r_eventid) last_escalation.status = ESCALATION_STATUS_COMPLETED; } if (0 != escalation.escalationid) { unsigned char esc_superseded = 0; if (ESCALATION_STATUS_COMPLETED == escalation.status) { /* delete a recovery record and skip all processing */ zbx_vector_uint64_append(&escalationids, escalation.escalationid); goto next; } if (0 != last_escalation.escalationid) { esc_superseded = (escalation.actionid == last_escalation.actionid && escalation.triggerid == last_escalation.triggerid); if (1 == esc_superseded) { if (0 != last_escalation.r_eventid) { /* recover this escalation */ escalation.r_eventid = last_escalation.r_eventid; escalation.status = ESCALATION_STATUS_ACTIVE; } else if (escalation.nextcheck > now || ESCALATION_STATUS_SLEEP == escalation.status) { zbx_vector_uint64_append(&escalationids, escalation.escalationid); goto next; } } } if (ESCALATION_STATUS_ACTIVE != escalation.status || (escalation.nextcheck > now && 0 == escalation.r_eventid)) { goto next; } DBbegin(); if (escalation.nextcheck <= now) execute_escalation(&escalation); /* execute recovery */ if (ESCALATION_STATUS_COMPLETED != escalation.status && 0 != escalation.r_eventid) { escalation.status = ESCALATION_STATUS_RECOVERY; execute_escalation(&escalation); } else if (1 == esc_superseded) escalation.status = ESCALATION_STATUS_COMPLETED; sql_offset = 0; if (ESCALATION_STATUS_COMPLETED != escalation.status) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update escalations set status=%d", escalation.status); if (ESCALATION_STATUS_ACTIVE == escalation.status) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",esc_step=%d,nextcheck=%d", escalation.esc_step, escalation.nextcheck); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where escalationid=" ZBX_FS_UI64, escalation.escalationid); } else { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from escalations where escalationid=" ZBX_FS_UI64, escalation.escalationid); } DBexecute("%s", sql); DBcommit(); } next: if (NULL != row) memcpy(&escalation, &last_escalation, sizeof(escalation)); } while (NULL != row); DBfree_result(result); zbx_free(sql); /* delete completed escalations */ if (0 != escalationids.values_num) { zbx_vector_uint64_sort(&escalationids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); DBbegin(); DBexecute_multiple_query("delete from escalations where", "escalationid", &escalationids); DBcommit(); } zbx_vector_uint64_destroy(&escalationids); 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: 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: 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: 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: 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: 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: lld_functions_get * * * * Purpose: retrieve functions which are used by all triggers in the host of * * the trigger prototype * * * ******************************************************************************/ static void lld_functions_get(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *functions_proto, zbx_vector_ptr_t *triggers) { const char *__function_name = "lld_functions_get"; int i; zbx_lld_trigger_t *trigger; zbx_vector_uint64_t triggerids; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_uint64_create(&triggerids); if (0 != parent_triggerid) zbx_vector_uint64_append(&triggerids, parent_triggerid); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; zbx_vector_uint64_append(&triggerids, trigger->triggerid); } if (0 != triggerids.values_num) { DB_RESULT result; DB_ROW row; zbx_lld_function_t *function; zbx_uint64_t triggerid; char *sql = NULL; size_t sql_alloc = 256, sql_offset = 0; int index; zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); sql = zbx_malloc(sql, sql_alloc); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select functionid,triggerid,itemid,function,parameter" " from functions" " where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values, triggerids.values_num); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { function = zbx_malloc(NULL, sizeof(zbx_lld_function_t)); function->index = 0; ZBX_STR2UINT64(function->functionid, row[0]); ZBX_STR2UINT64(triggerid, row[1]); ZBX_STR2UINT64(function->itemid, row[2]); function->itemid_orig = 0; function->function = zbx_strdup(NULL, row[3]); function->function_orig = NULL; function->parameter = zbx_strdup(NULL, row[4]); function->parameter_orig = NULL; function->flags = ZBX_FLAG_LLD_FUNCTION_UNSET; if (0 != parent_triggerid && triggerid == parent_triggerid) { zbx_vector_ptr_append(functions_proto, function); } else if (FAIL != (index = zbx_vector_ptr_bsearch(triggers, &triggerid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))) { trigger = (zbx_lld_trigger_t *)triggers->values[index]; zbx_vector_ptr_append(&trigger->functions, function); } else { THIS_SHOULD_NEVER_HAPPEN; lld_function_free(function); } } DBfree_result(result); if (NULL != functions_proto) zbx_vector_ptr_sort(functions_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; zbx_vector_ptr_sort(&trigger->functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); } } zbx_vector_uint64_destroy(&triggerids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: lld_triggers_save * * * * Purpose: add or update triggers in database based on discovery rule * * * ******************************************************************************/ static void lld_triggers_save(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *triggers, unsigned char status, unsigned char type, unsigned char priority, const char *url) { const char *__function_name = "lld_triggers_save"; int i, j, new_triggers = 0, upd_triggers = 0, new_functions = 0; zbx_lld_trigger_t *trigger; zbx_lld_function_t *function; zbx_vector_ptr_t upd_functions; /* the ordered list of functions which will be updated */ zbx_vector_uint64_t del_functionids; zbx_uint64_t triggerid = 0, functionid = 0; unsigned char flags = ZBX_FLAG_LLD_TRIGGER_UNSET; char *sql = NULL, *url_esc = NULL, *function_esc, *parameter_esc; size_t sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0; zbx_db_insert_t db_insert, db_insert_tdiscovery, db_insert_tfunctions; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&upd_functions); zbx_vector_uint64_create(&del_functionids); for (i = 0; i < triggers->values_num; i++) { trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; if (0 == trigger->triggerid) { new_triggers++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { upd_triggers++; flags |= trigger->flags; } for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) { zbx_vector_uint64_append(&del_functionids, function->functionid); continue; } if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) new_functions++; else if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE)) zbx_vector_ptr_append(&upd_functions, function); } } if (0 == new_triggers && 0 == new_functions && 0 == upd_triggers && 0 == upd_functions.values_num && 0 == del_functionids.values_num) { goto out; } DBbegin(); if (0 != new_triggers) { triggerid = DBget_maxid_num("triggers", new_triggers); zbx_db_insert_prepare(&db_insert, "triggers", "triggerid", "description", "expression", "priority", "status", "comments", "url", "type", "value", "state", "flags", NULL); zbx_db_insert_prepare(&db_insert_tdiscovery, "trigger_discovery", "triggerid", "parent_triggerid", NULL); } if (0 != new_functions) { functionid = DBget_maxid_num("functions", new_functions); zbx_db_insert_prepare(&db_insert_tfunctions, "functions", "functionid", "itemid", "triggerid", "function", "parameter", NULL); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); } if (0 != (flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) url_esc = DBdyn_escape_string(url); for (i = 0; i < triggers->values_num; i++) { char *description_esc, *expression_esc, *comments_esc; trigger = (zbx_lld_trigger_t *)triggers->values[i]; if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED)) continue; for (j = 0; j < trigger->functions.values_num; j++) { function = (zbx_lld_function_t *)trigger->functions.values[j]; if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE)) continue; if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED)) continue; if (0 == function->functionid) { zbx_db_insert_add_values(&db_insert_tfunctions, functionid, function->itemid, (0 == trigger->triggerid ? triggerid : trigger->triggerid), function->function, function->parameter); function->functionid = functionid++; } } if (0 == trigger->triggerid || 0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) lld_expression_create(&trigger->expression, &trigger->functions); if (0 == trigger->triggerid) { zbx_db_insert_add_values(&db_insert, triggerid, trigger->description, trigger->expression, (int)priority, (int)status, trigger->comments, url, (int)type, (int)TRIGGER_VALUE_OK, (int)TRIGGER_STATE_NORMAL, (int)ZBX_FLAG_DISCOVERY_CREATED); zbx_db_insert_add_values(&db_insert_tdiscovery, triggerid, parent_triggerid); trigger->triggerid = triggerid++; } else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE)) { const char *d = ""; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update triggers set "); if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION)) { description_esc = DBdyn_escape_string(trigger->description); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "description='%s'", description_esc); zbx_free(description_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION)) { expression_esc = DBdyn_escape_string(trigger->expression); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sexpression='%s'", d, expression_esc); zbx_free(expression_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_TYPE)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)type); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_PRIORITY)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spriority=%d", d, (int)priority); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS)) { comments_esc = DBdyn_escape_string(trigger->comments); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scomments='%s'", d, comments_esc); zbx_free(comments_esc); d = ","; } if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL)) zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%surl='%s'", d, url_esc); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where triggerid=" ZBX_FS_UI64 ";\n", trigger->triggerid); } } zbx_free(url_esc); zbx_vector_ptr_sort(&upd_functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC); for (i = 0; i < upd_functions.values_num; i++) { const char *d = ""; function = (zbx_lld_function_t *)upd_functions.values[i]; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update functions set "); if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID)) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64, function->itemid); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION)) { function_esc = DBdyn_escape_string(function->function); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sfunction='%s'", d, function_esc); zbx_free(function_esc); d = ","; } if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER)) { parameter_esc = DBdyn_escape_string(function->parameter); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sparameter='%s'", d, parameter_esc); zbx_free(parameter_esc); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where functionid=" ZBX_FS_UI64 ";\n", function->functionid); } if (0 != del_functionids.values_num) { zbx_vector_uint64_sort(&del_functionids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from functions where"); DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "functionid", del_functionids.values, del_functionids.values_num); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); } if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num) { DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); zbx_free(sql); } if (0 != new_triggers) { zbx_db_insert_execute(&db_insert); zbx_db_insert_clean(&db_insert); zbx_db_insert_execute(&db_insert_tdiscovery); zbx_db_insert_clean(&db_insert_tdiscovery); } if (0 != new_functions) { zbx_db_insert_execute(&db_insert_tfunctions); zbx_db_insert_clean(&db_insert_tfunctions); } DBcommit(); out: zbx_vector_uint64_destroy(&del_functionids); zbx_vector_ptr_destroy(&upd_functions); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: 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: 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_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: 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_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: aggregate_get_items * * * * Purpose: get array of items specified by key for selected groups * * * * Parameters: itemids - [OUT] list of item ids * * groups - [IN] list of comma-separated host groups * * itemkey - [IN] item key to aggregate * * * ******************************************************************************/ static void aggregate_get_items(zbx_vector_uint64_t *itemids, const char *groups, const char *itemkey) { const char *__function_name = "aggregate_get_items"; char *group, *esc; DB_RESULT result; DB_ROW row; zbx_uint64_t itemid; char *sql = NULL; size_t sql_alloc = ZBX_KIBIBYTE, sql_offset = 0; int num, n; zabbix_log(LOG_LEVEL_DEBUG, "In %s() groups:'%s' itemkey:'%s'", __function_name, groups, itemkey); sql = zbx_malloc(sql, sql_alloc); esc = DBdyn_escape_string(itemkey); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "select distinct i.itemid" " from items i,hosts h,hosts_groups hg,groups g" " where i.hostid=h.hostid" " and h.hostid=hg.hostid" " and hg.groupid=g.groupid" " and i.key_='%s'" " and i.status=%d" " and h.status=%d", esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED); zbx_free(esc); num = num_param(groups); zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in ("); for (n = 1; n <= num; n++) { if (NULL == (group = get_param_dyn(groups, n))) continue; esc = DBdyn_escape_string(group); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc); if (n != num) zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ','); zbx_free(esc); zbx_free(group); } zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); zbx_free(sql); while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(itemid, row[0]); zbx_vector_uint64_append(itemids, itemid); } DBfree_result(result); zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: execute_operations * * * * Purpose: execute all operations linked to the action * * * * Parameters: action - action to execute operations for * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static void execute_operations(DB_EVENT *event, zbx_uint64_t actionid) { const char *__function_name = "execute_operations"; DB_RESULT result; DB_ROW row; unsigned char operationtype; zbx_uint64_t groupid, templateid; zbx_vector_uint64_t lnk_templateids, del_templateids, new_groupids, del_groupids; zabbix_log(LOG_LEVEL_DEBUG, "In %s() actionid:" ZBX_FS_UI64, __function_name, actionid); zbx_vector_uint64_create(&lnk_templateids); zbx_vector_uint64_create(&del_templateids); zbx_vector_uint64_create(&new_groupids); zbx_vector_uint64_create(&del_groupids); result = DBselect( "select o.operationtype,g.groupid,t.templateid" " from operations o" " left join opgroup g on g.operationid=o.operationid" " left join optemplate t on t.operationid=o.operationid" " where o.actionid=" ZBX_FS_UI64, actionid); while (NULL != (row = DBfetch(result))) { operationtype = (unsigned char)atoi(row[0]); ZBX_DBROW2UINT64(groupid, row[1]); ZBX_DBROW2UINT64(templateid, row[2]); switch (operationtype) { case OPERATION_TYPE_HOST_ADD: op_host_add(event); break; case OPERATION_TYPE_HOST_REMOVE: op_host_del(event); break; case OPERATION_TYPE_HOST_ENABLE: op_host_enable(event); break; case OPERATION_TYPE_HOST_DISABLE: op_host_disable(event); break; case OPERATION_TYPE_GROUP_ADD: if (0 != groupid) zbx_vector_uint64_append(&new_groupids, groupid); break; case OPERATION_TYPE_GROUP_REMOVE: if (0 != groupid) zbx_vector_uint64_append(&del_groupids, groupid); break; case OPERATION_TYPE_TEMPLATE_ADD: if (0 != templateid) zbx_vector_uint64_append(&lnk_templateids, templateid); break; case OPERATION_TYPE_TEMPLATE_REMOVE: if (0 != templateid) zbx_vector_uint64_append(&del_templateids, templateid); break; default: ; } } DBfree_result(result); if (0 != lnk_templateids.values_num) { zbx_vector_uint64_sort(&lnk_templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); op_template_add(event, &lnk_templateids); } if (0 != del_templateids.values_num) { zbx_vector_uint64_sort(&del_templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); op_template_del(event, &del_templateids); } if (0 != new_groupids.values_num) { zbx_vector_uint64_sort(&new_groupids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); op_groups_add(event, &new_groupids); } if (0 != del_groupids.values_num) { zbx_vector_uint64_sort(&del_groupids, ZBX_DEFAULT_UINT64_COMPARE_FUNC); op_groups_del(event, &del_groupids); } zbx_vector_uint64_destroy(&del_groupids); zbx_vector_uint64_destroy(&new_groupids); zbx_vector_uint64_destroy(&del_templateids); zbx_vector_uint64_destroy(&lnk_templateids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }