/****************************************************************************** * * * Function: process_time_functions * * * * Purpose: re-calculate and update values of time-driven functions * * * * Author: Alexei Vladishev, Aleksandrs Saveljevs * * * ******************************************************************************/ static void process_time_functions(int *triggers_count, int *events_count) { const char *__function_name = "process_time_functions"; DC_TRIGGER *trigger_info = NULL; zbx_vector_ptr_t trigger_order; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_vector_ptr_create(&trigger_order); DCconfig_get_time_based_triggers(&trigger_info, &trigger_order, process_num, triggers_count); if (0 == trigger_order.values_num) goto clean; evaluate_expressions(&trigger_order); DBbegin(); process_triggers(&trigger_order); DCfree_triggers(&trigger_order); *events_count = process_events(); DBcommit(); clean: zbx_free(trigger_info); zbx_vector_ptr_destroy(&trigger_order); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_check * * * * Purpose: check if service is available and update database * * * * Parameters: service - service info * * * * Return value: * * * * Author: Eugene Grigorjev * * * * Comments: * * * ******************************************************************************/ static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, int *host_status, char *ip) { const char *__function_name = "process_check"; int port, first, last, now; char *curr_range, *next_range, *last_port; int status; char value[DSERVICE_VALUE_LEN_MAX]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); for (curr_range = dcheck->ports; curr_range; curr_range = next_range) { /* split by ',' */ if (NULL != (next_range = strchr(curr_range, ','))) *next_range = '\0'; if (NULL != (last_port = strchr(curr_range, '-'))) { /* split by '-' */ *last_port = '\0'; first = atoi(curr_range); last = atoi(last_port + 1); *last_port = '-'; } else first = last = atoi(curr_range); if (NULL != next_range) { *next_range = ','; next_range++; } for (port = first; port <= last; port++) { zabbix_log(LOG_LEVEL_DEBUG, "%s() port:%d", __function_name, port); status = (SUCCEED == discover_service(dcheck, ip, port, value)) ? DOBJECT_STATUS_UP : DOBJECT_STATUS_DOWN; /* Update host status */ if (*host_status == -1 || status == DOBJECT_STATUS_UP) *host_status = status; now = time(NULL); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) { discovery_update_service(drule, dcheck, dhost, ip, port, status, value, now); } else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) { proxy_update_service(drule, dcheck, ip, port, status, value, now); } DBcommit(); } } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/************************************************************************************ * * * Function: sql_writer_flush * * * * Purpose: flushes bulk insert data into database * * * ************************************************************************************/ static int sql_writer_flush(void) { int i, txn_error; /* The writer might be uninitialized only if the history */ /* was already flushed. In that case, return SUCCEED */ if (0 == writer.initialized) return SUCCEED; do { DBbegin(); for (i = 0; i < writer.dbinserts.values_num; i++) { zbx_db_insert_t *db_insert = (zbx_db_insert_t *)writer.dbinserts.values[i]; zbx_db_insert_execute(db_insert); } } while (ZBX_DB_DOWN == (txn_error = DBcommit())); sql_writer_release(); return ZBX_DB_OK == txn_error ? SUCCEED : FAIL; }
/****************************************************************************** * * * Function: tm_remove_old_tasks * * * * Purpose: remove old done/expired tasks * * * ******************************************************************************/ static void tm_remove_old_tasks(int now) { DBbegin(); DBexecute("delete from task where status in (%d,%d) and clock<=%d", ZBX_TM_STATUS_DONE, ZBX_TM_STATUS_EXPIRED, now - ZBX_TM_CLEANUP_TASK_AGE); DBcommit(); }
/****************************************************************************** * * * Function: process_check * * * * Purpose: check if service is available and update database * * * * Parameters: service - service info * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ static void process_check(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, int *host_status, char *ip, const char *dns) { const char *__function_name = "process_check"; int port, first, last, now; char *start, *comma, *last_port; int status; char value[DSERVICE_VALUE_LEN_MAX]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); for (start = dcheck->ports; '\0' != *start;) { if (NULL != (comma = strchr(start, ','))) *comma = '\0'; if (NULL != (last_port = strchr(start, '-'))) { *last_port = '\0'; first = atoi(start); last = atoi(last_port + 1); *last_port = '-'; } else first = last = atoi(start); for (port = first; port <= last; port++) { zabbix_log(LOG_LEVEL_DEBUG, "%s() port:%d", __function_name, port); status = (SUCCEED == discover_service(dcheck, ip, port, value)) ? DOBJECT_STATUS_UP : DOBJECT_STATUS_DOWN; /* update host status */ if (-1 == *host_status || DOBJECT_STATUS_UP == status) *host_status = status; now = time(NULL); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) discovery_update_service(drule, dcheck, dhost, ip, dns, port, status, value, now); else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) proxy_update_service(drule, dcheck, ip, dns, port, status, value, now); DBcommit(); } if (NULL != comma) { *comma = ','; start = comma + 1; } else break; } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: main_timer_loop * * * * Purpose: periodically updates time-related triggers * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: does update once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_timer_loop() { int now, cur; /* int itemid,functionid; char *function; char *parameter;*/ DB_ITEM item; DB_RESULT result; DB_ROW row; for(;;) { zbx_setproctitle("Timer: updating nodata() functions"); DBconnect(ZBX_DB_CONNECT_NORMAL); now=time(NULL); /* #ifdef HAVE_POSTGRESQL zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter::text::integer<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #else zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter,f.function from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #endif */ result = DBselect("select %s, functions f where h.hostid=i.hostid and h.status=%d and i.status=%d and f.function in ('nodata','date','dayofweek','time','now','count') and i.itemid=f.itemid and " ZBX_COND_SITE, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, getSiteCondition ()); cur = 1; while((row=DBfetch(result))) { #ifdef HAVE_MYSQL zbx_setproctitle("Timer: processing %d item of %d", cur++, result->row_count); #endif DBget_item_from_db(&item,row); DBbegin(); update_functions(&item); update_triggers(item.itemid); DBcommit(); DBfree_item(&item); } DBfree_result(result); DBclose(); zbx_setproctitle("Timer: sleeping for 10 sec"); sleep(10); } }
/****************************************************************************** * * * Function: main_nodewatcher_loop * * * * Purpose: periodically calculates checks sum of config data * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ int main_nodewatcher_loop() { int start, end; int lastrun = 0; zabbix_log( LOG_LEVEL_DEBUG, "In main_nodeupdater_loop()"); for(;;) { start = time(NULL); zbx_setproctitle("connecting to the database"); zabbix_log( LOG_LEVEL_DEBUG, "Starting sync with nodes"); DBconnect(ZBX_DB_CONNECT_NORMAL); #if 0 if(lastrun + 120 < start) { DBbegin(); calculate_checksums(); compare_checksums(); update_checksums(); /* Send configuration changes to required nodes */ main_nodesender(); DBcommit(); lastrun = start; } #endif /* Send new events to master node */ main_eventsender(); /* Send new history data to master node */ main_historysender(); DBclose(); end = time(NULL); if(end-start<10) { zbx_setproctitle("sender [sleeping for %d seconds]", 10-(end-start)); zabbix_log( LOG_LEVEL_DEBUG, "Sleeping %d seconds", 10-(end-start)); sleep(10-(end-start)); } } }
/****************************************************************************** * * * Function: history_sender * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static void history_sender(struct zbx_json *j, int *records, const char *tag, int (*f_get_data)(), void (*f_set_lastid)()) { const char *__function_name = "history_sender"; zbx_sock_t sock; zbx_uint64_t lastid; zbx_timespec_t ts; int ret = SUCCEED; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_json_clean(j); zbx_json_addstring(j, ZBX_PROTO_TAG_REQUEST, tag, ZBX_JSON_TYPE_STRING); zbx_json_addstring(j, ZBX_PROTO_TAG_HOST, CONFIG_HOSTNAME, ZBX_JSON_TYPE_STRING); zbx_json_addarray(j, ZBX_PROTO_TAG_DATA); *records = f_get_data(j, &lastid); zbx_json_close(j); if (*records > 0) { char *error = NULL; connect_to_server(&sock, 600, CONFIG_PROXYDATA_FREQUENCY); /* retry till have a connection */ zbx_timespec(&ts); zbx_json_adduint64(j, ZBX_PROTO_TAG_CLOCK, ts.sec); zbx_json_adduint64(j, ZBX_PROTO_TAG_NS, ts.ns); if (SUCCEED != (ret = put_data_to_server(&sock, j, &error))) { *records = 0; zabbix_log(LOG_LEVEL_WARNING, "sending data to server failed: %s", error); } zbx_free(error); disconnect_server(&sock); } if (SUCCEED == ret && 0 != lastid) { DBbegin(); f_set_lastid(lastid); DBcommit(); } zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
static void process_escalations(int now) { DB_RESULT result; DB_ROW row; DB_ESCALATION escalation; zabbix_log(LOG_LEVEL_DEBUG, "In process_escalations()"); result = DBselect("select escalationid,actionid,triggerid,eventid,r_eventid,esc_step,status" " from escalations where status in (%d,%d) and nextcheck<=%d" DB_NODE, ESCALATION_STATUS_ACTIVE, ESCALATION_STATUS_RECOVERY, now, DBnode_local("escalationid")); while (NULL != (row = DBfetch(result))) { memset(&escalation, 0, sizeof(escalation)); ZBX_STR2UINT64(escalation.escalationid, row[0]); ZBX_STR2UINT64(escalation.actionid, row[1]); ZBX_STR2UINT64(escalation.triggerid, row[2]); ZBX_STR2UINT64(escalation.eventid, row[3]); ZBX_STR2UINT64(escalation.r_eventid, row[4]); escalation.esc_step = atoi(row[5]); escalation.status = atoi(row[6]); escalation.nextcheck = 0; DBbegin(); execute_escalation(&escalation); if (escalation.status == ESCALATION_STATUS_COMPLETED) DBremove_escalation(escalation.escalationid); else DBexecute("update escalations set status=%d,esc_step=%d,nextcheck=%d" " where escalationid=" ZBX_FS_UI64, escalation.status, escalation.esc_step, escalation.nextcheck, escalation.escalationid); DBcommit(); } DBfree_result(result); }
/****************************************************************************** * * * Function: node_events * * * * Purpose: process new events received from a salve node * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int node_events(char *data) { char *s; int firstline=1; int nodeid=0; int sender_nodeid=0; char tmp[MAX_STRING_LEN]; int datalen; datalen = strlen(data); zabbix_log( LOG_LEVEL_DEBUG, "In node_events(len:%d)", datalen); DBbegin(); s=(char *)strtok(data,"\n"); while(s!=NULL) { if(firstline == 1) { /* zabbix_log( LOG_LEVEL_WARNING, "First line [%s]", s); */ zbx_get_field(s,tmp,1,ZBX_DM_DELIMITER); sender_nodeid=atoi(tmp); zbx_get_field(s,tmp,2,ZBX_DM_DELIMITER); nodeid=atoi(tmp); firstline=0; zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Received events from node %d for node %d datalen %d", CONFIG_NODEID, sender_nodeid, nodeid, datalen); } else { /* zabbix_log( LOG_LEVEL_WARNING, "Got line [%s]", s); */ process_record(nodeid, s); } s=(char *)strtok(NULL,"\n"); } DBcommit(); return SUCCEED; }
static void DBget_lastsize() { DB_RESULT result; DB_ROW row; DBbegin(); result = DBselect("select snmp_lastsize from globalvars"); if (NULL == (row = DBfetch(result))) { DBexecute("insert into globalvars (globalvarid,snmp_lastsize) values (1,0)"); trap_lastsize = 0; } else trap_lastsize = atoi(row[0]); DBfree_result(result); DBcommit(); }
/****************************************************************************** * * * Function: db_update_host_maintenances * * * * Purpose: update host maintenance parameters in cache and database * * * ******************************************************************************/ static int update_host_maintenances(void) { zbx_vector_uint64_t maintenanceids; zbx_vector_ptr_t updates; int hosts_num = 0; int tnx_error; zbx_vector_uint64_create(&maintenanceids); zbx_vector_ptr_create(&updates); zbx_vector_ptr_reserve(&updates, 100); do { DBbegin(); if (SUCCEED == zbx_dc_get_running_maintenanceids(&maintenanceids)) zbx_db_lock_maintenanceids(&maintenanceids); /* host maintenance update must be called even with no maintenances running */ /* to reset host maintenance status if necessary */ zbx_dc_get_host_maintenance_updates(&maintenanceids, &updates); if (0 != updates.values_num) db_update_host_maintenances(&updates); if (ZBX_DB_OK == (tnx_error = DBcommit()) && 0 != (hosts_num = updates.values_num)) zbx_dc_flush_host_maintenance_updates(&updates); zbx_vector_ptr_clear_ext(&updates, (zbx_clean_func_t)zbx_ptr_free); zbx_vector_uint64_clear(&maintenanceids); } while (ZBX_DB_DOWN == tnx_error); zbx_vector_ptr_destroy(&updates); zbx_vector_uint64_destroy(&maintenanceids); return hosts_num; }
static void 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: node_history * * * * Purpose: process new history received from a slave node * * * * Parameters: * * * * Return value: SUCCEED - processed successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int node_history(char *data, size_t datalen) { const char *r; char *newline = NULL; char *pos; int sender_nodeid = 0, nodeid = 0, firstline = 1, events = 0, history = 0, acknowledges = 0; const ZBX_TABLE *table_sync = NULL, *table = NULL; int res = SUCCEED; char *sql1 = NULL, *sql2 = NULL, *sql3 = NULL; size_t sql1_alloc, sql2_alloc, sql3_alloc; size_t sql1_offset, sql2_offset, sql3_offset; zbx_vector_uint64_t ack_eventids; assert(data); zabbix_log(LOG_LEVEL_DEBUG, "In node_history()"); buffer_alloc = 4 * ZBX_KIBIBYTE; sql1_alloc = 32 * ZBX_KIBIBYTE; sql2_alloc = 32 * ZBX_KIBIBYTE; sql3_alloc = 32 * ZBX_KIBIBYTE; tmp_alloc = 4 * ZBX_KIBIBYTE; buffer = zbx_malloc(buffer, buffer_alloc); sql1 = zbx_malloc(sql1, sql1_alloc); sql2 = zbx_malloc(sql2, sql2_alloc); sql3 = zbx_malloc(sql3, sql3_alloc); tmp = zbx_malloc(tmp, tmp_alloc); zbx_vector_uint64_create(&ack_eventids); DBbegin(); for (r = data; *r != '\0' && res == SUCCEED;) { if (NULL != (newline = strchr(r, '\n'))) *newline = '\0'; if (1 == firstline) { zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* constant 'History' */ zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* sender_nodeid */ sender_nodeid=atoi(buffer); zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* nodeid */ nodeid=atoi(buffer); zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* tablename */ if (FAIL == is_direct_slave_node(sender_nodeid)) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received data from node %d" " that is not a direct slave node", CONFIG_NODEID, sender_nodeid); res = FAIL; } if (FAIL == is_slave_node(CONFIG_NODEID, nodeid)) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received history for unknown slave node %d", CONFIG_NODEID, nodeid); res = FAIL; } table = DBget_table(buffer); if (NULL != table && 0 == (table->flags & (ZBX_HISTORY | ZBX_HISTORY_SYNC))) table = NULL; if (NULL != table && 0 != (table->flags & ZBX_HISTORY_SYNC)) { table_sync = table; if (NULL != (pos = strstr(buffer, "_sync"))) { *pos = '\0'; table = DBget_table(buffer); } } if (NULL == table) { zabbix_log(LOG_LEVEL_ERR, "NODE %d: Invalid received data: unknown tablename \"%s\"", CONFIG_NODEID, buffer); res = FAIL; } else { if (0 == strcmp(table->table, "events")) events = 1; if (0 == strncmp(table->table, "history", 7)) history = 1; if (0 == strcmp(table->table, "acknowledges")) acknowledges = 1; } if (NULL != newline) { zabbix_log(LOG_LEVEL_WARNING, "NODE %d: Received %s from node %d for node %d datalen " ZBX_FS_SIZE_T, CONFIG_NODEID, buffer, sender_nodeid, nodeid, (zbx_fs_size_t)datalen); } firstline = 0; sql1_offset = 0; sql2_offset = 0; sql3_offset = 0; } else if (NULL != table) { if (events) { res = process_record_event(sender_nodeid, nodeid, table, r); } else { res = process_record(&sql1, &sql1_alloc, &sql1_offset, sender_nodeid, nodeid, table, r, newline ? 0 : 1, acknowledges, &ack_eventids); if (SUCCEED == res && 0 != history) { res = process_items(&sql2, &sql2_alloc, &sql2_offset, sender_nodeid, nodeid, table, r, newline ? 0 : 1); } if (SUCCEED == res && NULL != table_sync && 0 != CONFIG_MASTER_NODEID) { res = process_record(&sql3, &sql3_alloc, &sql3_offset, sender_nodeid, nodeid, table_sync, r, newline ? 0 : 1, 0, NULL); } } } if (newline != NULL) { *newline = '\n'; r = newline + 1; } else break; } if (SUCCEED == res) DBcommit(); else DBrollback(); zbx_vector_uint64_destroy(&ack_eventids); zbx_free(tmp); zbx_free(sql1); zbx_free(sql2); zbx_free(sql3); zbx_free(buffer); return res; }
/****************************************************************************** * * * Function: get_values * * * * Purpose: retrieve values of metrics from monitored hosts * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: always SUCCEED * * * ******************************************************************************/ static int get_values(int now, int *nextcheck) { DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; int delay; int res; DB_ITEM item; AGENT_RESULT agent; int stop = 0, items = 0; static char *unreachable_hosts = NULL; static int unreachable_hosts_alloc = 32; int unreachable_hosts_offset = 0; char istatus[16]; zabbix_log( LOG_LEVEL_DEBUG, "In get_values()"); if (0 != CONFIG_DBSYNCER_FORKS) DCinit_nextchecks(); now = time(NULL); *nextcheck = FAIL; if (NULL == unreachable_hosts) unreachable_hosts = zbx_malloc(unreachable_hosts, unreachable_hosts_alloc); *unreachable_hosts = '\0'; if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf(istatus, sizeof(istatus), "%d,%d", ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); else zbx_snprintf(istatus, sizeof(istatus), "%d", ITEM_STATUS_ACTIVE); switch (poller_type) { case ZBX_POLLER_TYPE_UNREACHABLE: result = DBselect("select h.hostid,min(i.itemid) from hosts h,items i" " where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)" " and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from!=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " group by h.hostid", CONFIG_UNREACHABLE_POLLER_FORKS, poller_num-1, now + POLLER_DELAY, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; case ZBX_POLLER_TYPE_IPMI: result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)" " and i.type in (%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, istatus, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, ITEM_TYPE_INTERNAL, CONFIG_IPMIPOLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; default: /* ZBX_POLLER_TYPE_NORMAL */ result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)" " and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))" " and (h.proxy_hostid=0 or i.type in (%d))" " and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, HOST_STATUS_MONITORED, istatus, now, ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR, ITEM_TYPE_INTERNAL, CONFIG_POLLER_FORKS, poller_num-1, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); } /* Do not stop when select is made by poller for unreachable hosts */ while((row=DBfetch(result))&&(stop==0 || poller_type == ZBX_POLLER_TYPE_UNREACHABLE)) { /* This code is just to avoid compilation warining about use of uninitialized result2 */ result2 = result; /* */ /* Poller for unreachable hosts */ if(poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { result2 = DBselect("select %s where h.hostid=i.hostid and h.proxy_hostid=0 and i.itemid=%s" DB_NODE, ZBX_SQL_ITEM_SELECT, row[1], DBnode_local("h.hostid")); row2 = DBfetch(result2); if(!row2) { DBfree_result(result2); continue; } DBget_item_from_db(&item,row2); } else { DBget_item_from_db(&item,row); /* Skip unreachable hosts but do not break the loop. */ if(uint64_in_list(unreachable_hosts,item.hostid) == SUCCEED) { zabbix_log( LOG_LEVEL_DEBUG, "Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]", item.hostid,item.key); continue; } } if (item.nextcheck > time(NULL)) { if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) DBfree_result(result2); continue; } init_result(&agent); res = get_value(&item, &agent); now = time(NULL); if (res == SUCCEED) { if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } if (item.host_errors_from != 0) { DBbegin(); DBexecute("update hosts set errors_from=0 where hostid=" ZBX_FS_UI64, item.hostid); stop = 1; DBcommit(); } if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, now); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, now); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (0 != CONFIG_DBSYNCER_FORKS) DCadd_nextcheck(&item, now, 0, NULL); if (poller_type == ZBX_POLLER_TYPE_NORMAL || poller_type == ZBX_POLLER_TYPE_IPMI) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; } else if (res == NOTSUPPORTED || res == AGENT_ERROR) { if (item.status != ITEM_STATUS_NOTSUPPORTED) { zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] is not supported by agent on host [%s] Old status [%d]", item.key, item.host_name, item.status); zabbix_syslog("Parameter [%s] is not supported by agent on host [%s]", item.key, item.host_name); } if (0 == CONFIG_DBSYNCER_FORKS) { DBbegin(); DBupdate_item_status_to_notsupported(&item, now, agent.msg); DBcommit(); } else DCadd_nextcheck(&item, now, 0, agent.msg); if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck)) *nextcheck = item.nextcheck; if (HOST_AVAILABLE_TRUE != item.host_available) { DBbegin(); enable_host(&item, now); stop = 1; DBcommit(); } } else if (res == NETWORK_ERROR) { DBbegin(); /* First error */ if (item.host_errors_from == 0) { zabbix_log( LOG_LEVEL_WARNING, "Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: first network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set errors_from=%d,disable_until=%d where hostid=" ZBX_FS_UI64, now, now + CONFIG_UNREACHABLE_DELAY, item.hostid); item.host_errors_from = now; delay = MIN(4*item.delay, 300); zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] will be checked after %d seconds on host [%s]", item.key, delay, item.host_name); DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64, now + delay, item.itemid); } else { if (now - item.host_errors_from > CONFIG_UNREACHABLE_PERIOD) { disable_host(&item, now, agent.msg); } else { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zabbix_log(LOG_LEVEL_WARNING, "Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); zabbix_syslog("Host [%s]: another network error, wait for %d seconds", item.host_name, CONFIG_UNREACHABLE_DELAY); DBexecute("update hosts set disable_until=%d where hostid=" ZBX_FS_UI64, now + CONFIG_UNREACHABLE_DELAY, item.hostid); } } DBcommit(); zbx_snprintf_alloc(&unreachable_hosts, &unreachable_hosts_alloc, &unreachable_hosts_offset, 32, "%s" ZBX_FS_UI64, 0 == unreachable_hosts_offset ? "" : ",", item.hostid); } else { zabbix_log(LOG_LEVEL_CRIT, "Unknown response code returned."); assert(0==1); } items++; /* Poller for unreachable hosts */ if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE) { /* We cannot freeit earlier because items has references to the structure */ DBfree_result(result2); } free_result(&agent); } DBfree_result(result); if (0 != CONFIG_DBSYNCER_FORKS) DCflush_nextchecks(); zabbix_log(LOG_LEVEL_DEBUG, "End get_values()"); return items; }
/****************************************************************************** * * * Function : process_hstory_table_data: * * * * Purpose: process new history data * * * * Parameters: * * * * Return value: * * * * Author: Aleksander Vladishev * * * * Comments: * * * ******************************************************************************/ void process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid) { DB_RESULT result; DB_ROW row; char *data = NULL, *tmp = NULL; int data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len; int data_found = 0; zbx_uint64_t lastid; int lastclock = 0, clock; zabbix_log( LOG_LEVEL_DEBUG, "In process_history_table_data()"); DBbegin(); if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid)) return; if ((table->flags & ZBX_HISTORY_TRENDS) && FAIL == get_trends_lastid(master_nodeid, nodeid, table, &lastid, &lastclock)) return; data = zbx_malloc(data, data_allocated); tmp = zbx_malloc(tmp, tmp_allocated); data_offset = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s", ZBX_DM_DELIMITER, CONFIG_NODEID, ZBX_DM_DELIMITER, nodeid, ZBX_DM_DELIMITER, table->table); /* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */ /* if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid)) goto exit;*/ tmp_offset = 0; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,", table->recid); } else { /* ZBX_HISTORY, ZBX_HISTORY_TRENDS */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select "); } for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,", table->fields[f].name); } tmp_offset--; if (table->flags & ZBX_HISTORY_SYNC) { zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s", table->table, nodeid, table->recid); } else if (table->flags & ZBX_HISTORY_TRENDS) { clock = time(NULL) - 600; /* -10min */ clock -= clock % 3600; zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where" " (itemid>"ZBX_FS_UI64" or (itemid="ZBX_FS_UI64" and clock>%d)) and clock<%d" DB_NODE " order by itemid,clock", table->table, lastid, lastid, lastclock, clock, DBnode("itemid", nodeid)); } else { /* ZBX_HISTORY */ zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64 DB_NODE " order by %s", table->table, table->recid, lastid, DBnode(table->recid, nodeid), table->recid); } result = DBselectN(tmp, 10000); while (NULL != (row = DBfetch(result))) { if (table->flags & ZBX_HISTORY_SYNC) { ZBX_STR2UINT64(lastid, row[0]); fld = 1; } else fld = 0; zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n"); for (f = 0; table->fields[f].name != 0; f++) { if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC)) continue; if (table->fields[f].type == ZBX_TYPE_INT || table->fields[f].type == ZBX_TYPE_UINT || table->fields[f].type == ZBX_TYPE_ID || table->fields[f].type == ZBX_TYPE_FLOAT) { zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s%c", row[fld], ZBX_DM_DELIMITER); } else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */ len = (int)strlen(row[fld]); len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated); zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c", tmp, ZBX_DM_DELIMITER); } fld++; } data_offset--; data_found = 1; } DBfree_result(result); data[data_offset] = '\0'; if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) { if (table->flags & ZBX_HISTORY_SYNC) { DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64, table->table, nodeid, table->recid, lastid); } } DBcommit(); zbx_free(tmp); zbx_free(data); }
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); }
/****************************************************************************** * * * Function: tm_execute_remote_command * * * * Purpose: execute remote command task * * * * Parameters: taskid - [IN] the task identifier * * clock - [IN] the task creation time * * ttl - [IN] the task expiration period in seconds * * now - [IN] the current time * * * * Return value: SUCCEED - the remote command was executed * * FAIL - otherwise * * * ******************************************************************************/ static int tm_execute_remote_command(zbx_uint64_t taskid, int clock, int ttl, int now) { DB_ROW row; DB_RESULT result; zbx_uint64_t parent_taskid, hostid; zbx_tm_task_t *task = NULL; int ret = FAIL; zbx_script_t script; char *info = NULL, error[MAX_STRING_LEN]; DC_HOST host; result = DBselect("select command_type,execute_on,port,authtype,username,password,publickey,privatekey," "command,parent_taskid,hostid" " from task_remote_command" " where taskid=" ZBX_FS_UI64, taskid); if (NULL == (row = DBfetch(result))) goto finish; task = zbx_tm_task_create(0, ZBX_TM_TASK_REMOTE_COMMAND_RESULT, ZBX_TM_STATUS_NEW, time(NULL), 0, 0); ZBX_STR2UINT64(parent_taskid, row[9]); if (0 != ttl && clock + ttl < now) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "The remote command has been expired."); goto finish; } ZBX_STR2UINT64(hostid, row[10]); if (FAIL == DCget_host_by_hostid(&host, hostid)) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "Unknown host."); goto finish; } zbx_script_init(&script); ZBX_STR2UCHAR(script.type, row[0]); ZBX_STR2UCHAR(script.execute_on, row[1]); script.port = (0 == atoi(row[2]) ? (char *)"" : row[2]); ZBX_STR2UCHAR(script.authtype, row[3]); script.username = row[4]; script.password = row[5]; script.publickey = row[6]; script.privatekey = row[7]; script.command = row[8]; if (ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT == script.type && ZBX_SCRIPT_EXECUTE_ON_PROXY == script.execute_on) { if (0 == CONFIG_ENABLE_REMOTE_COMMANDS) { task->data = zbx_tm_remote_command_result_create(parent_taskid, FAIL, "Remote commands are not enabled"); goto finish; } if (1 == CONFIG_LOG_REMOTE_COMMANDS) zabbix_log(LOG_LEVEL_WARNING, "Executing command '%s'", script.command); else zabbix_log(LOG_LEVEL_DEBUG, "Executing command '%s'", script.command); } if (SUCCEED != (ret = zbx_script_execute(&script, &host, &info, error, sizeof(error)))) task->data = zbx_tm_remote_command_result_create(parent_taskid, ret, error); else task->data = zbx_tm_remote_command_result_create(parent_taskid, ret, info); zbx_free(info); finish: DBfree_result(result); DBbegin(); if (NULL != task) { zbx_tm_save_task(task); zbx_tm_task_free(task); } DBexecute("update task set status=%d where taskid=" ZBX_FS_UI64, ZBX_TM_STATUS_DONE, taskid); DBcommit(); return ret; }
/****************************************************************************** * * * Function: get_hostid_by_host * * * * Purpose: check for host name and return hostid * * * * Parameters: host - [IN] require size 'HOST_HOST_LEN_MAX' * * * * Return value: SUCCEED - host is found * * FAIL - an error occurred or host not found * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ static int get_hostid_by_host(const char *host, const char *ip, unsigned short port, zbx_uint64_t *hostid, char *error) { const char *__function_name = "get_hostid_by_host"; char *host_esc, dns[INTERFACE_DNS_LEN_MAX]; DB_RESULT result; DB_ROW row; int res = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() host:'%s'", __function_name, host); if (FAIL == zbx_check_hostname(host)) { zbx_snprintf(error, MAX_STRING_LEN, "invalid host name [%s]", host); goto out; } host_esc = DBdyn_escape_string(host); result = DBselect( "select hostid,status" " from hosts" " where host='%s'" " and status in (%d,%d)" " and proxy_hostid is null" DB_NODE, host_esc, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, DBnode_local("hostid")); if (NULL != (row = DBfetch(result))) { if (HOST_STATUS_MONITORED == atoi(row[1])) { ZBX_STR2UINT64(*hostid, row[0]); res = SUCCEED; } else zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not monitored", host); } else { zbx_snprintf(error, MAX_STRING_LEN, "host [%s] not found", host); /* remove ::ffff: prefix from IPv4-mapped IPv6 addresses */ if (0 == strncmp("::ffff:", ip, 7) && SUCCEED == is_ip4(ip + 7)) ip += 7; alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, dns, sizeof(dns)); alarm(0); DBbegin(); if (0 != (daemon_type & ZBX_DAEMON_TYPE_SERVER)) { DBregister_host(0, host, ip, dns, port, (int)time(NULL)); } else if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY)) { DBproxy_register_host(host, ip, dns, port); } DBcommit(); } DBfree_result(result); zbx_free(host_esc); out: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(res)); return res; }
/****************************************************************************** * * * Function: process_data * * * * Purpose: process new item value * * * * Parameters: sockfd - descriptor of agent-server socket connection * * server - server name * * key - item's key * * value - new value of server:key * * lastlogsize - if key=log[*], last size of log file * * * * Return value: SUCCEED - new value processed sucesfully * * FAIL - otherwise * * * * Author: Alexei Vladishev * * * * Comments: for trapper server process * * * ******************************************************************************/ static void process_mass_data(zbx_sock_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALUE *values, int value_num, int *processed, time_t proxy_timediff) { AGENT_RESULT agent; DB_RESULT result; DB_ROW row; DB_ITEM item; char host_esc[MAX_STRING_LEN], key_esc[MAX_STRING_LEN]; static char *sql = NULL; static int sql_allocated = 65536; int sql_offset = 0, i; zabbix_log(LOG_LEVEL_DEBUG, "In process_mass_data()"); if (NULL == sql) sql = zbx_malloc(sql, sql_allocated); DCinit_nextchecks(); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 2048, "select %s where h.hostid=i.hostid and h.proxy_hostid=" ZBX_FS_UI64 " and h.status=%d and i.status in (%d,%d)", ZBX_SQL_ITEM_SELECT, proxy_hostid, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED); if (proxy_hostid == 0) { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d)", ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE); } else { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64, " and i.type in (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)", ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_TRAPPER, ITEM_TYPE_SIMPLE, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_ZABBIX_ACTIVE, ITEM_TYPE_HTTPTEST, ITEM_TYPE_EXTERNAL, ITEM_TYPE_IPMI); } zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, " and ("); for (i = 0; i < value_num; i++) { DBescape_string(values[i].host_name, host_esc, sizeof(host_esc)); DBescape_string(values[i].key, key_esc, sizeof(key_esc)); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 512, "(h.host='%s' and i.key_='%s') or ", host_esc, key_esc); } sql_offset -= 4; zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, ")" DB_NODE, DBnode_local("h.hostid")); result = DBselect("%s", sql); while (NULL != (row = DBfetch(result))) { DBget_item_from_db(&item, row); if (item.type == ITEM_TYPE_ZABBIX_ACTIVE && FAIL == zbx_tcp_check_security(sock, item.trapper_hosts, 1)) continue; if (item.maintenance_status == HOST_MAINTENANCE_STATUS_ON && item.maintenance_type == MAINTENANCE_TYPE_NODATA && item.maintenance_from <= values[i].clock) continue; for (i = 0; i < value_num; i++) { if (0 == strcmp(item.host_name, values[i].host_name) && 0 == strcmp(item.key_orig, values[i].key)) { /* zabbix_log(LOG_LEVEL_DEBUG, "Processing [%s@%s: \"%s\"]", item.key, item.host_name, values[i].value);*/ if (0 == strcmp(values[i].value, "ZBX_NOTSUPPORTED")) { zabbix_log(LOG_LEVEL_WARNING, "Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); zabbix_syslog("Active parameter [%s] is not supported by agent on host [%s]", item.key_orig, item.host_name); DCadd_nextcheck(&item, values[i].clock, proxy_timediff, "Not supported by ZABBIX agent"); if (NULL != processed) (*processed)++; } else { if (0 == strncmp(item.key, "log[", 4) || 0 == strncmp(item.key, "eventlog[", 9)) { item.lastlogsize = values[i].lastlogsize; item.timestamp = values[i].timestamp; calc_timestamp(values[i].value, &item.timestamp, item.logtimefmt); item.eventlog_severity = values[i].severity; item.eventlog_source = values[i].source; /* zabbix_log(LOG_LEVEL_DEBUG, "Value [%s] Lastlogsize [%s] Timestamp [%s]", values[i].value, item.lastlogsize, item.timestamp);*/ } init_result(&agent); if (SUCCEED == set_result_type(&agent, item.value_type, item.data_type, values[i].value)) { if (0 == CONFIG_DBSYNCER_FORKS) DBbegin(); switch (zbx_process) { case ZBX_PROCESS_SERVER: process_new_value(&item, &agent, values[i].clock); break; case ZBX_PROCESS_PROXY: proxy_process_new_value(&item, &agent, values[i].clock); break; } if (0 == CONFIG_DBSYNCER_FORKS) DBcommit(); if (NULL != processed) (*processed)++; /* only for screen Administration|Queue */ if (item.type != ITEM_TYPE_TRAPPER && item.type != ITEM_TYPE_HTTPTEST && item.value_type != ITEM_VALUE_TYPE_LOG && 0 != strcmp(item.key, SERVER_STATUS_KEY) && 0 != strcmp(item.key, SERVER_ICMPPING_KEY) && 0 != strcmp(item.key, SERVER_ICMPPINGSEC_KEY) && 0 != strcmp(item.key, SERVER_ZABBIXLOG_KEY)) DCadd_nextcheck(&item, values[i].clock, proxy_timediff, NULL); } else { if (GET_MSG_RESULT(&agent)) zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s", zbx_host_key_string_by_item(&item), agent.msg); } free_result(&agent); } } } } DBfree_result(result); DCflush_nextchecks(); }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ char *evaluate_jobnetrun(zbx_sock_t * sock, struct zbx_json_parse *jp, int *ret) { DB_RESULT result; DB_ROW row; struct zbx_json_parse jp_row; struct zbx_json_parse jp_row2; char *message = NULL; char value[MAX_STRING_LEN]; const char *p; const char *p2; const char *p3 = NULL; int version; int res; int i; int count; zbx_uint64_t inner_jobnet_id; static JOBARG_EXEC_REQUEST er; init_exec_request(&er); if (SUCCEED == zbx_json_value_by_name(jp, JA_PROTO_TAG_VERSION, value, sizeof(value))) { version = atoi(value); if (version != JA_PROTO_VALUE_VERSION_1) { ja_log("JATRAPPER200027", 0, NULL, 0, JA_PROTO_VALUE_VERSION_1); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] is not correct."); } } else { ja_log("JATRAPPER200028", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [version] not found"); } if (NULL == (p = zbx_json_pair_by_name(jp, JA_PROTO_TAG_DATA))) { ja_log("JATRAPPER200021", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [data] not found"); } else { if (FAIL == (*ret = zbx_json_brackets_open(p, &jp_row))) { ja_log("JATRAPPER200022", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [data] object"); } else { if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_USERNAME, value, sizeof(value))) { er.username = strdup(value); } else { ja_log("JATRAPPER200032", 0, NULL, 0); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [username] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_PASSWORD, value, sizeof(value))) { er.password = strdup(value); } else { ja_log("JATRAPPER200033", 0, NULL, 0); zbx_free(er.username); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [password] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_JOBNETID, value, sizeof(value))) { er.jobnetid = strdup(value); } else { ja_log("JATRAPPER200034", 0, NULL, 0); zbx_free(er.username); zbx_free(er.password); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [jobnetid] not found"); } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_STARTTIME, value, sizeof(value))) { er.starttime = strdup(value); res = time_passed_check(er.starttime); if (res == FAIL) { zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: [start_time] already passed."); } } i = 0; if (NULL != (p2 = zbx_json_pair_by_name(&jp_row, JA_PROTO_TAG_ENV))) { if (FAIL == (*ret = zbx_json_brackets_open(p2, &jp_row2))) { ja_log("JATRAPPER200051", 0, er.jobnetid, 0); zbx_free(er.username); zbx_free(er.password); zbx_free(er.jobnetid); zbx_free(er.starttime); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Cannot open [env] object"); } else { while (NULL != (p3 = zbx_json_pair_next(&jp_row2, p3, value, sizeof(value)))) { er.env[i] = strdup(value); zbx_json_value_by_name(&jp_row2, er.env[i], value, sizeof(value)); er.value[i] = strdup(value); i++; } er.env[i] = '\0'; } } if (SUCCEED == zbx_json_value_by_name(&jp_row, JA_PROTO_TAG_DETERRENCE, value, sizeof(value))) { er.deterrence = atoi(value); } if (SUCCEED == (job_exec_auth(er))) { DBbegin(); /* double check start-up suppression time specified */ if (er.starttime != NULL && er.deterrence == 1) { result = DBselect("select count(*) from ja_run_jobnet_table" " where scheduled_time = %s and jobnet_id = '%s' and run_type = %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); if (NULL == (row = DBfetch(result))) { zbx_snprintf(msgwork, sizeof(msgwork), "%s %s %d", er.starttime, er.jobnetid, JA_JOBNET_RUN_TYPE_SCHEDULED); ja_log("JATRAPPER200057", 0, er.jobnetid, 0, "ja_run_jobnet_table", msgwork); DBfree_result(result); DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table select error."); } count = atoi(row[0]); DBfree_result(result); if (count > 0) { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Received message error: Double registration detection of time starting jobnet."); } } if (SUCCEED == (register_db_table(er, &inner_jobnet_id, i))) { DBcommit(); clean_exec_request(&er, i); return zbx_dsprintf(message, "Registry number : [" ZBX_FS_UI64 "]", inner_jobnet_id); } else { DBrollback(); clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "ja_run_jobnet_table insert error."); } } else { clean_exec_request(&er, i); *ret = FAIL; return zbx_dsprintf(message, "Authentication failure."); } } } }
/****************************************************************************** * * * 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); }
static void activate_host(DC_ITEM *item, int now) { char sql[MAX_STRING_LEN], error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (0 == *errors_from && HOST_AVAILABLE_TRUE == *available) return; if (SUCCEED != DCconfig_activate_host(item)) return; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); if (HOST_AVAILABLE_TRUE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Enabling %s host [%s]", type, item->host.host); zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); *available = HOST_AVAILABLE_TRUE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_STATUS_MONITORED, now); /* 0 */ } *errors_from = 0; *disable_until = 0; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,%s=%d,%s='' where hostid=" ZBX_FS_UI64, fld_errors_from, *errors_from, fld_disable_until, *disable_until, fld_error, item->host.hostid); DBbegin(); DBexecute("%s", sql); DBcommit(); }
static void DBupdate_lastsize() { DBbegin(); DBexecute("update globalvars set snmp_lastsize=%d", trap_lastsize); DBcommit(); }
/****************************************************************************** * * * Function: update_checksums * * * * Purpose: overwrite old checksums with new ones * * * * Parameters: * * * * Return value: SUCCESS - calculated successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int update_checksums(int nodeid, int synked_nodetype, int synked, const char *tablename, const zbx_uint64_t id, char *fields) { const char *__function_name = "update_checksums"; char *r[2], *d[2], sync[129], *s; char c[2], sql[2][256]; char cksum[32*64+32], *ck; char *exsql = NULL; int exsql_alloc = 65536, exsql_offset = 0, cksumtype; DB_RESULT result; DB_ROW row; int f; const ZBX_TABLE *table; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); exsql = zbx_malloc(exsql, exsql_alloc); DBbegin(); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 8, "begin\n"); #endif c[0] = synked == SUCCEED ? '1' : ' '; /* for new and updated records */ c[1] = synked == SUCCEED ? '2' : ' '; /* for deleted records */ if (NULL != tablename) { zbx_snprintf(sql[0], sizeof(sql[0]), " and curr.tablename='%s' and curr.recordid=" ZBX_FS_UI64, tablename, id); zbx_snprintf(sql[1], sizeof(sql[1]), " and prev.tablename='%s' and prev.recordid=" ZBX_FS_UI64, tablename, id); } else { *sql[0] = '\0'; *sql[1] = '\0'; } /* Find updated records */ result = DBselect("select curr.tablename,curr.recordid,prev.cksum,curr.cksum,prev.sync " "from node_cksum curr, node_cksum prev " "where curr.nodeid=%d and prev.nodeid=curr.nodeid and " "curr.tablename=prev.tablename and curr.recordid=prev.recordid and " "curr.cksumtype=%d and prev.cksumtype=%d%s " "union all " /* Find new records */ "select curr.tablename,curr.recordid,prev.cksum,curr.cksum,NULL " "from node_cksum curr left join node_cksum prev " "on prev.nodeid=curr.nodeid and prev.tablename=curr.tablename and " "prev.recordid=curr.recordid and prev.cksumtype=%d " "where curr.nodeid=%d and curr.cksumtype=%d and prev.tablename is null%s " "union all " /* Find deleted records */ "select prev.tablename,prev.recordid,prev.cksum,curr.cksum,prev.sync " "from node_cksum prev left join node_cksum curr " "on curr.nodeid=prev.nodeid and curr.tablename=prev.tablename and " "curr.recordid=prev.recordid and curr.cksumtype=%d " "where prev.nodeid=%d and prev.cksumtype=%d and curr.tablename is null%s", nodeid, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD, sql[0], NODE_CKSUM_TYPE_OLD, nodeid, NODE_CKSUM_TYPE_NEW, sql[0], NODE_CKSUM_TYPE_NEW, nodeid, NODE_CKSUM_TYPE_OLD, sql[1]); while (NULL != (row = DBfetch(result))) { /* Found table */ if (NULL == (table = DBget_table(row[0]))) { zabbix_log(LOG_LEVEL_WARNING, "Cannot find table [%s]", row[0]); continue; } if (FAIL == DBis_null(row[4])) zbx_strlcpy(sync, row[4], sizeof(sync)); else memset(sync, ' ', sizeof(sync)); s = sync; ck = cksum; *ck = '\0'; /* Special (simpler) processing for operation DELETE */ if (SUCCEED == DBis_null(row[3])) { if (synked == SUCCEED) { if (synked_nodetype == ZBX_NODE_SLAVE) s[0] = c[1]; else if (synked_nodetype == ZBX_NODE_MASTER) s[1] = c[1]; } if ((0 == CONFIG_MASTER_NODEID || s[1] == c[1]) && (CONFIG_NODEID == nodeid || s[0] == c[1])) { zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 256, "delete from node_cksum" " where nodeid=%d" " and cksumtype=%d" " and tablename='%s'" " and recordid=%s;\n", nodeid, NODE_CKSUM_TYPE_OLD, row[0], row[1]); DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset); continue; } s += 2; } else { r[0] = DBis_null(row[2]) == SUCCEED ? NULL : row[2]; r[1] = row[3]; f = 0; do { while ((table->fields[f].flags & ZBX_SYNC) == 0) f++; d[0] = NULL; d[1] = NULL; if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ','))) *d[0] = '\0'; if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ','))) *d[1] = '\0'; if (NULL == tablename || SUCCEED == str_in_list(fields, table->fields[f].name, ',')) { ck += zbx_snprintf(ck, 64, "%s,", NULL != r[1] ? r[1] : r[0]); if (r[0] == NULL || r[1] == NULL || strcmp(r[0], r[1]) != 0) { if (synked_nodetype == ZBX_NODE_SLAVE) { s[0] = c[0]; s[1] = ' '; } else if (synked_nodetype == ZBX_NODE_MASTER) { s[0] = ' '; s[1] = c[0]; } } else { if (synked == SUCCEED) { if (synked_nodetype == ZBX_NODE_SLAVE) s[0] = c[0]; else if (synked_nodetype == ZBX_NODE_MASTER) s[1] = c[0]; } } } else ck += zbx_snprintf(ck, 64, "%s,", NULL != r[0] ? r[0] : ""); s += 2; f++; if (d[0] != NULL) { *d[0] = ','; r[0] = d[0] + 1; } else r[0] = NULL; if (d[1] != NULL) { *d[1] = ','; r[1] = d[1] + 1; } else r[1] = NULL; } while (d[0] != NULL || d[1] != NULL); *--ck = '\0'; } *s = '\0'; if (SUCCEED == DBis_null(row[2]) || SUCCEED == DBis_null(row[3]) || 0 != strcmp(row[4], sync) || 0 != strcmp(row[2], row[3])) { cksumtype = (DBis_null(row[2]) == SUCCEED) ? NODE_CKSUM_TYPE_NEW : NODE_CKSUM_TYPE_OLD; zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 2560, "update node_cksum" " set cksumtype=%d," "cksum='%s'," "sync='%s'" " where nodeid=%d" " and cksumtype=%d" " and tablename='%s'" " and recordid=%s;\n", NODE_CKSUM_TYPE_OLD, cksum, sync, nodeid, cksumtype, row[0], row[1]); DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset); } } DBfree_result(result); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 8, "end;\n"); #endif if (exsql_offset > 16) /* In ORACLE always present begin..end; */ DBexecute("%s", exsql); zbx_free(exsql); DBcommit(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return SUCCEED; }
/****************************************************************************** * * * Function: lld_process_discovery_rule * * * * Purpose: add or update items, triggers and graphs for discovery item * * * * Parameters: lld_ruleid - [IN] discovery item identificator from database * * value - [IN] received value from agent * * * ******************************************************************************/ void lld_process_discovery_rule(zbx_uint64_t lld_ruleid, char *value, zbx_timespec_t *ts) { const char *__function_name = "lld_process_discovery_rule"; DB_RESULT result; DB_ROW row; zbx_uint64_t hostid = 0; char *discovery_key = NULL, *filter = NULL, *error = NULL, *db_error = NULL, *error_esc; unsigned char state = 0; unsigned short lifetime; zbx_vector_ptr_t lld_rows; char *sql = NULL; size_t sql_alloc = 128, sql_offset = 0; const char *sql_start = "update items set ", *sql_continue = ","; zabbix_log(LOG_LEVEL_DEBUG, "In %s() itemid:" ZBX_FS_UI64, __function_name, lld_ruleid); zbx_vector_ptr_create(&lld_rows); sql = zbx_malloc(sql, sql_alloc); result = DBselect( "select hostid,key_,state,filter,error,lifetime" " from items" " where itemid=" ZBX_FS_UI64, lld_ruleid); if (NULL != (row = DBfetch(result))) { char *lifetime_str; ZBX_STR2UINT64(hostid, row[0]); discovery_key = zbx_strdup(discovery_key, row[1]); state = (unsigned char)atoi(row[2]); filter = zbx_strdup(filter, row[3]); db_error = zbx_strdup(db_error, row[4]); lifetime_str = zbx_strdup(NULL, row[5]); substitute_simple_macros(NULL, NULL, NULL, NULL, &hostid, NULL, NULL, &lifetime_str, MACRO_TYPE_COMMON, NULL, 0); if (SUCCEED != is_ushort(lifetime_str, &lifetime)) { zabbix_log(LOG_LEVEL_WARNING, "cannot process lost resources for the discovery rule \"%s:%s\":" " \"%s\" is not a valid value", zbx_host_string(hostid), discovery_key, lifetime_str); lifetime = 3650; /* max value for the field */ } zbx_free(lifetime_str); } else zabbix_log(LOG_LEVEL_WARNING, "invalid discovery rule ID [" ZBX_FS_UI64 "]", lld_ruleid); DBfree_result(result); if (0 == hostid) goto clean; if (SUCCEED != lld_rows_get(value, filter, &lld_rows, &error)) goto error; error = zbx_strdup(error, ""); lld_update_items(hostid, lld_ruleid, &lld_rows, &error, lifetime, ts->sec); lld_update_triggers(hostid, lld_ruleid, &lld_rows, &error); lld_update_graphs(hostid, lld_ruleid, &lld_rows, &error); lld_update_hosts(lld_ruleid, &lld_rows, &error, lifetime, ts->sec); if (ITEM_STATE_NOTSUPPORTED == state) { zabbix_log(LOG_LEVEL_WARNING, "discovery rule [" ZBX_FS_UI64 "][%s] became supported", lld_ruleid, zbx_host_key_string(lld_ruleid)); add_event(0, EVENT_SOURCE_INTERNAL, EVENT_OBJECT_LLDRULE, lld_ruleid, ts, ITEM_STATE_NORMAL, NULL, NULL, 0, 0); process_events(); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sstate=%d", sql_start, ITEM_STATE_NORMAL); sql_start = sql_continue; } error: if (NULL != error && 0 != strcmp(error, db_error)) { error_esc = DBdyn_escape_string_len(error, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%serror='%s'", sql_start, error_esc); sql_start = sql_continue; zbx_free(error_esc); } if (sql_start == sql_continue) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64, lld_ruleid); DBbegin(); DBexecute("%s", sql); DBcommit(); } clean: zbx_free(error); zbx_free(db_error); zbx_free(filter); zbx_free(discovery_key); zbx_free(sql); zbx_vector_ptr_clean(&lld_rows, (zbx_mem_free_func_t)lld_row_free); zbx_vector_ptr_destroy(&lld_rows); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: update_checksums * * * * Purpose: overwrite old checksums with new ones * * * * Parameters: * * * * Return value: SUCCESS - calculated successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ int update_checksums(int nodeid, int synked_nodetype, int synked, const char *tablename, const zbx_uint64_t id, const char *fields) { const char *__function_name = "update_checksums"; char *r[2], *d[2], sync[129], *s; char c[2], sql[2][256]; char cksum[32 * 72 + 72], *ck; char *exsql = NULL; size_t exsql_alloc = 64 * ZBX_KIBIBYTE, exsql_offset = 0; int cksumtype; DB_RESULT result; DB_ROW row; int f; const ZBX_TABLE *table; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); exsql = zbx_malloc(exsql, exsql_alloc); DBbegin(); DBbegin_multiple_update(&exsql, &exsql_alloc, &exsql_offset); c[0] = SUCCEED == synked ? '1' : ' '; /* for new and updated records */ c[1] = SUCCEED == synked ? '2' : ' '; /* for deleted records */ if (NULL != tablename) { zbx_snprintf(sql[0], sizeof(sql[0]), " and curr.tablename='%s' and curr.recordid=" ZBX_FS_UI64, tablename, id); zbx_snprintf(sql[1], sizeof(sql[1]), " and prev.tablename='%s' and prev.recordid=" ZBX_FS_UI64, tablename, id); } else { *sql[0] = '\0'; *sql[1] = '\0'; } result = DBselect( /* new records */ "select curr.tablename,curr.recordid,prev.cksum,curr.cksum,NULL" " from node_cksum curr" " left join node_cksum prev" " on prev.nodeid=curr.nodeid" " and prev.tablename=curr.tablename" " and prev.recordid=curr.recordid" " and prev.cksumtype=%d" " where curr.nodeid=%d" " and curr.cksumtype=%d" " and prev.tablename is null%s" " union all " /* updated records */ "select curr.tablename,curr.recordid,prev.cksum,curr.cksum,prev.sync" " from node_cksum curr, node_cksum prev" " where curr.nodeid=%d" " and prev.nodeid=curr.nodeid" " and curr.tablename=prev.tablename" " and curr.recordid=prev.recordid" " and curr.cksumtype=%d" " and prev.cksumtype=%d%s" " union all " /* deleted records */ "select prev.tablename,prev.recordid,prev.cksum,curr.cksum,prev.sync" " from node_cksum prev" " left join node_cksum curr" " on curr.nodeid=prev.nodeid" " and curr.tablename=prev.tablename" " and curr.recordid=prev.recordid" " and curr.cksumtype=%d" " where prev.nodeid=%d" " and prev.cksumtype=%d" " and curr.tablename is null%s", NODE_CKSUM_TYPE_OLD, nodeid, NODE_CKSUM_TYPE_NEW, sql[0], nodeid, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD, sql[0], NODE_CKSUM_TYPE_NEW, nodeid, NODE_CKSUM_TYPE_OLD, sql[1]); while (NULL != (row = DBfetch(result))) { if (NULL == (table = DBget_table(row[0]))) { zabbix_log(LOG_LEVEL_WARNING, "cannot find table [%s]", row[0]); continue; } memset(sync, ' ', sizeof(sync)); if (FAIL == DBis_null(row[4])) memcpy(sync, row[4], strlen(row[4])); s = sync; ck = cksum; *ck = '\0'; /* special (simpler) processing for operation DELETE */ if (SUCCEED == DBis_null(row[3])) { if (SUCCEED == synked) s[synked_nodetype] = c[1]; if ((0 == CONFIG_MASTER_NODEID || s[1] == c[1]) && (CONFIG_NODEID == nodeid || s[0] == c[1])) { zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, "delete from node_cksum" " where nodeid=%d" " and cksumtype=%d" " and tablename='%s'" " and recordid=%s;\n", nodeid, NODE_CKSUM_TYPE_OLD, row[0], row[1]); DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset); continue; } s += 2; } else { r[0] = SUCCEED == DBis_null(row[2]) ? NULL : row[2]; r[1] = row[3]; f = 0; do { while ((table->fields[f].flags & ZBX_SYNC) == 0) f++; /* "host_inventory" table has more than 64 fields */ /* remaining fields are processed as one */ if (128 == s - sync) s -= 2; d[0] = NULL; d[1] = NULL; if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ','))) *d[0] = '\0'; if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ','))) *d[1] = '\0'; if (NULL == tablename || SUCCEED == str_in_list(fields, table->fields[f].name, ',')) { ck += zbx_snprintf(ck, 64, "%s,", NULL != r[1] ? r[1] : r[0]); if (NULL == r[0] || NULL == r[1] || 0 != strcmp(r[0], r[1])) { s[0] = s[1] = ' '; s[synked_nodetype] = c[0]; } else { if (SUCCEED == synked) s[synked_nodetype] = c[0]; } } else ck += zbx_snprintf(ck, 64, "%s,", NULL != r[0] ? r[0] : ""); s += 2; f++; if (d[0] != NULL) { *d[0] = ','; r[0] = d[0] + 1; } else r[0] = NULL; if (d[1] != NULL) { *d[1] = ','; r[1] = d[1] + 1; } else r[1] = NULL; } while (d[0] != NULL || d[1] != NULL); *--ck = '\0'; } *s = '\0'; if (SUCCEED == DBis_null(row[2]) || SUCCEED == DBis_null(row[3]) || 0 != strcmp(row[4], sync) || 0 != strcmp(row[2], row[3])) { cksumtype = (DBis_null(row[2]) == SUCCEED) ? NODE_CKSUM_TYPE_NEW : NODE_CKSUM_TYPE_OLD; zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, "update node_cksum" " set cksumtype=%d," "cksum='%s'," "sync='%s'" " where nodeid=%d" " and cksumtype=%d" " and tablename='%s'" " and recordid=%s;\n", NODE_CKSUM_TYPE_OLD, cksum, sync, nodeid, cksumtype, row[0], row[1]); DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset); } } DBfree_result(result); DBend_multiple_update(&exsql, &exsql_alloc, &exsql_offset); if (exsql_offset > 16) /* In ORACLE always present begin..end; */ DBexecute("%s", exsql); zbx_free(exsql); DBcommit(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return SUCCEED; }
/****************************************************************************** * * * Function: delete_history * * * * Purpose: remove outdated information from historical table * * * * Parameters: now - current timestamp * * * * Return value: number of rows records * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int delete_history(const char *table, const char *fieldname, int now) { const char *__function_name = "delete_history"; DB_RESULT result; DB_ROW row; int minclock, records = 0; zbx_uint64_t lastid, maxid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' now:%d", __function_name, table, now); DBbegin(); result = DBselect( "select nextid" " from ids" " where table_name='%s'" " and field_name='%s'", table, fieldname); if (NULL == (row = DBfetch(result))) goto rollback; ZBX_STR2UINT64(lastid, row[0]); DBfree_result(result); result = DBselect("select min(clock) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; minclock = atoi(row[0]); DBfree_result(result); result = DBselect("select max(id) from %s", table); if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0])) goto rollback; ZBX_STR2UINT64(maxid, row[0]); DBfree_result(result); records = DBexecute( "delete from %s" " where id<" ZBX_FS_UI64 " and (clock<%d" " or (id<=" ZBX_FS_UI64 " and clock<%d))", table, maxid, now - CONFIG_PROXY_OFFLINE_BUFFER * SEC_PER_HOUR, lastid, MIN(now - CONFIG_PROXY_LOCAL_BUFFER * SEC_PER_HOUR, minclock + HK_MAX_DELETE_PERIODS * hk_period)); DBcommit(); return records; rollback: DBfree_result(result); DBrollback(); return 0; }
/****************************************************************************** * * * Function: change_nodeid * * * * Purpose: convert database data to new node ID * * * * Parameters: old_id - old id, new_id - new node id * * * * Return value: SUCCEED - converted successfully * * FAIL - an error occurred * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int change_nodeid(int old_id, int new_id) { struct conv_t { const char *rel; int type; }; struct special_conv_t { const char *table_name, *field_name, *type_field_name; struct conv_t convs[32]; }; struct special_conv_t special_convs[] = { {"sysmaps_elements", "elementid", "elementtype", { {"hosts", SYSMAP_ELEMENT_TYPE_HOST}, {"sysmaps", SYSMAP_ELEMENT_TYPE_MAP}, {"triggers", SYSMAP_ELEMENT_TYPE_TRIGGER}, {"groups", SYSMAP_ELEMENT_TYPE_HOST_GROUP}, {"images", SYSMAP_ELEMENT_TYPE_IMAGE}, {NULL} } }, {"events", "objectid", "object", { {"triggers", EVENT_OBJECT_TRIGGER}, {"dhosts", EVENT_OBJECT_DHOST}, {"dservices", EVENT_OBJECT_DSERVICE}, {NULL} } }, {"ids", "nextid", NULL, { {NULL} } }, {"node_cksum", "recordid", NULL, { {NULL} } }, {"screens_items", "resourceid", "resourcetype", { {"graphs", SCREEN_RESOURCE_GRAPH}, {"items", SCREEN_RESOURCE_SIMPLE_GRAPH}, {"sysmaps", SCREEN_RESOURCE_MAP}, {"items", SCREEN_RESOURCE_PLAIN_TEXT}, {"groups", SCREEN_RESOURCE_HOSTS_INFO}, {"screens", SCREEN_RESOURCE_SCREEN}, {"groups", SCREEN_RESOURCE_TRIGGERS_OVERVIEW}, {"groups", SCREEN_RESOURCE_DATA_OVERVIEW}, {"groups", SCREEN_RESOURCE_HOSTGROUP_TRIGGERS}, {"hosts", SCREEN_RESOURCE_HOST_TRIGGERS}, {NULL} } }, {"auditlog", "resourceid", "resourcetype", { {"users", AUDIT_RESOURCE_USER}, /* {"", AUDIT_RESOURCE_ZABBIX},*/ {"config", AUDIT_RESOURCE_ZABBIX_CONFIG}, {"media_type", AUDIT_RESOURCE_MEDIA_TYPE}, {"hosts", AUDIT_RESOURCE_HOST}, {"actions", AUDIT_RESOURCE_ACTION}, {"graphs", AUDIT_RESOURCE_GRAPH}, {"graphs_items", AUDIT_RESOURCE_GRAPH_ELEMENT}, /* {"", AUDIT_RESOURCE_ESCALATION}, {"", AUDIT_RESOURCE_ESCALATION_RULE}, {"", AUDIT_RESOURCE_AUTOREGISTRATION},*/ {"usrgrp", AUDIT_RESOURCE_USER_GROUP}, {"applications", AUDIT_RESOURCE_APPLICATION}, {"triggers", AUDIT_RESOURCE_TRIGGER}, {"groups", AUDIT_RESOURCE_HOST_GROUP}, {"items", AUDIT_RESOURCE_ITEM}, {"images", AUDIT_RESOURCE_IMAGE}, {"valuemaps", AUDIT_RESOURCE_VALUE_MAP}, {"services", AUDIT_RESOURCE_IT_SERVICE}, {"sysmaps", AUDIT_RESOURCE_MAP}, {"screens", AUDIT_RESOURCE_SCREEN}, /* {"nodes", AUDIT_RESOURCE_NODE},*/ /* {"", AUDIT_RESOURCE_SCENARIO},*/ {"drules", AUDIT_RESOURCE_DISCOVERY_RULE}, {"slideshows", AUDIT_RESOURCE_SLIDESHOW}, {"scripts", AUDIT_RESOURCE_SCRIPT}, /* {"", AUDIT_RESOURCE_PROXY},*/ {"maintenances", AUDIT_RESOURCE_MAINTENANCE}, {"regexps", AUDIT_RESOURCE_REGEXP}, {NULL} } }, {NULL} }; struct conv_t condition_convs[] = { {"groups", CONDITION_TYPE_HOST_GROUP}, {"hosts", CONDITION_TYPE_HOST}, {"hosts", CONDITION_TYPE_HOST_TEMPLATE}, {"hosts", CONDITION_TYPE_PROXY}, {"triggers", CONDITION_TYPE_TRIGGER}, {"dchecks", CONDITION_TYPE_DCHECK}, {"drules", CONDITION_TYPE_DRULE}, {NULL}, }; int i, j, s, t, ret = FAIL; zbx_uint64_t prefix; const ZBX_TABLE *r_table; if (0 != old_id) { printf("Conversion from non-zero node ID is not supported.\n"); return ret; } if (1 > new_id || new_id > 999) { printf("Node ID must be in range of 1-999.\n"); return ret; } zabbix_set_log_level(LOG_LEVEL_WARNING); DBconnect(ZBX_DB_CONNECT_EXIT); DBbegin(); printf("Dropping foreign keys "); fflush(stdout); for (i = 0; NULL != db_schema_fkeys_drop[i]; i++) { DBexecute("%s", db_schema_fkeys_drop[i]); printf("."); fflush(stdout); } printf(" done.\nConverting tables "); fflush(stdout); for (i = 0; NULL != tables[i].table; i++) { printf("."); fflush(stdout); for (j = 0; NULL != tables[i].fields[j].name; j++) { for (s = 0; NULL != special_convs[s].table_name; s++) { if (0 == strcmp(special_convs[s].table_name, tables[i].table) && 0 == strcmp(special_convs[s].field_name, tables[i].fields[j].name)) { break; } } if (NULL != special_convs[s].table_name) { for (t = 0; NULL != special_convs[s].convs[t].rel; t++) { convert_special_field(old_id, new_id, special_convs[s].table_name, special_convs[s].field_name, special_convs[s].type_field_name, special_convs[s].convs[t].rel, special_convs[s].convs[t].type); } continue; } if (ZBX_TYPE_ID != tables[i].fields[j].type) continue; /* primary key */ if (0 == strcmp(tables[i].fields[j].name, tables[i].recid)) { prefix = (zbx_uint64_t)__UINT64_C(100000000000000) * (zbx_uint64_t)new_id; if (0 != (tables[i].flags & ZBX_SYNC)) prefix += (zbx_uint64_t)__UINT64_C(100000000000) * (zbx_uint64_t)new_id; } /* relations */ else if (NULL != tables[i].fields[j].fk_table) { r_table = DBget_table(tables[i].fields[j].fk_table); assert(NULL != r_table); prefix = (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)new_id; if (0 != (r_table->flags & ZBX_SYNC)) prefix += (zbx_uint64_t)__UINT64_C(100000000000)*(zbx_uint64_t)new_id; } /* special processing for table 'profiles' */ else if (0 == strcmp("profiles", tables[i].table)) { convert_profiles(old_id, new_id, tables[i].fields[j].name); continue; } else assert(0); DBexecute("update %s set %s=%s+" ZBX_FS_UI64 " where %s>0", tables[i].table, tables[i].fields[j].name, tables[i].fields[j].name, prefix, tables[i].fields[j].name); } } /* special processing for trigger expressions */ convert_triggers_expression(old_id, new_id); /* special processing for condition values */ for (i = 0; NULL != condition_convs[i].rel; i++) convert_condition_values(old_id, new_id, condition_convs[i].rel, condition_convs[i].type); DBexecute("insert into nodes (nodeid,name,ip,nodetype) values (%d,'Local node','127.0.0.1',1)", new_id); DBexecute("delete from ids where nodeid=0"); if (SUCCEED != (ret = DBtxn_status())) goto error; printf(" done.\nCreating foreign keys "); fflush(stdout); for (i = 0; NULL != db_schema_fkeys[i]; i++) { DBexecute("%s", db_schema_fkeys[i]); printf("."); fflush(stdout); } ret = DBtxn_status(); error: DBcommit(); DBclose(); if (SUCCEED != ret) printf("Conversion failed.\n"); else printf(" done.\nConversion completed successfully.\n"); return ret; }
static void deactivate_host(DC_ITEM *item, int now, const char *error) { char sql[MAX_STRING_LEN], *error_esc, error_msg[MAX_STRING_LEN]; int offset = 0, *errors_from, *disable_until; unsigned char *available; const char *fld_errors_from, *fld_available, *fld_disable_until, *fld_error, *type; switch (item->type) { case ITEM_TYPE_ZABBIX: errors_from = &item->host.errors_from; available = &item->host.available; disable_until = &item->host.disable_until; fld_errors_from = "errors_from"; fld_available = "available"; fld_disable_until = "disable_until"; fld_error = "error"; type = "Zabbix"; break; case ITEM_TYPE_SNMPv1: case ITEM_TYPE_SNMPv2c: case ITEM_TYPE_SNMPv3: errors_from = &item->host.snmp_errors_from; available = &item->host.snmp_available; disable_until = &item->host.snmp_disable_until; fld_errors_from = "snmp_errors_from"; fld_available = "snmp_available"; fld_disable_until = "snmp_disable_until"; fld_error = "snmp_error"; type = "SNMP"; break; case ITEM_TYPE_IPMI: errors_from = &item->host.ipmi_errors_from; available = &item->host.ipmi_available; disable_until = &item->host.ipmi_disable_until; fld_errors_from = "ipmi_errors_from"; fld_available = "ipmi_available"; fld_disable_until = "ipmi_disable_until"; fld_error = "ipmi_error"; type = "IPMI"; break; default: return; } if (SUCCEED != DCconfig_deactivate_host(item, now)) return; DBbegin(); *error_msg = '\0'; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "update hosts set "); /* First error */ if (0 == *errors_from) { zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: first network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *errors_from = now; *disable_until = now + CONFIG_UNREACHABLE_DELAY; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_errors_from, *errors_from); } else { if (now - *errors_from <= CONFIG_UNREACHABLE_PERIOD) { /* Still unavailable, but won't change status to UNAVAILABLE yet */ zbx_snprintf(error_msg, sizeof(error_msg), "%s Host [%s]: another network error, wait for %d seconds", type, item->host.host, CONFIG_UNREACHABLE_DELAY); *disable_until = now + CONFIG_UNREACHABLE_DELAY; } else { *disable_until = now + CONFIG_UNAVAILABLE_DELAY; if (HOST_AVAILABLE_FALSE != *available) { zbx_snprintf(error_msg, sizeof(error_msg), "Disabling %s host [%s]", type, item->host.host); *available = HOST_AVAILABLE_FALSE; offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d,", fld_available, *available); if (available == &item->host.available) update_key_status(item->host.hostid, HOST_AVAILABLE_FALSE, now); /* 2 */ update_triggers_status_to_unknown(item->host.hostid, item->type, now, "Agent is unavailable."); } error_esc = DBdyn_escape_string_len(error, HOST_ERROR_LEN); offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s='%s',", fld_error, error_esc); zbx_free(error_esc); } } offset += zbx_snprintf(sql + offset, sizeof(sql) - offset, "%s=%d where hostid=" ZBX_FS_UI64, fld_disable_until, *disable_until, item->host.hostid); DBexecute("%s", sql); DBcommit(); if ('\0' != *error_msg) { zabbix_log(LOG_LEVEL_WARNING, "%s", error_msg); zabbix_syslog("%s", error_msg); } }