static void add_command_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, char *command) { zbx_uint64_t alertid; int now; char *command_esc; zabbix_log(LOG_LEVEL_DEBUG, "In add_command_alert()"); alertid = DBget_maxid("alerts", "alertid"); now = time(NULL); command_esc = DBdyn_escape_string(command); DBexecute("insert into alerts (alertid,actionid,eventid,clock,message,status,alerttype,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s',%d,%d,%d)", alertid, action->actionid, event->eventid, now, command_esc, ALERT_STATUS_SENT, ALERT_TYPE_COMMAND, escalation->esc_step); op_run_commands(command); zbx_free(command_esc); }
/****************************************************************************** * * * Function: register_host * * * * Purpose: register host if one does not exist * * * * Parameters: host ip address * * * * Return value: dhostid or 0 if we didn't add host * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void register_host(DB_DHOST *host,DB_DCHECK *check, zbx_uint64_t druleid, char *ip) { DB_RESULT result; DB_ROW row; char hostname[MAX_STRING_LEN], hostname_esc[MAX_STRING_LEN]; assert(host); assert(check); assert(ip); zabbix_log(LOG_LEVEL_DEBUG, "In register_host(ip:%s)", ip); host->dhostid=0; result = DBselect("select dhostid,druleid,ip,status,lastup,lastdown from dhosts where ip='%s'", ip); row=DBfetch(result); if(!row || DBis_null(row[0])==SUCCEED) { /* Add host only if service is up */ if(check->status == DOBJECT_STATUS_UP) { alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(ip, hostname, sizeof(hostname)); alarm(0); if (hostname[0] != '\0') DBescape_string(hostname, hostname_esc, sizeof(hostname_esc)); else hostname_esc[0] = '\0'; zabbix_log(LOG_LEVEL_DEBUG, "New host discovered at %s (%s)", ip, hostname); host->dhostid = DBget_maxid("dhosts","dhostid"); DBexecute("insert into dhosts (dhostid, druleid, dns, ip) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ", '%s','%s')", host->dhostid, druleid, hostname_esc, ip); host->druleid = druleid; strscpy(host->ip,ip); host->status = 0; host->lastup = 0; host->lastdown = 0; } } else { zabbix_log(LOG_LEVEL_DEBUG, "Host is already in database"); ZBX_STR2UINT64(host->dhostid,row[0]); ZBX_STR2UINT64(host->druleid,row[1]); strscpy(host->ip, row[2]); host->status = atoi(row[3]); host->lastup = atoi(row[4]); host->lastdown = atoi(row[5]); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End register_host()"); }
static void add_command_alert(DC_HOST *host, zbx_uint64_t eventid, zbx_uint64_t actionid, int esc_step, const char *command, zbx_alert_status_t status, const char *error) { const char *__function_name = "add_command_alert"; zbx_uint64_t alertid; int now; char *tmp = NULL, *command_esc, *error_esc; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); alertid = DBget_maxid("alerts"); now = (int)time(NULL); tmp = zbx_dsprintf(tmp, "%s:%s", host->host, NULL == command ? "" : command); command_esc = DBdyn_escape_string_len(tmp, ALERT_MESSAGE_LEN); error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN); zbx_free(tmp); DBexecute("insert into alerts" " (alertid,actionid,eventid,clock,message,status,error,alerttype,esc_step)" " values " "(" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s',%d,'%s',%d,%d)", alertid, actionid, eventid, now, command_esc, (int)status, error_esc, ALERT_TYPE_COMMAND, esc_step); zbx_free(error_esc); zbx_free(command_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: process_event * * * * Purpose: process new event * * * * Parameters: event - event data (event.eventid - new event) * * * * Return value: SUCCEED - event added * * FAIL - event not added * * * * Comments: When processing trigger events IT services updates are queued * * and _must_ be flushed at the end of transaction with * * DBflush_itservice_updates() function !!! * * * * Author: Alexei Vladishev * * * ******************************************************************************/ int process_event(zbx_uint64_t eventid, int source, int object, zbx_uint64_t objectid, const zbx_timespec_t *timespec, int value, unsigned char value_changed, int acknowledged, int force_actions) { const char *__function_name = "process_event"; DB_EVENT event; int ret = FAIL; zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64 " object:%d objectid:" ZBX_FS_UI64 " value:%d" " value_changed:%d", __function_name, eventid, object, objectid, value, (int)value_changed); /* preparing event for processing */ memset(&event, 0, sizeof(DB_EVENT)); event.eventid = eventid; event.source = source; event.object = object; event.objectid = objectid; event.clock = timespec->sec; event.ns = timespec->ns; event.value = value; event.value_changed = value_changed; event.acknowledged = acknowledged; if (TRIGGER_VALUE_CHANGED_YES == event.value_changed || 1 == force_actions) if (SUCCEED != add_trigger_info(&event)) goto fail; if (0 == event.eventid) event.eventid = DBget_maxid("events"); DBexecute("insert into events (eventid,source,object,objectid,clock,ns,value,value_changed)" " values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d,%d,%d)", event.eventid, event.source, event.object, event.objectid, event.clock, event.ns, event.value, (int)event.value_changed); if (TRIGGER_VALUE_CHANGED_YES == event.value_changed || 1 == force_actions) process_actions(&event); if (TRIGGER_VALUE_CHANGED_YES == event.value_changed && EVENT_OBJECT_TRIGGER == event.object) { DBqueue_itservice_update(event.objectid, TRIGGER_VALUE_TRUE == event.value ? event.trigger.priority : 0, event.clock); } ret = SUCCEED; fail: zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_result_string(ret)); return ret; }
/****************************************************************************** * * * Function: discovery_separate_host * * * * Purpose: separate multiple-IP hosts * * * * Parameters: host ip address * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static void discovery_separate_host(DB_DRULE *drule, DB_DHOST *dhost, const char *ip) { const char *__function_name = "discovery_separate_host"; DB_RESULT result; DB_ROW row; char *ip_esc, *sql = NULL; zbx_uint64_t dhostid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s'", __function_name, ip); ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN); sql = zbx_dsprintf(sql, "select dserviceid" " from dservices" " where dhostid=" ZBX_FS_UI64 " and ip" ZBX_SQL_STRCMP, dhost->dhostid, ZBX_SQL_STRVAL_NE(ip_esc)); result = DBselectN(sql, 1); if (NULL != (row = DBfetch(result))) { dhostid = DBget_maxid("dhosts"); DBexecute("insert into dhosts (dhostid,druleid)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ")", dhostid, drule->druleid); DBexecute("update dservices" " set dhostid=" ZBX_FS_UI64 " where dhostid=" ZBX_FS_UI64 " and ip" ZBX_SQL_STRCMP, dhostid, dhost->dhostid, ZBX_SQL_STRVAL_EQ(ip_esc)); dhost->dhostid = dhostid; dhost->status = DOBJECT_STATUS_DOWN; dhost->lastup = 0; dhost->lastdown = 0; } DBfree_result(result); zbx_free(sql); zbx_free(ip_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: add_discovered_host_group * * * * Purpose: add group to host if not added already * * * * Author: Alexander Vladishev * * * ******************************************************************************/ static void add_discovered_host_group(zbx_uint64_t hostid, zbx_uint64_t groupid) { DB_RESULT result; DB_ROW row; zbx_uint64_t hostgroupid; result = DBselect( "select hostgroupid" " from hosts_groups" " where groupid=" ZBX_FS_UI64 " and hostid=" ZBX_FS_UI64, groupid, hostid); if (NULL == (row = DBfetch(result))) { hostgroupid = DBget_maxid("hosts_groups"); DBexecute("insert into hosts_groups (hostgroupid,hostid,groupid)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ")", hostgroupid, hostid, groupid); } DBfree_result(result); }
/****************************************************************************** * * * Function: save_events * * * * Purpose: flushes the events into a database * * * ******************************************************************************/ static void save_events() { char *sql = NULL; size_t sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0, i; const char *ins_event_sql = "insert into events (eventid,source,object,objectid,clock,ns,value) values "; sql = zbx_malloc(sql, sql_alloc); DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset); #ifdef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_event_sql); #endif for (i = 0; i < events_num; i++) { if (0 == events[i].eventid) events[i].eventid = DBget_maxid("events"); #ifndef HAVE_MULTIROW_INSERT zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ins_event_sql); #endif zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "(" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d,%d)" ZBX_ROW_DL, events[i].eventid, events[i].source, events[i].object, events[i].objectid, events[i].clock, events[i].ns, events[i].value); } #ifdef HAVE_MULTIROW_INSERT sql_offset--; zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n"); #endif DBend_multiple_update(&sql, &sql_alloc, &sql_offset); DBexecute("%s", sql); zbx_free(sql); }
static void add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, zbx_uint64_t userid, zbx_uint64_t mediatypeid, const char *subject, const char *message) { const char *__function_name = "add_message_alert"; DB_RESULT result; DB_ROW row; zbx_uint64_t alertid; int now, severity, medias = 0; char *subject_dyn, *message_dyn, *sendto_esc, *subject_esc, *message_esc, *error_esc; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); subject_dyn = zbx_strdup(NULL, subject); message_dyn = zbx_strdup(NULL, message); substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &subject_dyn, MACRO_TYPE_MESSAGE, NULL, 0); substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &message_dyn, MACRO_TYPE_MESSAGE, NULL, 0); now = time(NULL); subject_esc = DBdyn_escape_string_len(subject_dyn, ALERT_SUBJECT_LEN); message_esc = DBdyn_escape_string_len(message_dyn, ALERT_MESSAGE_LEN); zbx_free(subject_dyn); zbx_free(message_dyn); if (0 == mediatypeid) { result = DBselect( "select m.mediatypeid,m.sendto,m.severity,m.period,mt.status" " from media m,media_type mt" " where m.mediatypeid=mt.mediatypeid" " and m.active=%d" " and m.userid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid); } else { result = DBselect( "select m.mediatypeid,m.sendto,m.severity,m.period,mt.status" " from media m,media_type mt" " where m.mediatypeid=mt.mediatypeid" " and m.active=%d" " and m.userid=" ZBX_FS_UI64 " and m.mediatypeid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid, mediatypeid); } while (NULL != (row = DBfetch(result))) { medias = 1; ZBX_STR2UINT64(mediatypeid, row[0]); severity = atoi(row[2]); zabbix_log(LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]", (int)event->trigger.priority, severity, row[3]); if (((1 << event->trigger.priority) & severity) == 0) { zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (severity)"); continue; } if (FAIL == check_time_period(row[3], (time_t)NULL)) { zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (period)"); continue; } alertid = DBget_maxid("alerts"); sendto_esc = DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN); if (MEDIA_TYPE_STATUS_ACTIVE == atoi(row[4])) { DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, escalation->esc_step); } else { error_esc = DBdyn_escape_string("Media type disabled"); DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step,error)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d,'%s')", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, escalation->esc_step, error_esc); zbx_free(error_esc); } zbx_free(sendto_esc); } DBfree_result(result); if (0 == medias) { zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"", zbx_user_string(userid)); alertid = DBget_maxid("alerts"); error_esc = DBdyn_escape_string(error); DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock" ",subject,message,status,alerttype,error,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d" ",'%s','%s',%d,%d,'%s',%d)", alertid, action->actionid, event->eventid, userid, ALERT_MAX_RETRIES, now, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, error_esc, escalation->esc_step); zbx_free(error_esc); } zbx_free(subject_esc); zbx_free(message_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: compare_checksums * * * * Purpose: compare new checksums with old ones. Write difference to * * table 'node_config' * * * * Parameters: * * * * Return value: SUCCESS - calculated succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int compare_checksums() { DB_RESULT result; DB_ROW row; /* Find updated records */ result = DBselect("select curr.nodeid,curr.tablename,curr.recordid from node_cksum prev, node_cksum curr where curr.tablename=prev.tablename and curr.recordid=prev.recordid and curr.fieldname=prev.fieldname and curr.nodeid=prev.nodeid and curr.cksum<>prev.cksum and curr.cksumtype=%d and prev.cksumtype=%d", NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD); while((row=DBfetch(result))) { zabbix_log( LOG_LEVEL_DEBUG, "Adding record to node_configlog NODE_CONFIGLOG_OP_UPDATE"); DBexecute("insert into node_configlog (conflogid,nodeid,tablename,recordid,operation)" \ "values (" ZBX_FS_UI64 ",%s,'%s',%s,%d)", /* DBget_nextid("node_configlog","conflogid"),*/ DBget_maxid("node_configlog","conflogid"), row[0], row[1], row[2], NODE_CONFIGLOG_OP_UPDATE); } DBfree_result(result); /* Find new records */ result = DBselect("select curr.nodeid,curr.tablename,curr.recordid from node_cksum curr" \ " left join node_cksum prev" \ " on curr.tablename=prev.tablename and curr.recordid=prev.recordid and curr.fieldname=prev.fieldname and curr.nodeid=prev.nodeid and curr.cksumtype<>prev.cksumtype" \ " where prev.cksumid is null and curr.cksumtype=%d", NODE_CKSUM_TYPE_NEW); while((row=DBfetch(result))) { zabbix_log( LOG_LEVEL_DEBUG, "Adding record to node_configlog NODE_CONFIGLOG_OP_ADD"); DBexecute("insert into node_configlog (conflogid,nodeid,tablename,recordid,operation)" \ "values (" ZBX_FS_UI64 ",%s,'%s',%s,%d)", /* DBget_nextid("node_configlog","conflogid"),*/ DBget_maxid("node_configlog","conflogid"), row[0], row[1], row[2], NODE_CONFIGLOG_OP_ADD); } DBfree_result(result); /* Find deleted records */ result = DBselect("select curr.nodeid,curr.tablename,curr.recordid from node_cksum curr" \ " left join node_cksum prev" \ " on curr.tablename=prev.tablename and curr.recordid=prev.recordid and curr.fieldname=prev.fieldname and curr.nodeid=prev.nodeid and curr.cksumtype<>prev.cksumtype" \ " where prev.cksumid is null and curr.cksumtype=%d", NODE_CKSUM_TYPE_OLD); while((row=DBfetch(result))) { zabbix_log( LOG_LEVEL_DEBUG, "Adding record to node_configlog NODE_CONFIGLOG_OP_DELETE"); DBexecute("insert into node_configlog (conflogid,nodeid,tablename,recordid,operation)" \ "values (" ZBX_FS_UI64 ",%s,'%s',%s,%d)", /* DBget_nextid("node_configlog","conflogid"),*/ DBget_maxid("node_configlog","conflogid"), row[0], row[1], row[2], NODE_CONFIGLOG_OP_DELETE); } DBfree_result(result); return SUCCEED; }
/****************************************************************************** * * * Function: add host if not added already * * * * Purpose: add discovered host * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - new/existing hostid * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t add_discovered_host(DB_EVENT *event) { const char *__function_name = "add_discovered_host"; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; zbx_uint64_t hostid = 0, proxy_hostid, host_proxy_hostid; char host[MAX_STRING_LEN], *host_esc, *ip_esc, *host_unique, *host_unique_esc; int port; zbx_uint64_t groupid; zabbix_log(LOG_LEVEL_DEBUG, "In %s(eventid:" ZBX_FS_UI64 ")", __function_name, event->eventid); result = DBselect( "select discovery_groupid" " from config" " where 1=1" DB_NODE, DBnode_local("configid")); if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(groupid, row[0]); } else { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined"); return 0; } DBfree_result(result); switch (event->object) { case EVENT_OBJECT_DHOST: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds.dhostid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_DSERVICE: result = DBselect( "select dr.proxy_hostid,ds.ip" " from drules dr,dchecks dc,dservices ds,dservices ds1" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds1.dhostid=ds.dhostid" " and ds1.dserviceid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); break; case EVENT_OBJECT_ZABBIX_ACTIVE: result = DBselect("select proxy_hostid,host from autoreg_host" " where autoreg_hostid=" ZBX_FS_UI64, event->objectid); break; default: return 0; } if (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(proxy_hostid, row[0]); if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object) { char sql[512]; host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN); zbx_snprintf(sql, sizeof(sql), "select hostid,proxy_hostid" " from hosts" " where host='%s'" DB_NODE " order by hostid", host_esc, DBnode_local("hostid")); result2 = DBselectN(sql, 1); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,dns)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',0,'%s')", hostid, proxy_hostid, host_esc, host_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[1]); if (host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); } else /* EVENT_OBJECT_DHOST, EVENT_OBJECT_DSERVICE */ { alarm(CONFIG_TIMEOUT); zbx_gethost_by_ip(row[1], host, sizeof(host)); alarm(0); host_esc = DBdyn_escape_string_len(host, HOST_HOST_LEN); ip_esc = DBdyn_escape_string_len(row[1], HOST_IP_LEN); port = get_discovered_agent_port(event); result2 = DBselect( "select hostid,dns,port,proxy_hostid" " from hosts" " where ip='%s'" DB_NODE, ip_esc, DBnode_local("hostid")); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); /* for host uniqueness purposes */ if ('\0' != *host) { /* by host name */ make_hostname(host); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(host); } else { /* by ip */ make_hostname(row[1]); /* replace not-allowed characters */ host_unique = DBget_unique_hostname_by_sample(row[1]); } host_unique_esc = DBdyn_escape_string(host_unique); DBexecute("insert into hosts (hostid,proxy_hostid,host,useip,ip,dns,port)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",'%s',1,'%s','%s',%d)", hostid, proxy_hostid, host_unique_esc, ip_esc, host_esc, port); zbx_free(host_unique); zbx_free(host_unique_esc); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_STR2UINT64(host_proxy_hostid, row2[3]); if (0 != strcmp(host, row2[1]) || host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set dns='%s',proxy_hostid=" ZBX_FS_UI64 " where hostid=" ZBX_FS_UI64, host_esc, proxy_hostid, hostid); } } DBfree_result(result2); zbx_free(host_esc); zbx_free(ip_esc); } } DBfree_result(result); if (0 != hostid) add_discovered_host_group(hostid, groupid); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return hostid; }
static void add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action, zbx_uint64_t userid, zbx_uint64_t mediatypeid, char *subject, char *message) { DB_RESULT result; DB_ROW row; zbx_uint64_t alertid; int now, severity, medias = 0; char *sendto_esc, *subject_esc, *message_esc, *error_esc; char error[MAX_STRING_LEN]; zabbix_log(LOG_LEVEL_DEBUG, "In add_message_alert()"); /* zabbix_log(LOG_LEVEL_DEBUG,"MESSAGE\n\tuserid : " ZBX_FS_UI64 "\n\tsubject: %s\n\tmessage: %s", userid, subject, message);*/ now = time(NULL); subject_esc = DBdyn_escape_string_len(subject, ALERT_SUBJECT_LEN); message_esc = DBdyn_escape_string(message); if (0 == mediatypeid) { result = DBselect("select mediatypeid,sendto,severity,period from media" " where active=%d and userid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid); } else { result = DBselect("select mediatypeid,sendto,severity,period from media" " where active=%d and userid=" ZBX_FS_UI64 " and mediatypeid=" ZBX_FS_UI64, MEDIA_STATUS_ACTIVE, userid, mediatypeid); } while (NULL != (row = DBfetch(result))) { medias = 1; ZBX_STR2UINT64(mediatypeid, row[0]); severity = atoi(row[2]); zabbix_log( LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]", event->trigger_priority, severity, row[3]); if (((1 << event->trigger_priority) & severity) == 0) { zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (severity)"); continue; } if (check_time_period(row[3], (time_t)NULL) == 0) { zabbix_log( LOG_LEVEL_DEBUG, "Won't send message (period)"); continue; } alertid = DBget_maxid("alerts", "alertid"); sendto_esc = DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN); DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock" ",mediatypeid,sendto,subject,message,status,alerttype,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d" "," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)", alertid, action->actionid, event->eventid, userid, now, mediatypeid, sendto_esc, subject_esc, message_esc, ALERT_STATUS_NOT_SENT, ALERT_TYPE_MESSAGE, escalation->esc_step); zbx_free(sendto_esc); } DBfree_result(result); if (0 == medias) { zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"", zbx_user_string(userid)); alertid = DBget_maxid("alerts", "alertid"); error_esc = DBdyn_escape_string(error); DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock" ",subject,message,status,alerttype,error,esc_step)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d" ",'%s','%s',%d,%d,'%s',%d)", alertid, action->actionid, event->eventid, userid, ALERT_MAX_RETRIES, now, subject_esc, message_esc, ALERT_STATUS_FAILED, ALERT_TYPE_MESSAGE, error_esc, escalation->esc_step); zbx_free(error_esc); } zbx_free(subject_esc); zbx_free(message_esc); }
/****************************************************************************** * * * Function: calculate_checksums * * * * Purpose: calculate check sums of configuration data * * * * Parameters: * * * * Return value: SUCCESS - calculated succesfully * * FAIL - an error occured * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static int calculate_checksums() { char *sql = NULL; int sql_allocated, sql_offset; int i = 0; int j; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; int nodeid; int now; zabbix_log( LOG_LEVEL_DEBUG, "In calculate_checksums"); DBexecute("delete from node_cksum where cksumtype=%d", NODE_CKSUM_TYPE_NEW); /* Select all nodes */ result =DBselect("select nodeid from nodes"); while((row=DBfetch(result))) { sql_allocated=64*1024; sql_offset=0; sql=zbx_malloc(sql, sql_allocated); now = time(NULL); nodeid = atoi(row[0]); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "select 'table ','field ',itemid, '012345678901234' from items where 1=0\n"); for(i=0; tables[i].table!=0; i++) { /* zabbix_log( LOG_LEVEL_WARNING, "In calculate_checksums2 [%s]", tables[i].table ); */ /* Do not sync some of tables */ if( (tables[i].flags & ZBX_SYNC) ==0) continue; #ifdef HAVE_MYSQL zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4096, "union all select '%s','%s',%s,md5(concat(", tables[i].table, tables[i].recid, tables[i].recid); #else zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4096, "union all select '%s','%s',%s,md5(", tables[i].table, tables[i].recid, tables[i].recid); #endif j=0; while(tables[i].fields[j].name != 0) { if( (tables[i].fields[j].flags & ZBX_SYNC) ==0) { j++; continue; } #ifdef HAVE_MYSQL zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "coalesce(%s,'1234567890'),", tables[i].fields[j].name); #else if(tables[i].fields[j].type == ZBX_TYPE_BLOB) /* postgresql is not work: coalesce(blob,'1234567890')||coalesce(varchar,'1234567890') */ { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "md5(coalesce(%s,'1234567890'))||", tables[i].fields[j].name); } else { zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "coalesce(%s,'1234567890')||", tables[i].fields[j].name); } #endif j++; } #ifdef HAVE_MYSQL if(j>0) sql_offset--; /* Remove last */ #else if(j>0) sql_offset-=2; /* Remove last */ #endif /* select table,recid,md5(fields) from table union all ... */ #ifdef HAVE_MYSQL zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4096, ")) from %s where %s>=" ZBX_FS_UI64 " and %s<=" ZBX_FS_UI64 "\n", tables[i].table, tables[i].recid, (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)nodeid, tables[i].recid, (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)nodeid+__UINT64_C(99999999999999)); #else zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 4096, ") from %s where %s>=" ZBX_FS_UI64 " and %s<=" ZBX_FS_UI64 "\n", tables[i].table, tables[i].recid, (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)nodeid, tables[i].recid, (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)nodeid+__UINT64_C(99999999999999)); #endif } /* zabbix_log( LOG_LEVEL_WARNING, "SQL DUMP [%s]", sql);*/ result2 =DBselect("%s",sql); /* zabbix_log( LOG_LEVEL_WARNING, "Selected records in %d seconds", time(NULL)-now);*/ now = time(NULL); i=0; while((row2=DBfetch(result2))) { DBexecute("insert into node_cksum (cksumid,nodeid,tablename,fieldname,recordid,cksumtype,cksum) "\ "values (" ZBX_FS_UI64 ",%d,'%s','%s',%s,%d,'%s')", /* DBget_nextid("node_cksum","cksumid"),*/ DBget_maxid("node_cksum","cksumid"), nodeid, row2[0], row2[1], row2[2], NODE_CKSUM_TYPE_NEW, row2[3]); i++; } DBfree_result(result2); zbx_free(sql); } DBfree_result(result); return SUCCEED; }
/****************************************************************************** * * * Function: register_service * * * * Purpose: register service if one does not exist * * * * Parameters: host ip address * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: * * * ******************************************************************************/ static void register_service(DB_DSERVICE *service,DB_DRULE *rule,DB_DCHECK *check,zbx_uint64_t dhostid,char *ip,int port) { DB_RESULT result; DB_ROW row; char value_esc[MAX_STRING_LEN]; char key_esc[MAX_STRING_LEN]; assert(service); assert(rule); assert(check); assert(ip); zabbix_log(LOG_LEVEL_DEBUG, "In register_service(ip:%s,port:%d)", ip, port); DBescape_string(check->key_, key_esc, sizeof(key_esc)-1); result = DBselect("select dserviceid,dhostid,type,port,status,lastup,lastdown,value,key_ from dservices where dhostid=" ZBX_FS_UI64 " and type=%d and port=%d and key_='%s'", dhostid, check->type, port, key_esc); row=DBfetch(result); if(!row || DBis_null(row[0])==SUCCEED) { /* Add host only if service is up */ if(check->status == DOBJECT_STATUS_UP) { zabbix_log(LOG_LEVEL_DEBUG, "New service discovered on port %d", port); service->dserviceid = DBget_maxid("dservices","dserviceid"); service->dhostid = dhostid; service->type = check->type; service->port = port; service->status = DOBJECT_STATUS_UP; service->lastup = 0; service->lastdown = 0; strscpy(service->value, check->value); strscpy(service->key_, check->key_); DBescape_string(service->value, value_esc, sizeof(value_esc)-1); DBescape_string(service->key_, key_esc, sizeof(key_esc)-1); DBexecute("insert into dservices (dhostid,dserviceid,type,port,status,value,key_) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d,%d,'%s','%s')", service->dhostid, service->dserviceid, check->type, service->port, service->status, value_esc, key_esc); } } else { zabbix_log(LOG_LEVEL_DEBUG, "Service is already in database"); ZBX_STR2UINT64(service->dserviceid, row[0]); ZBX_STR2UINT64(service->dhostid, row[1]); service->type = atoi(row[2]); service->port = atoi(row[3]); service->status = atoi(row[4]); service->lastup = atoi(row[5]); service->lastdown = atoi(row[6]); strscpy(service->value,row[7]); strscpy(service->key_,row[8]); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End register_service()"); }
/****************************************************************************** * * * Function: DCflush_nextchecks * * * * Purpose: add item nextcheck to the array * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev, Dmitry Borovikov * * * * Comments: * * * ******************************************************************************/ void DCflush_nextchecks() { const char *__function_name = "DCflush_nextchecks"; int i, sql_offset = 0, sql_allocated = 4096; char *sql = NULL; DB_RESULT result; DB_ROW row; zbx_uint64_t triggerid; zbx_uint64_t itemid; zbx_uint64_t events_maxid = 0; char *error_msg_esc = NULL; char *sql_select = NULL; int sql_select_offset = 0, sql_select_allocated = 512; /* a crutch for the function `DBadd_condition_alloc' */ zbx_uint64_t *ids = NULL; int ids_allocated = 0, ids_num = 0; zbx_uint64_t *triggerids = NULL; int triggerids_allocated = 0, triggerids_num = 0; struct event_objectid_clock *events = NULL; int events_num = 0, events_allocated = 32; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); if (nextcheck_num == 0) return; sql = zbx_malloc(sql, sql_allocated); DBbegin(); #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n"); #endif /* dealing with items */ for (i = 0; i < nextcheck_num; i++) { if (NULL == nextchecks[i].error_msg) continue; uint64_array_add(&ids, &ids_allocated, &ids_num, nextchecks[i].itemid, 64); error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update items set status=%d,lastclock=%d,error='%s' where itemid=" ZBX_FS_UI64 ";\n", ITEM_STATUS_NOTSUPPORTED, (int)nextchecks[i].now, error_msg_esc, nextchecks[i].itemid); zbx_free(error_msg_esc); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } /* dealing with notsupported items */ if (ids_num > 0) { sql_select = zbx_malloc(sql_select, sql_select_allocated); events = zbx_malloc(events, events_allocated * sizeof(struct event_objectid_clock)); /* preparing triggers */ zbx_snprintf_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, 256, "select t.triggerid,i.itemid" " from triggers t,functions f,items i" " where t.triggerid=f.triggerid" " and f.itemid=i.itemid" " and t.status in (%d)" " and t.value not in (%d)" " and", TRIGGER_STATUS_ENABLED, TRIGGER_VALUE_UNKNOWN); DBadd_condition_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, "i.itemid", ids, ids_num); result = DBselect("%s", sql_select); zbx_free(sql_select); /* processing triggers */ while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(triggerid, row[0]); ZBX_STR2UINT64(itemid, row[1]); /* do not generate multiple unknown events for a trigger */ if (SUCCEED == uint64_array_exists(triggerids, triggerids_num, triggerid)) continue; uint64_array_add(&triggerids, &triggerids_allocated, &triggerids_num, triggerid, 64); /* index `i' will surely contain necessary itemid */ i = get_nearestindex(nextchecks, sizeof(ZBX_DC_NEXTCHECK), nextcheck_num, itemid); if (i == nextcheck_num || nextchecks[i].itemid != itemid) { THIS_SHOULD_NEVER_HAPPEN; continue; } error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, TRIGGER_ERROR_LEN); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc), "update triggers set value=%d,lastchange=%d,error='%s' where triggerid=" ZBX_FS_UI64";\n", TRIGGER_VALUE_UNKNOWN, nextchecks[i].now, error_msg_esc, triggerid); zbx_free(error_msg_esc); if (events_num == events_allocated) { events_allocated += 32; events = zbx_realloc(events, events_allocated * sizeof(struct event_objectid_clock)); } events[events_num].objectid = triggerid; events[events_num].clock = nextchecks[i].now; events_num++; DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } DBfree_result(result); /* dealing with events */ for (i = 0; i < events_num; i++) { events_maxid = DBget_maxid("events"); zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 256, "insert into events (eventid,source,object,objectid,clock,value) " "values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d);\n", events_maxid, EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, events[i].objectid, events[i].clock, TRIGGER_VALUE_UNKNOWN); DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset); } zbx_free(events); } #ifdef HAVE_ORACLE zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n"); #endif if (sql_offset > 16) /* In ORACLE always present begin..end; */ DBexecute("%s", sql); zbx_free(sql); zbx_free(ids); zbx_free(triggerids); DCrelease_nextchecks(); DBcommit(); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: discovery_register_service * * * * Purpose: register service if one does not exist * * * * Parameters: host ip address * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static void discovery_register_service(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, DB_DSERVICE *dservice, const char *ip, const char *dns, int port, int status, int now) { const char *__function_name = "discovery_register_service"; DB_RESULT result; DB_ROW row; char *key_esc, *ip_esc, *dns_esc; zbx_uint64_t dhostid; zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s' port:%d key:'%s'", __function_name, ip, port, dcheck->key_); key_esc = DBdyn_escape_string_len(dcheck->key_, DSERVICE_KEY_LEN); ip_esc = DBdyn_escape_string_len(ip, INTERFACE_IP_LEN); result = DBselect( "select dserviceid,dhostid,status,lastup,lastdown,value,dns" " from dservices" " where dcheckid=" ZBX_FS_UI64 " and type=%d" " and key_" ZBX_SQL_STRCMP " and ip" ZBX_SQL_STRCMP " and port=%d", dcheck->dcheckid, dcheck->type, ZBX_SQL_STRVAL_EQ(key_esc), ZBX_SQL_STRVAL_EQ(ip_esc), port); if (NULL == (row = DBfetch(result))) { if (DOBJECT_STATUS_UP == status) /* add host only if service is up */ { zabbix_log(LOG_LEVEL_DEBUG, "new service discovered on port %d", port); dservice->dserviceid = DBget_maxid("dservices"); dservice->status = DOBJECT_STATUS_DOWN; dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN); DBexecute("insert into dservices (dserviceid,dhostid,dcheckid,type,key_,ip,dns,port,status)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,'%s','%s','%s',%d,%d)", dservice->dserviceid, dhost->dhostid, dcheck->dcheckid, dcheck->type, key_esc, ip_esc, dns_esc, port, dservice->status); zbx_free(dns_esc); } } else { zabbix_log(LOG_LEVEL_DEBUG, "service is already in database"); ZBX_STR2UINT64(dservice->dserviceid, row[0]); ZBX_STR2UINT64(dhostid, row[1]); dservice->status = atoi(row[2]); dservice->lastup = atoi(row[3]); dservice->lastdown = atoi(row[4]); strscpy(dservice->value, row[5]); if (dhostid != dhost->dhostid) { DBexecute("update dservices" " set dhostid=" ZBX_FS_UI64 " where dhostid=" ZBX_FS_UI64, dhost->dhostid, dhostid); DBexecute("delete from dhosts" " where dhostid=" ZBX_FS_UI64, dhostid); } if (0 != strcmp(row[6], dns)) { dns_esc = DBdyn_escape_string_len(dns, INTERFACE_DNS_LEN); DBexecute("update dservices" " set dns='%s'" " where dserviceid=" ZBX_FS_UI64, dns_esc, dservice->dserviceid); zbx_free(dns_esc); } } DBfree_result(result); zbx_free(ip_esc); zbx_free(key_esc); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: discovery_register_host * * * * Purpose: register host if one does not exist * * * * Parameters: host ip address * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static void discovery_register_host(DB_DRULE *drule, DB_DCHECK *dcheck, DB_DHOST *dhost, const char *ip, int status, const char *value) { const char *__function_name = "discovery_register_host"; DB_RESULT result; DB_ROW row; zabbix_log(LOG_LEVEL_DEBUG, "In %s() ip:'%s' status:%d value:'%s'", __function_name, ip, status, value); if (drule->unique_dcheckid == dcheck->dcheckid) { result = discovery_get_dhost_by_value(dcheck->dcheckid, value); if (NULL == (row = DBfetch(result))) { DBfree_result(result); result = discovery_get_dhost_by_ip(drule->druleid, ip); row = DBfetch(result); } } else { result = discovery_get_dhost_by_ip(drule->druleid, ip); row = DBfetch(result); } if (NULL == row) { if (DOBJECT_STATUS_UP == status) /* add host only if service is up */ { zabbix_log(LOG_LEVEL_DEBUG, "new host discovered at %s", ip); dhost->dhostid = DBget_maxid("dhosts"); dhost->status = DOBJECT_STATUS_DOWN; dhost->lastup = 0; dhost->lastdown = 0; DBexecute("insert into dhosts (dhostid,druleid)" " values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ")", dhost->dhostid, drule->druleid); } } else { zabbix_log(LOG_LEVEL_DEBUG, "host at %s is already in database", ip); ZBX_STR2UINT64(dhost->dhostid, row[0]); dhost->status = atoi(row[1]); dhost->lastup = atoi(row[2]); dhost->lastdown = atoi(row[3]); if (0 == drule->unique_dcheckid) discovery_separate_host(drule, dhost, ip); } DBfree_result(result); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); }
/****************************************************************************** * * * Function: add_discovered_host * * * * Purpose: add discovered host if it was not added already * * * * Parameters: dhostid - discovered host id * * * * Return value: hostid - new/existing hostid * * * * Author: Alexei Vladishev * * * ******************************************************************************/ static zbx_uint64_t add_discovered_host(const DB_EVENT *event) { const char *__function_name = "add_discovered_host"; DB_RESULT result; DB_RESULT result2; DB_ROW row; DB_ROW row2; zbx_uint64_t dhostid, hostid = 0, proxy_hostid; char *host = NULL, *host_esc, *host_unique; unsigned short port; zbx_uint64_t groupid; zbx_vector_uint64_t groupids; unsigned char svc_type, interface_type; zabbix_log(LOG_LEVEL_DEBUG, "In %s() eventid:" ZBX_FS_UI64, __function_name, event->eventid); zbx_vector_uint64_create(&groupids); if (0 == *(zbx_uint64_t *)DCconfig_get_config_data(&groupid, CONFIG_DISCOVERY_GROUPID)) { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host: group for discovered hosts is not defined"); goto clean; } zbx_vector_uint64_append(&groupids, groupid); if (EVENT_OBJECT_DHOST == event->object || EVENT_OBJECT_DSERVICE == event->object) { if (EVENT_OBJECT_DHOST == event->object) { result = DBselect( "select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type" " from drules dr,dchecks dc,dservices ds" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds.dhostid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); } else { result = DBselect( "select ds.dhostid,dr.proxy_hostid,ds.ip,ds.dns,ds.port,ds.type" " from drules dr,dchecks dc,dservices ds,dservices ds1" " where dc.druleid=dr.druleid" " and ds.dcheckid=dc.dcheckid" " and ds1.dhostid=ds.dhostid" " and ds1.dserviceid=" ZBX_FS_UI64 " order by ds.dserviceid", event->objectid); } while (NULL != (row = DBfetch(result))) { ZBX_STR2UINT64(dhostid, row[0]); ZBX_DBROW2UINT64(proxy_hostid, row[1]); svc_type = (unsigned char)atoi(row[5]); switch (svc_type) { case SVC_AGENT: port = (unsigned short)atoi(row[4]); interface_type = INTERFACE_TYPE_AGENT; break; case SVC_SNMPv1: case SVC_SNMPv2c: case SVC_SNMPv3: port = (unsigned short)atoi(row[4]); interface_type = INTERFACE_TYPE_SNMP; break; default: port = ZBX_DEFAULT_AGENT_PORT; interface_type = INTERFACE_TYPE_AGENT; } if (0 == hostid) { result2 = DBselect( "select distinct h.hostid" " from hosts h,interface i,dservices ds" " where h.hostid=i.hostid" " and i.ip=ds.ip" " and h.proxy_hostid%s" " and ds.dhostid=" ZBX_FS_UI64 ZBX_SQL_NODE " order by h.hostid", DBsql_id_cmp(proxy_hostid), dhostid, DBand_node_local("h.hostid")); if (NULL != (row2 = DBfetch(result2))) ZBX_STR2UINT64(hostid, row2[0]); DBfree_result(result2); } if (0 == hostid) { hostid = DBget_maxid("hosts"); /* for host uniqueness purposes */ host = zbx_strdup(host, '\0' != *row[3] ? row[3] : row[2]); make_hostname(host); /* replace not-allowed symbols */ host_unique = DBget_unique_hostname_by_sample(host); host_esc = DBdyn_escape_string(host_unique); zbx_free(host); DBexecute("insert into hosts" " (hostid,proxy_hostid,host,name)" " values" " (" ZBX_FS_UI64 ",%s,'%s','%s')", hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc); DBadd_interface(hostid, interface_type, 1, row[2], row[3], port); zbx_free(host_unique); zbx_free(host_esc); add_discovered_host_groups(hostid, &groupids); } else { DBadd_interface(hostid, interface_type, 1, row[2], row[3], port); } } DBfree_result(result); } else if (EVENT_OBJECT_ZABBIX_ACTIVE == event->object) { result = DBselect( "select proxy_hostid,host,listen_ip,listen_dns,listen_port" " from autoreg_host" " where autoreg_hostid=" ZBX_FS_UI64, event->objectid); if (NULL != (row = DBfetch(result))) { char *sql = NULL; zbx_uint64_t host_proxy_hostid; ZBX_DBROW2UINT64(proxy_hostid, row[0]); host_esc = DBdyn_escape_string_len(row[1], HOST_HOST_LEN); port = (unsigned short)atoi(row[4]); result2 = DBselect( "select null" " from hosts" " where host='%s'" " and status=%d", host_esc, HOST_STATUS_TEMPLATE); if (NULL != (row2 = DBfetch(result2))) { zabbix_log(LOG_LEVEL_WARNING, "cannot add discovered host \"%s\":" " template with the same name already exists", row[1]); DBfree_result(result2); goto out; } DBfree_result(result2); sql = zbx_dsprintf(sql, "select hostid,proxy_hostid" " from hosts" " where host='%s'" " and flags<>%d" " and status in (%d,%d)" ZBX_SQL_NODE " order by hostid", host_esc, ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, DBand_node_local("hostid")); result2 = DBselectN(sql, 1); zbx_free(sql); if (NULL == (row2 = DBfetch(result2))) { hostid = DBget_maxid("hosts"); DBexecute("insert into hosts" " (hostid,proxy_hostid,host,name)" " values" " (" ZBX_FS_UI64 ",%s,'%s','%s')", hostid, DBsql_id_ins(proxy_hostid), host_esc, host_esc); DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port); add_discovered_host_groups(hostid, &groupids); } else { ZBX_STR2UINT64(hostid, row2[0]); ZBX_DBROW2UINT64(host_proxy_hostid, row2[1]); if (host_proxy_hostid != proxy_hostid) { DBexecute("update hosts" " set proxy_hostid=%s" " where hostid=" ZBX_FS_UI64, DBsql_id_ins(proxy_hostid), hostid); } DBadd_interface(hostid, INTERFACE_TYPE_AGENT, 1, row[2], row[3], port); } DBfree_result(result2); out: zbx_free(host_esc); } DBfree_result(result); } clean: zbx_vector_uint64_destroy(&groupids); zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name); return hostid; }