diff options
author | alex <alex@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2006-09-14 11:06:27 +0000 |
---|---|---|
committer | alex <alex@97f52cf1-0a1b-0410-bd0e-c28be96e8082> | 2006-09-14 11:06:27 +0000 |
commit | 8755f9643aba3cffc5320321618fbe8e7b78b73b (patch) | |
tree | 61f79790fee2222b1d3c5c3cd3faf09c9de8f168 /src | |
parent | 220a18752f8fefdd0af90ccd17cc045c2e6ae1a6 (diff) | |
download | zabbix-8755f9643aba3cffc5320321618fbe8e7b78b73b.tar.gz zabbix-8755f9643aba3cffc5320321618fbe8e7b78b73b.tar.xz zabbix-8755f9643aba3cffc5320321618fbe8e7b78b73b.zip |
Initial integration of distributed monitoring.
Changes 3196:HEAD of branches/distributed
git-svn-id: svn://svn.zabbix.com/trunk@3306 97f52cf1-0a1b-0410-bd0e-c28be96e8082
Diffstat (limited to 'src')
32 files changed, 1688 insertions, 43 deletions
diff --git a/src/zabbix_server/Makefile.am b/src/zabbix_server/Makefile.am index beb9dd06..a4e0b907 100644 --- a/src/zabbix_server/Makefile.am +++ b/src/zabbix_server/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = alerter housekeeper pinger poller timer trapper +SUBDIRS = alerter housekeeper pinger poller timer trapper nodewatcher nodesender INCLUDES=-I@top_srcdir@/include @MYSQL_INCLUDE@ @ORACLE_INCLUDE@ @SNMP_INCLUDE@ @PGSQL_INCLUDE@ bin_PROGRAMS = zabbix_server @@ -7,7 +7,8 @@ zabbix_server_CPPFLAGS = -DZABBIX_DAEMON zabbix_server_LDADD = ../libs/zbxsysinfo/libzbxsysinfo.a ../libs/zbxsysinfo/@ARCH@/libzbxsysinfo2.a \ ../libs/zbxlog/libzbxlog.a ../libs/zbxnix/libzbxnix.a ../libs/zbxsys/libzbxsys.a ../libs/zbxconf/libzbxconf.a \ ../libs/zbxnet/libzbxnet.a pinger/libzbxpinger.a poller/libzbxpoller.a housekeeper/libzbxhousekeeper.a \ -alerter/libzbxalerter.a timer/libzbxtimer.a trapper/libzbxtrapper.a ../libs/zbxemail/libzbxemail.a \ +alerter/libzbxalerter.a timer/libzbxtimer.a trapper/libzbxtrapper.a nodewatcher/libzbxnodewatcher.a \ +nodesender/libzbxnodesender.a ../libs/zbxemail/libzbxemail.a \ ../libs/zbxsms/libzbxsms.a ../libs/zbxdbhigh/libzbxdbhigh.a ../libs/zbxcommon/libzbxcommon.a \ ../libs/zbxcrypto/libzbxcrypto.a @MYSQL_LIBS@ @PGSQL_LIBS@ @ORACLE_LIBS@ @LDAP_LIBS@ @SNMP_LIBS@ zabbix_server_LDFLAGS=@MYSQL_LFLAGS@ @PGSQL_LFLAGS@ @ORACLE_LFLAGS@ @LDAP_LFLAGS@ @SNMP_LFLAGS@ diff --git a/src/zabbix_server/actions.c b/src/zabbix_server/actions.c index 86892f4c..bcc0a51d 100644 --- a/src/zabbix_server/actions.c +++ b/src/zabbix_server/actions.c @@ -234,7 +234,8 @@ static void run_remote_command(char* host_name, char* command) zabbix_log(LOG_LEVEL_DEBUG, "run_remote_command START [hostname: '%s', command: '%s']", host_name, command); - result = DBselect("select distinct host,ip,useip,port from hosts where host='%s'", host_name); + result = DBselect("select distinct host,ip,useip,port from hosts where host='%s' and " ZBX_COND_NODEID, + host_name, LOCAL_NODE("hostid")); row = DBfetch(result); if(row) { @@ -380,7 +381,7 @@ static int get_next_command(char** command_list, char** alias, int* is_group, ch if(alias == '\0' || command == '\0') continue; if(is_group) { - result = DBselect("select distinct h.host from hosts_groups hg,hosts h, groups g where hg.hostid=h.hostid and hg.groupid=g.groupid and g.name='%s'", alias); + result = DBselect("select distinct h.host from hosts_groups hg,hosts h, groups g where hg.hostid=h.hostid and hg.groupid=g.groupid and g.name='%s' and" ZBX_COND_NODEID, alias, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { run_remote_command(row[0], command); @@ -683,7 +684,7 @@ void apply_actions(DB_TRIGGER *trigger,int alarmid,int trigger_value) /* zbx_snprintf(sql,sizeof(sql),"select actionid,userid,delay,subject,message,recipient,maxrepeats,repeatdelay,scripts,actiontype from actions where nextcheck<=%d and status=%d", now, ACTION_STATUS_ACTIVE);*/ /* No support of action delay anymore */ - result = DBselect("select actionid,userid,subject,message,recipient,maxrepeats,repeatdelay,scripts,actiontype from actions where status=%d", ACTION_STATUS_ACTIVE); + result = DBselect("select actionid,userid,subject,message,recipient,maxrepeats,repeatdelay,scripts,actiontype from actions where status=%d and" ZBX_COND_NODEID, ACTION_STATUS_ACTIVE, LOCAL_NODE("actionid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/actions.h b/src/zabbix_server/actions.h index 2d9becd7..983d7ee7 100644 --- a/src/zabbix_server/actions.h +++ b/src/zabbix_server/actions.h @@ -24,6 +24,8 @@ #include "common.h" #include "db.h" +extern int CONFIG_NODEID; + void apply_actions(DB_TRIGGER *trigger,int alarmid,int trigger_value); #endif diff --git a/src/zabbix_server/alerter/alerter.c b/src/zabbix_server/alerter/alerter.c index 472fba96..7b22b115 100644 --- a/src/zabbix_server/alerter/alerter.c +++ b/src/zabbix_server/alerter/alerter.c @@ -177,7 +177,7 @@ int main_alerter_loop() now = time(NULL); /* zbx_snprintf(sql,sizeof(sql),"select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,a.retries,mt.mediatypeid,mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path from alerts a,media_type mt where a.status=0 and a.retries<3 and a.mediatypeid=mt.mediatypeid order by a.clock"); */ - result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,a.retries,mt.mediatypeid,mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path,a.delay,mt.gsm_modem from alerts a,media_type mt where a.status=%d and a.retries<3 and (a.repeats<a.maxrepeats or a.maxrepeats=0) and a.nextcheck<=%d and a.mediatypeid=mt.mediatypeid order by a.clock", ALERT_STATUS_NOT_SENT, now); + result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,a.retries,mt.mediatypeid,mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path,a.delay,mt.gsm_modem from alerts a,media_type mt where a.status=%d and a.retries<3 and (a.repeats<a.maxrepeats or a.maxrepeats=0) and a.nextcheck<=%d and a.mediatypeid=mt.mediatypeid and " ZBX_COND_NODEID " order by a.clock", ALERT_STATUS_NOT_SENT, now, LOCAL_NODE("mt.mediatypeid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/alerter/alerter.h b/src/zabbix_server/alerter/alerter.h index 5fba1229..1b2f69d7 100644 --- a/src/zabbix_server/alerter/alerter.h +++ b/src/zabbix_server/alerter/alerter.h @@ -28,6 +28,8 @@ extern char *CONFIG_DBPASSWORD; extern char *CONFIG_DBSOCKET; extern char *CONFIG_ALERT_SCRIPTS_PATH; +extern int CONFIG_NODEID; + extern void signal_handler( int sig ); int main_alerter_loop(); diff --git a/src/zabbix_server/evalfunc.c b/src/zabbix_server/evalfunc.c index 679e92b0..29b7a1d6 100644 --- a/src/zabbix_server/evalfunc.c +++ b/src/zabbix_server/evalfunc.c @@ -1263,7 +1263,7 @@ int evaluate_FUNCTION2(char *value,char *host,char *key,char *function,char *par zabbix_log(LOG_LEVEL_DEBUG, "In evaluate_FUNCTION2()" ); - result = DBselect("select %s where h.host='%s' and h.hostid=i.hostid and i.key_='%s'", ZBX_SQL_ITEM_SELECT, host, key ); + result = DBselect("select %s where h.host='%s' and h.hostid=i.hostid and i.key_='%s'" ZBX_COND_NODEID, ZBX_SQL_ITEM_SELECT, host, key, LOCAL_NODE("h.hostid")); row = DBfetch(result); diff --git a/src/zabbix_server/evalfunc.h b/src/zabbix_server/evalfunc.h index 348a61f0..eca3e118 100644 --- a/src/zabbix_server/evalfunc.h +++ b/src/zabbix_server/evalfunc.h @@ -30,6 +30,7 @@ #define ZBX_FLAG_SEC 0 #define ZBX_FLAG_VALUES 1 +extern int CONFIG_NODEID; int evaluate_FUNCTION(char *value,DB_ITEM *item,char *function,char *parameter); int evaluate_FUNCTION2(char *value,char *host,char *key,char *function,char *parameter); diff --git a/src/zabbix_server/functions.c b/src/zabbix_server/functions.c index 2ff3c25c..2262eb7e 100644 --- a/src/zabbix_server/functions.c +++ b/src/zabbix_server/functions.c @@ -412,7 +412,7 @@ int process_data(int sockfd,char *server,char *key,char *value,char *lastlogsize DBescape_string(server, server_esc, MAX_STRING_LEN); DBescape_string(key, key_esc, MAX_STRING_LEN); - result = DBselect("select %s where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type in (%d,%d)", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, server_esc, key_esc, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE); + result = DBselect("select %s where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type in (%d,%d) and" ZBX_COND_NODEID, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, server_esc, key_esc, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, LOCAL_NODE("h.hostid")); row=DBfetch(result); @@ -425,7 +425,7 @@ int process_data(int sockfd,char *server,char *key,char *value,char *lastlogsize DBfree_result(result); /* Same SQL */ - result = DBselect("select %s where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type in (%d,%d)", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, server_esc, key_esc, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE); + result = DBselect("select %s where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type in (%d,%d) and" ZBX_COND_NODEID, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, server_esc, key_esc, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, LOCAL_NODE("hostid")); row = DBfetch(result); if(!row) { diff --git a/src/zabbix_server/nodesender/Makefile.am b/src/zabbix_server/nodesender/Makefile.am new file mode 100644 index 00000000..53ab135c --- /dev/null +++ b/src/zabbix_server/nodesender/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS= +INCLUDES=-I@top_srcdir@/include @MYSQL_INCLUDE@ @ORACLE_INCLUDE@ +lib_LIBRARIES=libzbxnodesender.a +libzbxnodesender_a_SOURCES=nodesender.c diff --git a/src/zabbix_server/nodesender/nodesender.c b/src/zabbix_server/nodesender/nodesender.c new file mode 100644 index 00000000..8f3f1c61 --- /dev/null +++ b/src/zabbix_server/nodesender/nodesender.c @@ -0,0 +1,589 @@ +/* +** ZABBIX +** Copyright (C) 2000-2006 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include <sys/wait.h> + +#include <string.h> + +#ifdef HAVE_NETDB_H + #include <netdb.h> +#endif + +/* Required for getpwuid */ +#include <pwd.h> + +#include <signal.h> +#include <errno.h> + +#include <time.h> + +#include "common.h" +#include "cfg.h" +#include "db.h" +#include "log.h" +#include "zlog.h" + +#include "dbsync.h" +#include "nodesender.h" + +#define ZBX_NODE_MASTER 0 +#define ZBX_NODE_SLAVE 1 + +extern int CONFIG_NODEID; + +/****************************************************************************** + * * + * Function: send_to_node * + * * + * Purpose: send configuration changes to required node * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int send_to_node(int dest_nodeid, int nodeid, char *xml) +{ + int i,s; + char answer[MAX_STRING_LEN]; + struct hostent *hp; + + struct sockaddr_in myaddr_in; + struct sockaddr_in servaddr_in; + char ip[MAX_STRING_LEN]; + int port; + int ret = FAIL; + int written; + + DB_RESULT result; + DB_ROW row; + +// zabbix_log( LOG_LEVEL_WARNING, "In send_to_node (%d,%d)", nodeid, strlen(xml)); +// zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Sending data of node %d to node %d", CONFIG_NODEID, nodeid, dest_nodeid); + + result = DBselect("select ip, port from nodes where nodeid=%d", dest_nodeid); + row = DBfetch(result); + if(!row) + { + DBfree_result(result); + zabbix_log( LOG_LEVEL_WARNING, "Node [%d] in unknown", dest_nodeid); + return FAIL; + } + strncpy(ip,row[0],sizeof(ip)); + port=atoi(row[1]); + DBfree_result(result); + +// zabbix_log( LOG_LEVEL_WARNING, "In send_to_node IP (%s:%d)", ip, port); + servaddr_in.sin_family=AF_INET; + hp=gethostbyname(ip); + + if(hp==NULL) + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot resolve [%s] for node [%d]", ip, dest_nodeid); + return FAIL; + } + + servaddr_in.sin_addr.s_addr=((struct in_addr *)(hp->h_addr))->s_addr; + + servaddr_in.sin_port=htons(port); + + s=socket(AF_INET,SOCK_STREAM,0); + if(s == -1) + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot create socket [%s] for node [%d]", ip, dest_nodeid); + return FAIL; + } + + myaddr_in.sin_family = AF_INET; + myaddr_in.sin_port=0; + myaddr_in.sin_addr.s_addr=INADDR_ANY; + + if( connect(s,(struct sockaddr *)&servaddr_in,sizeof(struct sockaddr_in)) == -1 ) + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot connect [%s] to node [%d]", ip, dest_nodeid); + close(s); + return FAIL; + } + + written = 0; + + while(written<strlen(xml)) + { + i=write(s, xml+written,strlen(xml)-written); + if(i == -1) + { + zabbix_log( LOG_LEVEL_WARNING, "Error writing to node [%d] [%s]", dest_nodeid, strerror(errno)); + close(s); + return FAIL; + } + written+=i; +// zabbix_log( LOG_LEVEL_WARNING, "Wrote %d of %d bytes to node %d", written, strlen(xml), nodeid); + } + i=sizeof(struct sockaddr_in); +/* i=recvfrom(s,result,MAX_STRING_LEN-1,0,(struct sockaddr *)&servaddr_in,(socklen_t *)&i);*/ + i=read(s,answer,MAX_STRING_LEN-1); + if(i==-1) + { + zabbix_log( LOG_LEVEL_WARNING, "Error reading from node [%d]", dest_nodeid); + close(s); + return FAIL; + } + + answer[i-1]=0; + + if(strcmp(answer,"OK") == 0) + { + ret = SUCCEED; + } + + if( close(s)!=0 ) + { + } + + return ret; +} + +/****************************************************************************** + * * + * Function: send_config_data * + * * + * Purpose: send configuration changes to required node * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int send_config_data(int nodeid, int dest_nodeid, int maxlogid, int node_type) +{ + DB_RESULT result; + DB_RESULT result2; + DB_ROW row; + DB_ROW row2; + +#define ZBX_XML_MAX 161024*1024 + char *xml; + char tmp[MAX_STRING_LEN]; + char fields[MAX_STRING_LEN]; + + int i,j; + + xml=malloc(ZBX_XML_MAX); + + xml[0]=0; + +// zabbix_log( LOG_LEVEL_WARNING, "In send_config_data(local:%d,nodeid:%d,dest_node:%d,maxlogid:%d,type:%d)",local_nodeid, nodeid, dest_nodeid,maxlogid,node_type); + + /* Begin work */ + if(node_type == ZBX_NODE_MASTER) + { + result=DBselect("select tablename,recordid,operation from node_configlog where nodeid=%d and sync_master=0 and conflogid<=%d order by tablename,operation", nodeid, maxlogid); + } + else + { + result=DBselect("select tablename,recordid,operation from node_configlog where nodeid=%d and sync_slave=0 and conflogid<=%d order by tablename,operation", nodeid, maxlogid); + } + +// snprintf(tmp,sizeof(tmp),"<Data type='config'>\n<Node id='%d'>\n</Node>\n<Version>1.4</Version>\n<Records>\n", nodeid); + zbx_snprintf(tmp,sizeof(tmp),"Data|%d|%d\n", CONFIG_NODEID, nodeid); + strncat(xml,tmp,ZBX_XML_MAX); + + while((row=DBfetch(result))) + { +// zabbix_log( LOG_LEVEL_WARNING, "Fetched [%s,%s,%s]",row[0],row[1],row[2]); + for(i=0;tables[i].table!=0;i++) + { + if(strcmp(tables[i].table, row[0])==0) break; + } + + /* Found table */ + if(tables[i].table!=0) + { + fields[0]=0; + /* for each field */ + for(j=0;tables[i].fields[j].name!=0;j++) + { + strncat(fields,tables[i].fields[j].name,sizeof(fields)); + strncat(fields,",",sizeof(fields)); + } + if(fields[0]!=0) fields[strlen(fields)-1]=0; + + result2=DBselect("select %s from %s where %s=%s", fields, row[0], tables[i].recid,row[1]); +// zabbix_log( LOG_LEVEL_WARNING,"select %s from %s where %s=%s",fields, row[0], tables[i].recid,row[1]); + row2=DBfetch(result2); + + if(row2) + { + zbx_snprintf(tmp,sizeof(tmp),"%s|%s|%s", + row[0], row[1], row[2]); +// zabbix_log( LOG_LEVEL_WARNING, "TMP [%s]",tmp); + strncat(xml,tmp,ZBX_XML_MAX); + /* for each field */ + for(j=0;tables[i].fields[j].name!=0;j++) + { +// snprintf(tmp,sizeof(tmp),"<Record table='%s' field='%s' op='%s' recid='%s'>%s<Record>\n", +// row[0], tables[i].fields[j].name, row[2], row[1], row2[j]); +// // Fieldname, type, value + if(DBis_null(row2[j]) == SUCCEED) + { +// zabbix_log( LOG_LEVEL_WARNING, "Field name [%s] [%s]",tables[i].fields[j].name,row2[j]); +// if(strcmp("snmpv3_securityname",tables[i].fields[j].name)==0) +// { +// zabbix_log( LOG_LEVEL_WARNING, "snmpv3_securityname [%s]",row2[j]); +// } + zbx_snprintf(tmp,sizeof(tmp),"|%s|%d|NULL", + tables[i].fields[j].name,tables[i].fields[j].type); + } + else + { + zbx_snprintf(tmp,sizeof(tmp),"|%s|%d|%s", + tables[i].fields[j].name,tables[i].fields[j].type,row2[j]); +// if(strcmp("snmpv3_securityname",tables[i].fields[j].name)==0) +// { +// zabbix_log( LOG_LEVEL_WARNING, "snmpv3_securityname 2[%s]",row2[j]); +// } + } +// zabbix_log( LOG_LEVEL_WARNING, "TMP [%s]",tmp); + strncat(xml,tmp,ZBX_XML_MAX); + } + strncat(xml,"\n",ZBX_XML_MAX); + + } + else + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot select %s from table [%s]",tables[i].fields[j],row[0]); + } + DBfree_result(result2); + } + else + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot find table [%s]",row[0]); + } + } +// snprintf(tmp,sizeof(tmp),"</Records></Data>\n"); +// strncat(xml,tmp,ZBX_XML_MAX); +// +// zabbix_log( LOG_LEVEL_WARNING, "DATA [%s]",xml); + if(send_to_node(dest_nodeid, nodeid, xml) == SUCCEED) + { + if(node_type == ZBX_NODE_MASTER) + { + DBexecute("update node_configlog set sync_master=1 where nodeid=%d and sync_master=0 and conflogid<=%d", nodeid, maxlogid); + } + else + { + DBexecute("update node_configlog set sync_slave=1 where nodeid=%d and sync_slave=0 and conflogid<=%d", nodeid, maxlogid); + } + } + + DBfree_result(result); + free(xml); + /* Commit */ + + return SUCCEED; +} + +/****************************************************************************** + * * + * Function: get_slave_node * + * * + * Purpose: send configuration changes to required node * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int get_slave_node(int nodeid) +{ + DB_RESULT result; + DB_ROW row; + int ret = 0; + int m; + +// zabbix_log( LOG_LEVEL_WARNING, "In get_slave_node(%d,%d)",local_nodeid, nodeid); + /* Begin work */ + + result = DBselect("select masterid from nodes where nodeid=%d", nodeid); + row = DBfetch(result); + if(row) + { + m = atoi(row[0]); + if(m == CONFIG_NODEID) + { + ret = nodeid; + } + else if(m ==0) + { + ret = m; + } + else ret = get_slave_node(m); + } + DBfree_result(result); + + return ret; +} + +/****************************************************************************** + * * + * Function: get_master_node * + * * + * Purpose: send configuration changes to required node * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int get_master_node(int nodeid) +{ + DB_RESULT result; + DB_ROW row; + int ret = 0; + +// zabbix_log( LOG_LEVEL_WARNING, "In get_master_node(%d,%d)",local_nodeid, nodeid); + /* Begin work */ + + result = DBselect("select masterid from nodes where nodeid=%d", CONFIG_NODEID); + row = DBfetch(result); + if(row) + { + ret = atoi(row[0]); + } + DBfree_result(result); + + return ret; +} + +/****************************************************************************** + * * + * Function: send_config_data * + * * + * Purpose: send configuration changes to required node * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int send_to_master_and_slave(int nodeid) +{ + DB_RESULT result; + DB_ROW row; + int master_nodeid, slave_nodeid; + int master_result, slave_result; + int maxlogid; + +// zabbix_log( LOG_LEVEL_WARNING, "In send_to_master_and_slave(local:%d,node:%d)",local_nodeid, nodeid); + /* Begin work */ + + result = DBselect("select min(conflogid),max(conflogid) from node_configlog where nodeid=%d", nodeid); + + row = DBfetch(result); + + if(DBis_null(row[0]) == SUCCEED) + { +// zabbix_log( LOG_LEVEL_WARNING, "No configuration changes of node %d on node %d", nodeid, local_nodeid); + DBfree_result(result); + return SUCCEED; + } + if(atoi(row[1])-atoi(row[0])>200) + { + maxlogid = atoi(row[0])+200; + } + else + { + maxlogid = atoi(row[1]); + } + DBfree_result(result); + + + /* Send data to master and slave if required */ +// zabbix_log( LOG_LEVEL_WARNING, "Node [%d]", nodeid); +// zabbix_log( LOG_LEVEL_WARNING, "Local node [%d]", local_nodeid); + master_nodeid=get_master_node(nodeid); +// zabbix_log( LOG_LEVEL_WARNING, "Master node [%d]", master_nodeid); + slave_nodeid=get_slave_node(nodeid); +// zabbix_log( LOG_LEVEL_WARNING, "Slave node [%d]", slave_nodeid); + + if(master_nodeid != 0) + { + master_result = send_config_data(nodeid, master_nodeid, maxlogid, ZBX_NODE_MASTER); + } + + if(slave_nodeid != 0) + { + slave_result = send_config_data(nodeid, slave_nodeid, maxlogid, ZBX_NODE_SLAVE); + } + + if( (master_nodeid!=0) && (slave_nodeid != 0)) + { + if((master_result == SUCCEED) && (slave_result == SUCCEED)) + { + DBexecute("delete from node_configlog where nodeid=%d and sync_slave=1 and sync_master=1 and conflogid<=%d", nodeid, maxlogid); +// zabbix_log(LOG_LEVEL_WARNING,"delete from node_configlog where nodeid=%d and sync_slave=1 and sync_master=1 and conflogid<=%d", nodeid, maxlogid); + } + } + + if(master_nodeid!=0) + { + if(master_result == SUCCEED) + { + DBexecute("delete from node_configlog where nodeid=%d and sync_master=1 and conflogid<=%d", nodeid, maxlogid); +// zabbix_log(LOG_LEVEL_WARNING,"delete from node_configlog where nodeid=%d and sync_master=1 and conflogid<=%d", nodeid, maxlogid); + } + } + + if(slave_nodeid!=0) + { + if(slave_result == SUCCEED) + { + DBexecute("delete from node_configlog where nodeid=%d and sync_slave=1 and conflogid<=%d", nodeid, maxlogid); +// zabbix_log(LOG_LEVEL_WARNING,"delete from node_configlog where nodeid=%d and sync_slave=1 and conflogid<=%d", nodeid, maxlogid); + } + } + + return SUCCEED; +} + + +/****************************************************************************** + * * + * Function: process_node * + * * + * Purpose: select all related nodes and send config changes * + * * + * Parameters: * + * * + * Return value: SUCCESS - processed succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int process_node(int nodeid) +{ + DB_RESULT result; + DB_ROW row; + +// zabbix_log( LOG_LEVEL_WARNING, "In process_node(local:%d,node:%d)",local_nodeid, nodeid); + /* Begin work */ + + send_to_master_and_slave(nodeid); + + result = DBselect("select nodeid from nodes where masterid=%d", nodeid); + while((row=DBfetch(result))) + { + process_node(atoi(row[0])); + } + DBfree_result(result); + + return SUCCEED; +} + +/****************************************************************************** + * * + * Function: main_nodesender_loop * + * * + * Purpose: periodically sends config changes and history to related nodes * + * * + * Parameters: * + * * + * Return value: * + * * + * Author: Alexei Vladishev * + * * + * Comments: never returns * + * * + ******************************************************************************/ +int main_nodesender_loop() +{ + DB_RESULT result; + DB_ROW row; + +// zabbix_log( LOG_LEVEL_WARNING, "In main_nodesender_loop()"); + for(;;) + { + + zbx_setproctitle("connecting to the database"); + + DBconnect(); + + result = DBselect("select nodeid from nodes where nodetype=%d",NODE_TYPE_LOCAL); + + row = DBfetch(result); + + if(row) + { + if(CONFIG_NODEID != atoi(row[0])) + { + zabbix_log( LOG_LEVEL_WARNING, "NodeID does not match configuration settings. Processing of the node is disabled."); + } + else + { + process_node(atoi(row[0])); + } + } + + DBfree_result(result); + + DBclose(); + + zbx_setproctitle("node sender [sleeping for %d seconds]", 30); + + sleep(30); + } +} diff --git a/src/zabbix_server/nodesender/nodesender.h b/src/zabbix_server/nodesender/nodesender.h new file mode 100644 index 00000000..23d735d5 --- /dev/null +++ b/src/zabbix_server/nodesender/nodesender.h @@ -0,0 +1,26 @@ +/* +** ZABBIX +** Copyright (C) 2000-2005 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + +#ifndef ZABBIX_NODESENDER_H +#define ZABBIX_NODESENDER_H + + +int main_nodesender_loop(); + +#endif diff --git a/src/zabbix_server/nodewatcher/.deps/nodewatcher.Po b/src/zabbix_server/nodewatcher/.deps/nodewatcher.Po new file mode 100644 index 00000000..0c9aef3d --- /dev/null +++ b/src/zabbix_server/nodewatcher/.deps/nodewatcher.Po @@ -0,0 +1,396 @@ +nodewatcher.o nodewatcher.o: nodewatcher.c ../../../include/config.h \ + /usr/include/stdio.h /usr/include/features.h /usr/include/sys/cdefs.h \ + /usr/include/gnu/stubs.h \ + /usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/stddef.h \ + /usr/include/bits/types.h /usr/include/bits/wordsize.h \ + /usr/include/bits/typesizes.h /usr/include/libio.h \ + /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \ + /usr/include/gconv.h \ + /usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/stdarg.h \ + /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h \ + /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \ + /usr/include/endian.h /usr/include/bits/endian.h \ + /usr/include/sys/select.h /usr/include/bits/select.h \ + /usr/include/bits/sigset.h /usr/include/bits/time.h \ + /usr/include/sys/sysmacros.h /usr/include/bits/pthreadtypes.h \ + /usr/include/alloca.h /usr/include/unistd.h \ + /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \ + /usr/include/getopt.h /usr/include/sys/stat.h /usr/include/bits/stat.h \ + /usr/include/sys/socket.h /usr/include/sys/uio.h \ + /usr/include/bits/uio.h /usr/include/bits/socket.h \ + /usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/limits.h \ + /usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/syslimits.h \ + /usr/include/limits.h /usr/include/bits/posix1_lim.h \ + /usr/include/bits/local_lim.h /usr/include/linux/limits.h \ + /usr/include/bits/posix2_lim.h /usr/include/bits/sockaddr.h \ + /usr/include/asm/socket.h /usr/include/asm-x86_64/socket.h \ + /usr/include/asm/sockios.h /usr/include/asm-x86_64/sockios.h \ + /usr/include/netinet/in.h /usr/include/stdint.h /usr/include/bits/in.h \ + /usr/include/bits/byteswap.h /usr/include/sys/wait.h \ + /usr/include/signal.h /usr/include/bits/signum.h \ + /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h \ + /usr/include/bits/sigcontext.h /usr/include/bits/sigstack.h \ + /usr/include/bits/sigthread.h /usr/include/sys/resource.h \ + /usr/include/bits/resource.h /usr/include/bits/waitflags.h \ + /usr/include/bits/waitstatus.h /usr/include/string.h \ + /usr/include/netdb.h /usr/include/rpc/netdb.h /usr/include/bits/netdb.h \ + /usr/include/pwd.h /usr/include/errno.h /usr/include/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/asm/errno.h \ + /usr/include/asm-x86_64/errno.h ../../../include/common.h \ + ../../../include/sysinc.h /usr/include/assert.h /usr/include/ctype.h \ + /usr/include/strings.h /usr/include/sys/time.h \ + /usr/include/linux/kernel.h /usr/include/arpa/nameser.h \ + /usr/include/sys/param.h /usr/include/linux/param.h \ + /usr/include/asm/param.h /usr/include/asm-x86_64/param.h \ + /usr/include/sys/bitypes.h /usr/include/arpa/nameser_compat.h \ + /usr/include/dirent.h /usr/include/bits/dirent.h /usr/include/fcntl.h \ + /usr/include/bits/fcntl.h /usr/include/ldap.h /usr/include/lber.h \ + /usr/include/lber_types.h /usr/include/ldap_cdefs.h \ + /usr/include/ldap_features.h /usr/include/sys/procfs.h \ + /usr/include/sys/user.h /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/bits/sched.h /usr/include/bits/setjmp.h \ + /usr/include/resolv.h /usr/include/sys/statvfs.h \ + /usr/include/bits/statvfs.h /usr/include/sys/swap.h \ + /usr/include/sys/syscall.h /usr/include/asm/unistd.h \ + /usr/include/asm-x86_64/unistd.h /usr/include/bits/syscall.h \ + /usr/include/sys/sysctl.h /usr/include/linux/sysctl.h \ + /usr/include/linux/types.h /usr/include/sys/sysinfo.h \ + /usr/include/sys/vfs.h /usr/include/sys/statfs.h \ + /usr/include/bits/statfs.h /usr/include/net/if.h /usr/include/syslog.h \ + /usr/include/sys/syslog.h /usr/include/sys/ipc.h \ + /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h \ + /usr/include/sys/sem.h /usr/include/bits/sem.h /usr/include/sys/shm.h \ + /usr/include/bits/shm.h /usr/include/math.h \ + /usr/include/bits/huge_val.h /usr/include/bits/mathdef.h \ + /usr/include/bits/mathcalls.h /usr/include/regex.h \ + /usr/include/arpa/inet.h /usr/include/sys/mount.h \ + /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \ + /usr/include/asm/ioctls.h /usr/include/asm-x86_64/ioctls.h \ + /usr/include/asm/ioctl.h /usr/include/asm-x86_64/ioctl.h \ + /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \ + /usr/include/sys/timeb.h ../../../include/zbxtypes.h \ + ../../../include/cfg.h ../../../include/db.h /usr/include/mysql/mysql.h \ + /usr/include/mysql/mysql_com.h /usr/include/mysql/mysql_version.h \ + /usr/include/mysql/my_alloc.h /usr/include/mysql/errmsg.h \ + /usr/include/mysql/mysqld_error.h ../../../include/log.h \ + ../../../include/zlog.h ../../../include/dbsync.h nodewatcher.h + +../../../include/config.h: + +/usr/include/stdio.h: + +/usr/include/features.h: + +/usr/include/sys/cdefs.h: + +/usr/include/gnu/stubs.h: + +/usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/stddef.h: + +/usr/include/bits/types.h: + +/usr/include/bits/wordsize.h: + +/usr/include/bits/typesizes.h: + +/usr/include/libio.h: + +/usr/include/_G_config.h: + +/usr/include/wchar.h: + +/usr/include/bits/wchar.h: + +/usr/include/gconv.h: + +/usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/stdarg.h: + +/usr/include/bits/stdio_lim.h: + +/usr/include/bits/sys_errlist.h: + +/usr/include/stdlib.h: + +/usr/include/sys/types.h: + +/usr/include/time.h: + +/usr/include/endian.h: + +/usr/include/bits/endian.h: + +/usr/include/sys/select.h: + +/usr/include/bits/select.h: + +/usr/include/bits/sigset.h: + +/usr/include/bits/time.h: + +/usr/include/sys/sysmacros.h: + +/usr/include/bits/pthreadtypes.h: + +/usr/include/alloca.h: + +/usr/include/unistd.h: + +/usr/include/bits/posix_opt.h: + +/usr/include/bits/confname.h: + +/usr/include/getopt.h: + +/usr/include/sys/stat.h: + +/usr/include/bits/stat.h: + +/usr/include/sys/socket.h: + +/usr/include/sys/uio.h: + +/usr/include/bits/uio.h: + +/usr/include/bits/socket.h: + +/usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/limits.h: + +/usr/lib/gcc-lib/x86_64-linux-gnu/3.3.6/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/bits/posix1_lim.h: + +/usr/include/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/bits/posix2_lim.h: + +/usr/include/bits/sockaddr.h: + +/usr/include/asm/socket.h: + +/usr/include/asm-x86_64/socket.h: + +/usr/include/asm/sockios.h: + +/usr/include/asm-x86_64/sockios.h: + +/usr/include/netinet/in.h: + +/usr/include/stdint.h: + +/usr/include/bits/in.h: + +/usr/include/bits/byteswap.h: + +/usr/include/sys/wait.h: + +/usr/include/signal.h: + +/usr/include/bits/signum.h: + +/usr/include/bits/siginfo.h: + +/usr/include/bits/sigaction.h: + +/usr/include/bits/sigcontext.h: + +/usr/include/bits/sigstack.h: + +/usr/include/bits/sigthread.h: + +/usr/include/sys/resource.h: + +/usr/include/bits/resource.h: + +/usr/include/bits/waitflags.h: + +/usr/include/bits/waitstatus.h: + +/usr/include/string.h: + +/usr/include/netdb.h: + +/usr/include/rpc/netdb.h: + +/usr/include/bits/netdb.h: + +/usr/include/pwd.h: + +/usr/include/errno.h: + +/usr/include/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/asm/errno.h: + +/usr/include/asm-x86_64/errno.h: + +../../../include/common.h: + +../../../include/sysinc.h: + +/usr/include/assert.h: + +/usr/include/ctype.h: + +/usr/include/strings.h: + +/usr/include/sys/time.h: + +/usr/include/linux/kernel.h: + +/usr/include/arpa/nameser.h: + +/usr/include/sys/param.h: + +/usr/include/linux/param.h: + +/usr/include/asm/param.h: + +/usr/include/asm-x86_64/param.h: + +/usr/include/sys/bitypes.h: + +/usr/include/arpa/nameser_compat.h: + +/usr/include/dirent.h: + +/usr/include/bits/dirent.h: + +/usr/include/fcntl.h: + +/usr/include/bits/fcntl.h: + +/usr/include/ldap.h: + +/usr/include/lber.h: + +/usr/include/lber_types.h: + +/usr/include/ldap_cdefs.h: + +/usr/include/ldap_features.h: + +/usr/include/sys/procfs.h: + +/usr/include/sys/user.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/bits/sched.h: + +/usr/include/bits/setjmp.h: + +/usr/include/resolv.h: + +/usr/include/sys/statvfs.h: + +/usr/include/bits/statvfs.h: + +/usr/include/sys/swap.h: + +/usr/include/sys/syscall.h: + +/usr/include/asm/unistd.h: + +/usr/include/asm-x86_64/unistd.h: + +/usr/include/bits/syscall.h: + +/usr/include/sys/sysctl.h: + +/usr/include/linux/sysctl.h: + +/usr/include/linux/types.h: + +/usr/include/sys/sysinfo.h: + +/usr/include/sys/vfs.h: + +/usr/include/sys/statfs.h: + +/usr/include/bits/statfs.h: + +/usr/include/net/if.h: + +/usr/include/syslog.h: + +/usr/include/sys/syslog.h: + +/usr/include/sys/ipc.h: + +/usr/include/bits/ipctypes.h: + +/usr/include/bits/ipc.h: + +/usr/include/sys/sem.h: + +/usr/include/bits/sem.h: + +/usr/include/sys/shm.h: + +/usr/include/bits/shm.h: + +/usr/include/math.h: + +/usr/include/bits/huge_val.h: + +/usr/include/bits/mathdef.h: + +/usr/include/bits/mathcalls.h: + +/usr/include/regex.h: + +/usr/include/arpa/inet.h: + +/usr/include/sys/mount.h: + +/usr/include/sys/ioctl.h: + +/usr/include/bits/ioctls.h: + +/usr/include/asm/ioctls.h: + +/usr/include/asm-x86_64/ioctls.h: + +/usr/include/asm/ioctl.h: + +/usr/include/asm-x86_64/ioctl.h: + +/usr/include/bits/ioctl-types.h: + +/usr/include/sys/ttydefaults.h: + +/usr/include/sys/timeb.h: + +../../../include/zbxtypes.h: + +../../../include/cfg.h: + +../../../include/db.h: + +/usr/include/mysql/mysql.h: + +/usr/include/mysql/mysql_com.h: + +/usr/include/mysql/mysql_version.h: + +/usr/include/mysql/my_alloc.h: + +/usr/include/mysql/errmsg.h: + +/usr/include/mysql/mysqld_error.h: + +../../../include/log.h: + +../../../include/zlog.h: + +../../../include/dbsync.h: + +nodewatcher.h: diff --git a/src/zabbix_server/nodewatcher/Makefile.am b/src/zabbix_server/nodewatcher/Makefile.am new file mode 100644 index 00000000..e8af7e8f --- /dev/null +++ b/src/zabbix_server/nodewatcher/Makefile.am @@ -0,0 +1,4 @@ +SUBDIRS= +INCLUDES=-I@top_srcdir@/include @MYSQL_INCLUDE@ @ORACLE_INCLUDE@ +lib_LIBRARIES=libzbxnodewatcher.a +libzbxnodewatcher_a_SOURCES=nodewatcher.c diff --git a/src/zabbix_server/nodewatcher/nodewatcher.c b/src/zabbix_server/nodewatcher/nodewatcher.c new file mode 100644 index 00000000..d86611cd --- /dev/null +++ b/src/zabbix_server/nodewatcher/nodewatcher.c @@ -0,0 +1,260 @@ +/* +** ZABBIX +** Copyright (C) 2000-2006 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <netinet/in.h> + +#include <sys/wait.h> + +#include <string.h> + +#ifdef HAVE_NETDB_H + #include <netdb.h> +#endif + +/* Required for getpwuid */ +#include <pwd.h> + +#include <signal.h> +#include <errno.h> + +#include <time.h> + +#include "common.h" +#include "cfg.h" +#include "db.h" +#include "log.h" +#include "zlog.h" + +#include "dbsync.h" +#include "nodewatcher.h" + +/****************************************************************************** + * * + * 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[64000]; + char tmp[MAX_STRING_LEN]; + char fields[MAX_STRING_LEN]; + + int i = 0; + int j; + DB_RESULT result; + DB_RESULT result2; + DB_ROW row,row2; + +// zabbix_log( LOG_LEVEL_WARNING, "In calculate_checksums"); + DBexecute("delete from node_cksum where cksumtype=%d", NODE_CKSUM_TYPE_NEW); + // insert into node_cksum (select NULL,0,'items','itemid',itemid,0,md5(concat(key_)) as md5 from items); + + /* Select all nodes */ + zbx_snprintf(sql,sizeof(sql),"select nodeid from nodes"); + result =DBselect(sql); + while((row=DBfetch(result))) + { + zbx_snprintf(sql,sizeof(sql),"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; + + j=0; + fields[0]=0; + while(tables[i].fields[j].name != 0) + { +// zabbix_log( LOG_LEVEL_WARNING, "In calculate_checksums2 [%s,%s]", tables[i].table,tables[i].fields[j].name ); + strncat(fields,tables[i].fields[j].name,sizeof(tmp)); + strncat(fields,",",sizeof(tmp)); + j++; + } + if(fields[0]!=0) fields[strlen(fields)-1] = 0; + + // select table,recid,md5(fields) from table union all ... + zbx_snprintf(tmp,sizeof(tmp),"union all select '%s','%s',%s,md5(concat(%s)) from %s where mod(%s,100)=%s\n", + tables[i].table, tables[i].recid, tables[i].recid, fields, tables[i].table, tables[i].recid, row[0]); + strncat(sql,tmp,sizeof(sql)); + } +// zabbix_log( LOG_LEVEL_WARNING, "SQL [%s]", sql); + + result2 =DBselect(sql); + while((row2=DBfetch(result2))) + { + DBexecute("insert into node_cksum (nodeid,tablename,fieldname,recordid,cksumtype,cksum)"\ + "values (%s,'%s','%s',%s,%d,'%s')",row[0],row2[0],row2[1],row2[2],NODE_CKSUM_TYPE_NEW,row2[3]); + } + DBfree_result(result2); + } + DBfree_result(result); + + + return SUCCEED; +} + +/****************************************************************************** + * * + * Function: update_checksums * + * * + * Purpose: overwrite old checksums with new ones * + * * + * Parameters: * + * * + * Return value: SUCCESS - calculated succesfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int update_checksums() +{ + /* Begin work */ + DBexecute("delete from node_cksum where cksumtype=%d", NODE_CKSUM_TYPE_OLD); + DBexecute("update node_cksum set cksumtype=%d where cksumtype=%d", NODE_CKSUM_TYPE_OLD, NODE_CKSUM_TYPE_NEW); + /* Commit */ + + return SUCCEED; +} + +/****************************************************************************** + * * + * 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; + + /* Begin work */ + + /* Find updated records */ + result = DBselect("select new.nodeid,new.tablename,new.recordid from node_cksum old, node_cksum new where new.tablename=old.tablename and new.recordid=old.recordid and new.fieldname=old.fieldname and new.nodeid=old.nodeid and new.cksum<>old.cksum and new.cksumtype=%d and old.cksumtype=%d", NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD); + while((row=DBfetch(result))) + { +// zabbix_log( LOG_LEVEL_WARNING, "Adding record to node_configlog"); + DBexecute("insert into node_configlog (nodeid,tablename,recordid,operation)" \ + "values (%s,'%s',%s,%d)", row[0],row[1],row[2],NODE_CONFIGLOG_OP_UPDATE); + } + DBfree_result(result); + + /* Find new records */ + result = DBselect("select new.nodeid,new.tablename,new.recordid from node_cksum new" \ + " left join node_cksum old" \ + " on new.tablename=old.tablename and new.recordid=old.recordid and new.fieldname=old.fieldname and new.nodeid=old.nodeid and new.cksumtype<>old.cksumtype" \ + " where old.cksumid is null and new.cksumtype=%d", NODE_CKSUM_TYPE_NEW); + + while((row=DBfetch(result))) + { +// zabbix_log( LOG_LEVEL_WARNING, "Adding record to node_configlog"); + DBexecute("insert into node_configlog (nodeid,tablename,recordid,operation)" \ + "values (%s,'%s',%s,%d)", row[0],row[1],row[2],NODE_CONFIGLOG_OP_ADD); + } + DBfree_result(result); + + /* Find deleted records */ + result = DBselect("select new.nodeid,new.tablename,new.recordid from node_cksum new" \ + " left join node_cksum old" \ + " on new.tablename=old.tablename and new.recordid=old.recordid and new.fieldname=old.fieldname and new.nodeid=old.nodeid and new.cksumtype<>old.cksumtype" \ + " where old.cksumid is null and new.cksumtype=%d", NODE_CKSUM_TYPE_OLD); + + while((row=DBfetch(result))) + { +// zabbix_log( LOG_LEVEL_WARNING, "Adding record to node_configlog"); + DBexecute("insert into node_configlog (nodeid,tablename,recordid,operation)" \ + "values (%s,'%s',%s,%d)", row[0],row[1],row[2],NODE_CONFIGLOG_OP_DELETE); + } + DBfree_result(result); + + /* Commit */ + + return SUCCEED; +} + + +/****************************************************************************** + * * + * 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() +{ +// zabbix_log( LOG_LEVEL_WARNING, "In main_nodeupdater_loop()"); + for(;;) + { + + zbx_setproctitle("connecting to the database"); + + DBconnect(); + calculate_checksums(); + compare_checksums(); + update_checksums(); + DBclose(); + + zbx_setproctitle("sender [sleeping for %d seconds]", 30); + + sleep(30); + } +} diff --git a/src/zabbix_server/nodewatcher/nodewatcher.h b/src/zabbix_server/nodewatcher/nodewatcher.h new file mode 100644 index 00000000..ea4ca409 --- /dev/null +++ b/src/zabbix_server/nodewatcher/nodewatcher.h @@ -0,0 +1,25 @@ +/* +** ZABBIX +** Copyright (C) 2000-2005 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + +#ifndef ZABBIX_NODEWATCHER_H +#define ZABBIX_NODEWATCHER_H + +int main_nodewatcher_loop(); + +#endif diff --git a/src/zabbix_server/pinger/pinger.c b/src/zabbix_server/pinger/pinger.c index 112a9a1e..e134b9bd 100644 --- a/src/zabbix_server/pinger/pinger.c +++ b/src/zabbix_server/pinger/pinger.c @@ -132,11 +132,11 @@ static int process_value(char *key, char *host, AGENT_RESULT *value) /* IP address? */ if(is_ip(host) == SUCCEED) { - result = DBselect("select i.itemid,i.key_,h.host,h.port,i.delay,i.description,i.nextcheck,i.type,i.snmp_community,i.snmp_oid,h.useip,h.ip,i.history,i.lastvalue,i.prevvalue,i.value_type,i.trapper_hosts,i.delta,i.units,i.multiplier,i.formula from items i,hosts h where h.status=%d and h.hostid=i.hostid and h.ip='%s' and i.key_='%s' and i.status=%d and i.type=%d", HOST_STATUS_MONITORED, host, key, ITEM_STATUS_ACTIVE, ITEM_TYPE_SIMPLE); + result = DBselect("select i.itemid,i.key_,h.host,h.port,i.delay,i.description,i.nextcheck,i.type,i.snmp_community,i.snmp_oid,h.useip,h.ip,i.history,i.lastvalue,i.prevvalue,i.value_type,i.trapper_hosts,i.delta,i.units,i.multiplier,i.formula from items i,hosts h where h.status=%d and h.hostid=i.hostid and h.ip='%s' and i.key_='%s' and i.status=%d and i.type=%d and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, host, key, ITEM_STATUS_ACTIVE, ITEM_TYPE_SIMPLE, LOCAL_NODE("h.hostid")); } else { - result = DBselect("select i.itemid,i.key_,h.host,h.port,i.delay,i.description,i.nextcheck,i.type,i.snmp_community,i.snmp_oid,h.useip,h.ip,i.history,i.lastvalue,i.prevvalue,i.value_type,i.trapper_hosts,i.delta,i.units,i.multiplier,i.formula from items i,hosts h where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type=%d", HOST_STATUS_MONITORED, host, key, ITEM_STATUS_ACTIVE, ITEM_TYPE_SIMPLE); + result = DBselect("select i.itemid,i.key_,h.host,h.port,i.delay,i.description,i.nextcheck,i.type,i.snmp_community,i.snmp_oid,h.useip,h.ip,i.history,i.lastvalue,i.prevvalue,i.value_type,i.trapper_hosts,i.delta,i.units,i.multiplier,i.formula from items i,hosts h where h.status=%d and h.hostid=i.hostid and h.host='%s' and i.key_='%s' and i.status=%d and i.type=%d and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, host, key, ITEM_STATUS_ACTIVE, ITEM_TYPE_SIMPLE, LOCAL_NODE("configid")); } row=DBfetch(result); @@ -233,7 +233,7 @@ static int create_host_file(void) now=time(NULL); /* Select hosts monitored by IP */ - result = DBselect("select distinct h.ip from hosts h,items i where i.hostid=h.hostid and (h.status=%d or (h.status=%d and h.available=%d and h.disable_until<=%d)) and (i.key_='%s' or i.key_='%s') and i.type=%d and i.status=%d and h.useip=1", HOST_STATUS_MONITORED, HOST_STATUS_MONITORED, HOST_AVAILABLE_FALSE, now, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, ITEM_TYPE_SIMPLE, ITEM_STATUS_ACTIVE); + result = DBselect("select distinct h.ip from hosts h,items i where i.hostid=h.hostid and (h.status=%d or (h.status=%d and h.available=%d and h.disable_until<=%d)) and (i.key_='%s' or i.key_='%s') and i.type=%d and i.status=%d and h.useip=1 and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, HOST_STATUS_MONITORED, HOST_AVAILABLE_FALSE, now, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, ITEM_TYPE_SIMPLE, ITEM_STATUS_ACTIVE, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { @@ -247,7 +247,7 @@ static int create_host_file(void) DBfree_result(result); /* Select hosts monitored by hostname */ - result = DBselect("select distinct h.host from hosts h,items i where i.hostid=h.hostid and (h.status=%d or (h.status=%d and h.available=%d and h.disable_until<=%d)) and (i.key_='%s' or i.key_='%s') and i.type=%d and i.status=%d and h.useip=0", HOST_STATUS_MONITORED, HOST_STATUS_MONITORED, HOST_AVAILABLE_FALSE, now, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, ITEM_TYPE_SIMPLE, ITEM_STATUS_ACTIVE); + result = DBselect("select distinct h.host from hosts h,items i where i.hostid=h.hostid and (h.status=%d or (h.status=%d and h.available=%d and h.disable_until<=%d)) and (i.key_='%s' or i.key_='%s') and i.type=%d and i.status=%d and h.useip=0 and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, HOST_STATUS_MONITORED, HOST_AVAILABLE_FALSE, now, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, ITEM_TYPE_SIMPLE, ITEM_STATUS_ACTIVE, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/pinger/pinger.h b/src/zabbix_server/pinger/pinger.h index e4f1d08d..e87088fc 100644 --- a/src/zabbix_server/pinger/pinger.h +++ b/src/zabbix_server/pinger/pinger.h @@ -29,6 +29,8 @@ extern char *CONFIG_DBPASSWORD; extern char *CONFIG_DBSOCKET; extern char *CONFIG_FPING_LOCATION; +extern int CONFIG_NODEID; + extern void signal_handler( int sig ); void main_pinger_loop(); diff --git a/src/zabbix_server/poller/checks_aggregate.c b/src/zabbix_server/poller/checks_aggregate.c index 09e6261e..14272dd1 100644 --- a/src/zabbix_server/poller/checks_aggregate.c +++ b/src/zabbix_server/poller/checks_aggregate.c @@ -110,7 +110,7 @@ static int evaluate_aggregate(AGENT_RESULT *res,char *grpfunc, char *hostgroup, DBescape_string(hostgroup,hostgroup_esc,MAX_STRING_LEN); /* Get list of affected item IDs */ strscpy(items,"0"); - result = DBselect("select itemid from items,hosts_groups,hosts,groups where hosts_groups.groupid=groups.groupid and items.hostid=hosts.hostid and hosts_groups.hostid=hosts.hostid and groups.name='%s' and items.key_='%s' and items.status=%d and hosts.status=%d",hostgroup_esc, itemkey_esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED); + result = DBselect("select itemid from items i,hosts_groups hg,hosts h,groups g where hosts_groups.groupid=groups.groupid and items.hostid=hosts.hostid and hosts_groups.hostid=hosts.hostid and groups.name='%s' and items.key_='%s' and items.status=%d and hosts.status=%d and" ZBX_COND_NODEID,hostgroup_esc, itemkey_esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/poller/checks_aggregate.h b/src/zabbix_server/poller/checks_aggregate.h index a111cc45..f218ec08 100644 --- a/src/zabbix_server/poller/checks_aggregate.h +++ b/src/zabbix_server/poller/checks_aggregate.h @@ -29,6 +29,8 @@ #include "db.h" #include "log.h" +extern int CONFIG_NODEID; + extern int get_value_aggregate(DB_ITEM *item, AGENT_RESULT *result); #endif diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c index 8e88b1e6..64ea2604 100644 --- a/src/zabbix_server/poller/poller.c +++ b/src/zabbix_server/poller/poller.c @@ -121,17 +121,17 @@ static int get_minnextcheck(int now) 2 == UNREACHABLE */ if(my_server_num == 4) { - result = DBselect("select count(*),min(i.nextcheck) as nextcheck from items i,hosts h where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from!=0 and h.hostid=i.hostid and i.key_ not in ('%s','%s','%s','%s') order by nextcheck", now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select count(*),min(nextcheck) as nextcheck from items i,hosts h where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from!=0 and h.hostid=i.hostid and i.key_ not in ('%s','%s','%s','%s') and " ZBX_COND_NODEID "order by nextcheck", now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } else { if(CONFIG_REFRESH_UNSUPPORTED != 0) { - result = DBselect("select count(*),min(nextcheck) from items i,hosts h where h.status=%d and h.disable_until<%d and h.errors_from=0 and h.hostid=i.hostid and i.status in (%d,%d) and i.type not in (%d,%d) and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s')", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, CONFIG_POLLER_FORKS-5,my_server_num-5,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select count(*),min(nextcheck) from items i,hosts h where h.status=%d and h.disable_until<%d and h.errors_from=0 and h.hostid=i.hostid and i.status in (%d,%d) and i.type not in (%d,%d) and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, CONFIG_POLLER_FORKS-7,my_server_num-7,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } else { - result = DBselect("select count(*),min(nextcheck) from items i,hosts h where h.status=%d and h.disable_until<%d and h.errors_from=0 and h.hostid=i.hostid and i.status in (%d,%d) and i.type not in (%d) and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s')", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, CONFIG_POLLER_FORKS-5,my_server_num-5,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select count(*),min(nextcheck) from items i,hosts h where h.status=%d and h.disable_until<%d and h.errors_from=0 and h.hostid=i.hostid and i.status in (%d,%d) and i.type not in (%d) and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, CONFIG_POLLER_FORKS-7,my_server_num-7,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } } @@ -229,17 +229,17 @@ int get_values(void) /* Poller for unreachable hosts */ if(my_server_num == 4) { - result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from!=0 and h.hostid=i.hostid and i.key_ not in ('%s','%s','%s','%s') order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from!=0 and h.hostid=i.hostid and i.key_ not in ('%s','%s','%s','%s') and " ZBX_COND_NODEID " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } else { if(CONFIG_REFRESH_UNSUPPORTED != 0) { - result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d,%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from=0 and h.hostid=i.hostid and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, CONFIG_POLLER_FORKS-5,my_server_num-5,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d,%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from=0 and h.hostid=i.hostid and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') and " ZBX_COND_NODEID " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, CONFIG_POLLER_FORKS-7,my_server_num-7,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } else { - result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from=0 and h.hostid=i.hostid and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, CONFIG_POLLER_FORKS-5,my_server_num-5,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY); + result = DBselect("select %s where i.nextcheck<=%d and i.status in (%d) and i.type not in (%d,%d) and h.status=%d and h.disable_until<=%d and h.errors_from=0 and h.hostid=i.hostid and mod(i.itemid,%d)=%d and i.key_ not in ('%s','%s','%s','%s') and " ZBX_COND_NODEID " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now, ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, ITEM_TYPE_ZABBIX_ACTIVE, HOST_STATUS_MONITORED, now, CONFIG_POLLER_FORKS-7,my_server_num-7,SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY,SERVER_ZABBIXLOG_KEY, LOCAL_NODE("h.hostid")); } } diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c index eef7d8c1..2757a1b6 100644 --- a/src/zabbix_server/server.c +++ b/src/zabbix_server/server.c @@ -60,6 +60,8 @@ #include "poller/checks_snmp.h" #include "timer/timer.h" #include "trapper/trapper.h" +#include "nodewatcher/nodewatcher.h" +#include "nodesender/nodesender.h" #define LISTENQ 1024 @@ -123,6 +125,8 @@ char *CONFIG_DBSOCKET = NULL; int CONFIG_DBPORT = 3306; int CONFIG_ENABLE_REMOTE_COMMANDS = 0; +int CONFIG_NODEID = 0; + /* From table config */ int CONFIG_REFRESH_UNSUPPORTED = 0; @@ -146,7 +150,7 @@ void init_config(void) static struct cfg_line cfg[]= { /* PARAMETER ,VAR ,FUNC, TYPE(0i,1s),MANDATORY,MIN,MAX */ - {"StartPollers",&CONFIG_POLLER_FORKS,0,TYPE_INT,PARM_OPT,6,255}, + {"StartPollers",&CONFIG_POLLER_FORKS,0,TYPE_INT,PARM_OPT,8,255}, {"HousekeepingFrequency",&CONFIG_HOUSEKEEPING_FREQUENCY,0,TYPE_INT,PARM_OPT,1,24}, {"SenderFrequency",&CONFIG_SENDER_FREQUENCY,0,TYPE_INT,PARM_OPT,5,3600}, {"PingerFrequency",&CONFIG_PINGER_FREQUENCY,0,TYPE_INT,PARM_OPT,1,3600}, @@ -171,6 +175,7 @@ void init_config(void) {"DBPassword",&CONFIG_DBPASSWORD,0,TYPE_STRING,PARM_OPT,0,0}, {"DBSocket",&CONFIG_DBSOCKET,0,TYPE_STRING,PARM_OPT,0,0}, {"DBPort",&CONFIG_DBPORT,0,TYPE_INT,PARM_OPT,1024,65535}, + {"NodeID",&CONFIG_NODEID,0,TYPE_INT,PARM_OPT,0,65535}, {0} }; @@ -445,7 +450,8 @@ int MAIN_ZABBIX_ENTRY(void) DBconnect(); - result = DBselect("select refresh_unsupported from config"); + zabbix_log( LOG_LEVEL_WARNING, "Cond1 " ZBX_COND_NODEID, LOCAL_NODE("configid")); + result = DBselect("select refresh_unsupported from config where " ZBX_COND_NODEID, LOCAL_NODE("configid")); row = DBfetch(result); if(row && DBis_null(row[0]) != SUCCEED) @@ -453,6 +459,7 @@ int MAIN_ZABBIX_ENTRY(void) CONFIG_REFRESH_UNSUPPORTED = atoi(row[0]); } DBfree_result(result); + zabbix_log( LOG_LEVEL_WARNING, "OK"); /* Need to set trigger status to UNKNOWN since last run */ /* DBconnect() already made in init_config() */ @@ -542,6 +549,18 @@ int MAIN_ZABBIX_ENTRY(void) main_poller_loop(server_num); } + else if(server_num == 5) + { +/* Periodic checker of node configuration changes */ + zabbix_log( LOG_LEVEL_WARNING, "server #%d started [Node watcher]",server_num); + main_nodewatcher_loop(); + } + else if(server_num == 6) + { +/* Node communications */ + zabbix_log( LOG_LEVEL_WARNING, "server #%d started [Node sender]",server_num); + main_nodesender_loop(); + } else { #ifdef HAVE_SNMP diff --git a/src/zabbix_server/timer/timer.c b/src/zabbix_server/timer/timer.c index 04c77d6c..72dfb8e4 100644 --- a/src/zabbix_server/timer/timer.c +++ b/src/zabbix_server/timer/timer.c @@ -42,6 +42,7 @@ #include "zlog.h" #include "common.h" +#include "timer.h" extern void update_triggers(int itemid); extern void update_functions(DB_ITEM *item); @@ -89,7 +90,7 @@ void main_timer_loop() #endif */ - result = DBselect("select distinct %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') and i.itemid=f.itemid", ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE); + result = DBselect("select distinct %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') and i.itemid=f.itemid and" ZBX_COND_NODEID, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/timer/timer.h b/src/zabbix_server/timer/timer.h index bcd95c1d..469eb099 100644 --- a/src/zabbix_server/timer/timer.h +++ b/src/zabbix_server/timer/timer.h @@ -20,14 +20,8 @@ #ifndef ZABBIX_TIMER_H #define ZABBIX_TIMER_H -/* -extern void signal_handler(int); -extern int server_num; +extern int CONFIG_NODEID; -extern int CONFIG_TIMEOUT; -extern int CONFIG_SUCKERD_FORKS; -*/ - -int main_timer_loop(); +void main_timer_loop(); #endif diff --git a/src/zabbix_server/trapper/Makefile.am b/src/zabbix_server/trapper/Makefile.am index 5053811e..9b3e40aa 100644 --- a/src/zabbix_server/trapper/Makefile.am +++ b/src/zabbix_server/trapper/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS= INCLUDES=-I@top_srcdir@/include @MYSQL_INCLUDE@ @ORACLE_INCLUDE@ @PGSQL_INCLUDE@ lib_LIBRARIES=libzbxtrapper.a -libzbxtrapper_a_SOURCES=active.c autoregister.h autoregister.c trapper.c +libzbxtrapper_a_SOURCES=active.c autoregister.h autoregister.c trapper.c nodesync.c libzbxtrapper_a_LIBADD = ../../libs/zbxdbhigh/libzbxdbhigh.a diff --git a/src/zabbix_server/trapper/active.c b/src/zabbix_server/trapper/active.c index 8ac24c7f..1dc83091 100644 --- a/src/zabbix_server/trapper/active.c +++ b/src/zabbix_server/trapper/active.c @@ -68,7 +68,7 @@ int send_list_of_active_checks(int sockfd, char *host) zabbix_log( LOG_LEVEL_DEBUG, "In send_list_of_active_checks()"); - result = DBselect("select i.key_,i.delay,i.lastlogsize from items i,hosts h where i.hostid=h.hostid and h.status=%d and i.status=%d and i.type=%d and h.host='%s'", HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX_ACTIVE, host); + result = DBselect("select i.key_,i.delay,i.lastlogsize from items i,hosts h where i.hostid=h.hostid and h.status=%d and i.status=%d and i.type=%d and h.host='%s' and" ZBX_COND_NODEID, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, ITEM_TYPE_ZABBIX_ACTIVE, host, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/trapper/active.h b/src/zabbix_server/trapper/active.h index afeb9b28..b10bf034 100644 --- a/src/zabbix_server/trapper/active.h +++ b/src/zabbix_server/trapper/active.h @@ -24,6 +24,8 @@ #include "common.h" #include "db.h" +extern int CONFIG_NODEID; + int send_list_of_active_checks(int sockfd, char *host); #endif diff --git a/src/zabbix_server/trapper/autoregister.c b/src/zabbix_server/trapper/autoregister.c index 747b4d42..edf9f083 100644 --- a/src/zabbix_server/trapper/autoregister.c +++ b/src/zabbix_server/trapper/autoregister.c @@ -56,7 +56,7 @@ int autoregister(char *server) return FAIL; } - result = DBselect("select id,pattern,hostid from autoreg order by priority"); + result = DBselect("select id,pattern,hostid from autoreg where " ZBX_COND_NODEID " order by priority", LOCAL_NODE("id")); while((row=DBfetch(result))) { diff --git a/src/zabbix_server/trapper/autoregister.h b/src/zabbix_server/trapper/autoregister.h index ec308c67..4bf93016 100644 --- a/src/zabbix_server/trapper/autoregister.h +++ b/src/zabbix_server/trapper/autoregister.h @@ -20,6 +20,8 @@ #ifndef ZABBIX_AUTOREGISTER_H #define ZABBIX_AUTOREGISTER_H +extern int CONFIG_NODEID; + int autoregister(char *server); #endif diff --git a/src/zabbix_server/trapper/nodesync.c b/src/zabbix_server/trapper/nodesync.c new file mode 100644 index 00000000..0d0346ee --- /dev/null +++ b/src/zabbix_server/trapper/nodesync.c @@ -0,0 +1,258 @@ +/* +** ZABBIX +** Copyright (C) 2000-2005 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <netinet/in.h> +#include <netdb.h> + +#include <string.h> + +#include <time.h> + +#include <sys/socket.h> +#include <errno.h> + +/* Functions: pow(), round() */ +#include <math.h> + +#include "common.h" +#include "db.h" +#include "log.h" +#include "zlog.h" + +#include "dbsync.h" +#include "nodesync.h" + +int get_field(char *line, char *result, int num) +{ + int delim=0; + int ptr=0; + int i; + + int ret = FAIL; + + for(i=0;line[i]!=0;i++) + { + if(line[i]=='|') + { + delim++; + continue; + } + if(delim==num) + { + result[ptr++]=line[i]; + result[ptr]=0; + ret = SUCCEED; + } + } + return ret; +} + +/****************************************************************************** + * * + * Function: process_record * + * * + * Purpose: process record update * + * * + * Parameters: * + * * + * Return value: SUCCEED - processed successfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static int process_record(int nodeid, char *record) +{ + char tablename[MAX_STRING_LEN]; + char fieldname[MAX_STRING_LEN]; + int recid; + int op; + int valuetype; + char value[MAX_STRING_LEN]; + char value_esc[MAX_STRING_LEN]; + char tmp[MAX_STRING_LEN]; + char sql[MAX_STRING_LEN]; + int i; + char *key=NULL; + char fields[MAX_STRING_LEN]; + char fields_update[MAX_STRING_LEN]; + char values[MAX_STRING_LEN]; + DB_RESULT result; + DB_ROW row; + +// zabbix_log( LOG_LEVEL_WARNING, "In process_record [%s]", record); + + get_field(record,tablename,0); + get_field(record,tmp,1); + recid=atoi(tmp); + get_field(record,tmp,2); + op=atoi(tmp); + + for(i=0;tables[i].table!=0;i++) + { + if(strcmp(tables[i].table, tablename)==0) + { + key=tables[i].recid; + break; + } + } + + if(key == NULL) + { + zabbix_log( LOG_LEVEL_WARNING, "Cannot find key field for table [%s]",tablename); + return FAIL; + } + if(op==NODE_CONFIGLOG_OP_DELETE) + { + zbx_snprintf(tmp,sizeof(tmp),"delete from %s where %s=%d and nodeid=%d", tablename, key, recid, nodeid); + zabbix_log( LOG_LEVEL_WARNING, "SQL [%s]", sql); + return SUCCEED; + } + + i=3; + fields[0]=0; + fields_update[0]=0; + values[0]=0; + while(get_field(record,fieldname,i++)==SUCCEED) + { + tmp[0]=0; + get_field(record,tmp,i++); + valuetype=atoi(tmp); + value[0]=0; + get_field(record,value,i++); + if(op==NODE_CONFIGLOG_OP_UPDATE || op==NODE_CONFIGLOG_OP_ADD) + { + if(strcmp(value,"NULL")==0) + { + zbx_snprintf(tmp,sizeof(tmp),"%s=NULL,", fieldname); + strncat(fields_update,tmp,sizeof(fields)); + + zbx_snprintf(tmp,sizeof(tmp),"NULL,", value); + } + else + { + DBescape_string(value, value_esc,MAX_STRING_LEN); + + zbx_snprintf(tmp,sizeof(tmp),"%s='%s',", fieldname, value_esc); + strncat(fields_update,tmp,sizeof(fields)); + + zbx_snprintf(tmp,sizeof(tmp),"'%s',", value_esc); + } + + strncat(values,tmp,sizeof(values)); +// zabbix_log( LOG_LEVEL_WARNING, "VALUES [%s]", values); + zbx_snprintf(tmp,sizeof(tmp),"%s,", fieldname); + strncat(fields,tmp,sizeof(fields)); +// zabbix_log( LOG_LEVEL_WARNING, "FIELDS [%s]", fields); + } + else + { + zabbix_log( LOG_LEVEL_WARNING, "Unknown record operation [%d]",op); + return FAIL; + } + } + if(fields[0]!=0) fields[strlen(fields)-1]=0; + if(fields_update[0]!=0) fields_update[strlen(fields_update)-1]=0; + if(values[0]!=0) values[strlen(values)-1]=0; + + if(op==NODE_CONFIGLOG_OP_UPDATE) + { +// zbx_snprintf(tmp,sizeof(tmp),"%s='%s',", fieldname, value); +// strncat(fields,tmp,sizeof(fields)); + zbx_snprintf(sql,sizeof(sql),"update %s set %s where %s=%d", tablename, fields_update, key, recid); + } + else if(op==NODE_CONFIGLOG_OP_ADD) + { + result = DBselect("select 0 from %s where %s=%d", tablename, key, recid); + row = DBfetch(result); + if(row) + { + zbx_snprintf(sql,sizeof(sql),"update %s set %s where %s=%d", tablename, fields_update, key, recid); + } + else + { + zbx_snprintf(sql,sizeof(sql),"insert into %s (%s) values(%s)", tablename, fields, values); + } + DBfree_result(result); + } +// zabbix_log( LOG_LEVEL_WARNING, "SQL [%s]", sql); + if(FAIL == DBexecute(sql)) + { + zabbix_log( LOG_LEVEL_WARNING, "Failed [%s]", record); + } + + return SUCCEED; +} +/****************************************************************************** + * * + * Function: node_sync * + * * + * Purpose: process configuration changes received from a node * + * * + * Parameters: * + * * + * Return value: SUCCEED - processed successfully * + * FAIL - an error occured * + * * + * Author: Alexei Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +int node_sync(char *data) +{ + char *s; + int firstline=1; + int nodeid=0; + int sender_nodeid=0; + char tmp[MAX_STRING_LEN]; + +// zabbix_log( LOG_LEVEL_WARNING, "In node_sync(len:%d)", strlen(data)); + + s=(char *)strtok(data,"\n"); + while(s!=NULL) + { + if(firstline == 1) + { +// zabbix_log( LOG_LEVEL_WARNING, "First line [%s]", s); + get_field(s,tmp,1); + sender_nodeid=atoi(tmp); + get_field(s,tmp,2); + nodeid=atoi(tmp); + firstline=0; + zabbix_log( LOG_LEVEL_WARNING, "NODE %d: Received data from node %d for node %d", CONFIG_NODEID, sender_nodeid, nodeid); + } + else + { +// zabbix_log( LOG_LEVEL_WARNING, "Got line [%s]", s); + process_record(nodeid, s); + } + + s=(char *)strtok(NULL,"\n"); + } + return SUCCEED; +} diff --git a/src/zabbix_server/trapper/nodesync.h b/src/zabbix_server/trapper/nodesync.h new file mode 100644 index 00000000..ee168c31 --- /dev/null +++ b/src/zabbix_server/trapper/nodesync.h @@ -0,0 +1,28 @@ +/* +** ZABBIX +** Copyright (C) 2000-2005 SIA Zabbix +** +** This program is free software; you can redistribute it and/or modify +** it under the terms of the GNU General Public License as published by +** the Free Software Foundation; either version 2 of the License, or +** (at your option) any later version. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU General Public License for more details. +** +** You should have received a copy of the GNU General Public License +** along with this program; if not, write to the Free Software +** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +**/ + + +#ifndef ZABBIX_NODESYNC_H +#define ZABBIX_NODESYNC_H + +extern int CONFIG_NODEID; + +int node_sync(char *data); + +#endif diff --git a/src/zabbix_server/trapper/trapper.c b/src/zabbix_server/trapper/trapper.c index dd695ecf..86517f4e 100644 --- a/src/zabbix_server/trapper/trapper.c +++ b/src/zabbix_server/trapper/trapper.c @@ -50,6 +50,7 @@ #include "../expression.h" #include "autoregister.h" +#include "nodesync.h" #include "trapper.h" #include "daemon.h" @@ -100,8 +101,23 @@ int process_trap(int sockfd,char *s, int max_len) /* Process information sent by zabbix_sender */ else { + /* Node data exchange? */ + if(strncmp(s,"Data",4) == 0) + { +// zabbix_log( LOG_LEVEL_WARNING, "Node data received [len:%d]", strlen(s)); + if(node_sync(s) == SUCCEED) + { + zbx_snprintf(result,sizeof(result),"OK\n"); + if( write(sockfd,result,strlen(result)) == -1) + { + zabbix_log( LOG_LEVEL_WARNING, "Error sending confirmation to node [%s]",strerror(errno)); + zabbix_syslog("Trapper: error sending confirmation to node [%s]",strerror(errno)); + } + } + return ret; + } /* New XML protocol? */ - if(s[0]=='<') + else if(s[0]=='<') { zabbix_log( LOG_LEVEL_DEBUG, "XML received [%s]", s); @@ -167,33 +183,39 @@ int process_trap(int sockfd,char *s, int max_len) void process_trapper_child(int sockfd) { ssize_t nbytes; - char buffer[MAX_BUF_LEN]; + char *buffer; static struct sigaction phan; char *bufptr; +#define ZBX_MAX_PACKET_LEN 8*1024*1024 + zabbix_log( LOG_LEVEL_DEBUG, "In process_trapper_child"); + + buffer=malloc(ZBX_MAX_PACKET_LEN); + phan.sa_handler = &child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = 0; sigaction(SIGALRM, &phan, NULL); - alarm(CONFIG_TIMEOUT); +// alarm(CONFIG_TIMEOUT); - zabbix_log( LOG_LEVEL_DEBUG, "Before read(%d)", MAX_BUF_LEN); + zabbix_log( LOG_LEVEL_DEBUG, "Before read(%d)", ZBX_MAX_PACKET_LEN); /* if( (nbytes = read(sockfd, line, MAX_BUF_LEN)) < 0)*/ - memset(buffer,0,sizeof(buffer)); + memset(buffer,0,ZBX_MAX_PACKET_LEN); bufptr = buffer; - while ((nbytes = read(sockfd, bufptr, buffer + sizeof(buffer) - bufptr - 1)) != -1 && nbytes != 0) + while ((nbytes = read(sockfd, bufptr, buffer + ZBX_MAX_PACKET_LEN - bufptr - 1)) != -1 && nbytes != 0) { - zabbix_log( LOG_LEVEL_DEBUG, "Read %d bytes", nbytes); - if(nbytes < buffer + sizeof(buffer) - bufptr - 1) +// zabbix_log( LOG_LEVEL_WARNING, "Read %d bytes", nbytes); + if(nbytes < buffer + ZBX_MAX_PACKET_LEN - bufptr - 1) { bufptr += nbytes; break; } bufptr += nbytes; } +// zabbix_log( LOG_LEVEL_WARNING, "Read total %d bytes", nbytes); if(nbytes < 0) { @@ -206,6 +228,7 @@ void process_trapper_child(int sockfd) zabbix_log( LOG_LEVEL_WARNING, "read() failed"); } alarm(0); + free(buffer); return; } @@ -215,6 +238,7 @@ void process_trapper_child(int sockfd) process_trap(sockfd,buffer, sizeof(buffer)); + free(buffer); alarm(0); } diff --git a/src/zabbix_server/zlog.c b/src/zabbix_server/zlog.c index 783646a8..6939ce0b 100644 --- a/src/zabbix_server/zlog.c +++ b/src/zabbix_server/zlog.c @@ -34,6 +34,8 @@ #include "log.h" #include "zlog.h" +extern int CONFIG_NODEID; + /****************************************************************************** * * * Function: zabbix_syslog * @@ -62,7 +64,7 @@ void zabbix_syslog(const char *fmt, ...) zabbix_log(LOG_LEVEL_DEBUG, "In zabbix_log()"); - result = DBselect("select %s where h.hostid=i.hostid and i.key_='%s' and i.value_type=%d", ZBX_SQL_ITEM_SELECT, SERVER_ZABBIXLOG_KEY, ITEM_VALUE_TYPE_STR); + result = DBselect("select %s where h.hostid=i.hostid and i.key_='%s' and i.value_type=%d and" ZBX_COND_NODEID, ZBX_SQL_ITEM_SELECT, SERVER_ZABBIXLOG_KEY, ITEM_VALUE_TYPE_STR, LOCAL_NODE("h.hostid")); while((row=DBfetch(result))) { |