diff options
author | Dmitry Borovikov <git-no-replydmitry@zabbix.com> | 2009-08-10 17:50:01 +0400 |
---|---|---|
committer | Dmitry Borovikov <git-no-replydmitry@zabbix.com> | 2009-08-10 17:50:01 +0400 |
commit | 712764362c9a5c60456b0a176b830faa3aa88537 (patch) | |
tree | ab7d00ac0f848b622a2440b30270bda2ffd672ec | |
parent | c2d836594c66d3873f8eb45ecbe817115df2362d (diff) |
- [DEV-416] new simple check `icmppingloss' added; ICMP ckecks now support additional parameters (Dmitry)
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | create/data/data.sql | 6 | ||||
-rw-r--r-- | include/common.h | 2 | ||||
-rw-r--r-- | include/zbxicmpping.h | 38 | ||||
-rw-r--r-- | src/libs/zbxdbhigh/db.c | 11 | ||||
-rw-r--r-- | src/libs/zbxicmpping/icmpping.c | 85 | ||||
-rw-r--r-- | src/zabbix_server/discoverer/discoverer.c | 25 | ||||
-rw-r--r-- | src/zabbix_server/pinger/pinger.c | 532 | ||||
-rw-r--r-- | src/zabbix_server/poller/poller.c | 15 |
9 files changed, 508 insertions, 207 deletions
diff --git a/ChangeLog b/ChangeLog index 8c3c313c964..bf73c34365f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ Changes for 1.7.0 + - [DEV-416] new simple check `icmppingloss' added; ICMP ckecks now support additional parameters (Dmitry) - [DEV-9] added support of global, template and host level macros on the server side (Sasha) - [DEV-414] created basic man pages for all Zabbix binaries (Alexei) - [DEV-340] auto registration of active agents (Sasha) diff --git a/create/data/data.sql b/create/data/data.sql index 1fb89e3c2ed..c4065a9d645 100644 --- a/create/data/data.sql +++ b/create/data/data.sql @@ -368,9 +368,9 @@ INSERT INTO hosts_groups VALUES (46,10046,1); -- Dumping data for table `help_items` -- - -insert into help_items values (3,'icmpping','Checks if server is accessible by ICMP ping 0 - ICMP ping fails 1 - ICMP ping successful One of zabbix_server processes performs ICMP pings once per PingerFrequency seconds.'); -insert into help_items values (3,'icmppingsec','Return ICMP ping response time Number of seconds Example: 0.02'); +insert into help_items values (3,'icmpping[<ip>,<count>,<interval>,<size>,<timeout>]','Checks if server is accessible by ICMP ping 0 - ICMP ping fails 1 - ICMP ping successful One of zabbix_server processes performs ICMP pings once per PingerFrequency seconds.'); +insert into help_items values (3,'icmppingloss[<ip>,<count>,<interval>,<size>,<timeout>]','Returns percentage of lost ICMP ping packets'); +insert into help_items values (3,'icmppingsec[<ip>,<count>,<interval>,<size>,<timeout>,<type>]','Returns ICMP ping response time Number of seconds Example: 0.02'); insert into help_items values (3,'ftp<,port>','Checks if FTP server is running and accepting connections 0 - FTP server is down 1 - FTP server is running'); insert into help_items values (3,'http<,port>','Checks if HTTP (WEB) server is running and accepting connections 0 - HTTP server is down 1 - HTTP server is running'); insert into help_items values (3,'imap<,port>','Checks if IMAP server is running and accepting connections 0 - IMAP server is down 1 - IMAP server is running'); diff --git a/include/common.h b/include/common.h index a6cc2718e8c..aa2049c3412 100644 --- a/include/common.h +++ b/include/common.h @@ -377,7 +377,7 @@ typedef enum /* Special item key used for ICMP pings */ #define SERVER_ICMPPING_KEY "icmpping" /* Special item key used for ICMP ping latency */ -#define SERVER_ICMPPINGSEC_KEY "icmppingsec" +/*#define SERVER_ICMPPINGSEC_KEY "icmppingsec"*/ /*not used, since using `SERVER_ICMPPING_KEY' with `like'(SQL)*/ /* Special item key used for internal ZABBIX log */ #define SERVER_ZABBIXLOG_KEY "zabbix[log]" diff --git a/include/zbxicmpping.h b/include/zbxicmpping.h index 8c2d844fc18..6f90d3e24a8 100644 --- a/include/zbxicmpping.h +++ b/include/zbxicmpping.h @@ -20,13 +20,39 @@ #include "common.h" #include "db.h" -#define ZBX_FPING_HOST struct zbx_fipng_host +#define ZBX_FPING_HOST struct zbx_fping_host ZBX_FPING_HOST { - char addr[HOST_ADDR_LEN_MAX]; - int useip; - zbx_uint64_t alive; - double sec; + char *addr; + double min, avg, max; + int rcv; }; -int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len); +int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len); + +typedef enum +{ + ICMPPING = 0, + ICMPPINGSEC, + ICMPPINGLOSS +} icmpping_t; + +typedef enum +{ + ICMPPINGSEC_MIN = 0, + ICMPPINGSEC_AVG, + ICMPPINGSEC_MAX +} icmppingsec_type_t; + +typedef struct +{ + int count; + int interval; + int size; + int timeout; + zbx_uint64_t itemid; + char *addr; + icmpping_t icmpping; + icmppingsec_type_t type; +} icmpitem_t; + diff --git a/src/libs/zbxdbhigh/db.c b/src/libs/zbxdbhigh/db.c index e5cd10dc99f..c7a3c2d9580 100644 --- a/src/libs/zbxdbhigh/db.c +++ b/src/libs/zbxdbhigh/db.c @@ -679,11 +679,11 @@ void update_triggers_status_to_unknown(zbx_uint64_t hostid,int clock,char *reaso zabbix_log(LOG_LEVEL_DEBUG,"In update_triggers_status_to_unknown()"); - result = DBselect("select distinct t.triggerid,t.expression,t.description,t.status,t.priority,t.value,t.url,t.comments from hosts h,items i,triggers t,functions f where f.triggerid=t.triggerid and f.itemid=i.itemid and h.hostid=i.hostid and h.hostid=" ZBX_FS_UI64 " and i.key_ not in ('%s','%s','%s')", + result = DBselect("select distinct t.triggerid,t.expression,t.description,t.status,t.priority,t.value,t.url,t.comments from hosts h,items i,triggers t,functions f where f.triggerid=t.triggerid and f.itemid=i.itemid and h.hostid=i.hostid and h.hostid=" ZBX_FS_UI64 " and not i.key_ like '%s' and not i.key_ like '%s%%'", hostid, SERVER_STATUS_KEY, - SERVER_ICMPPING_KEY, - SERVER_ICMPPINGSEC_KEY); + SERVER_ICMPPING_KEY); + while((row=DBfetch(result))) { @@ -1463,7 +1463,7 @@ int DBget_queue_count(void) now=time(NULL); /* zbx_snprintf(sql,sizeof(sql),"select count(*) from items i,hosts h where i.status=%d and i.type not in (%d) and h.status=%d and i.hostid=h.hostid and i.nextcheck<%d and i.key_<>'status'", ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, HOST_STATUS_MONITORED, now);*/ - result = DBselect("select count(*) from items i,hosts h where i.status=%d and i.type not in (%d) and ((h.status=%d and h.available!=%d) or (h.status=%d and h.available=%d and h.disable_until<=%d)) and i.hostid=h.hostid and i.nextcheck<%d and i.key_ not in ('%s','%s','%s','%s')", + result = DBselect("select count(*) from items i,hosts h where i.status=%d and i.type not in (%d) and ((h.status=%d and h.available!=%d) or (h.status=%d and h.available=%d and h.disable_until<=%d)) and i.hostid=h.hostid and i.nextcheck<%d and not i.key_ like '%s' and not i.key_ like '%s%%' and not i.key_ like '%s'", ITEM_STATUS_ACTIVE, ITEM_TYPE_TRAPPER, HOST_STATUS_MONITORED, @@ -1473,8 +1473,7 @@ int DBget_queue_count(void) now, now, SERVER_STATUS_KEY, - SERVER_ICMPPING_KEY, - SERVER_ICMPPINGSEC_KEY, + SERVER_ICMPPING_KEY, SERVER_ZABBIXLOG_KEY); row=DBfetch(result); diff --git a/src/libs/zbxicmpping/icmpping.c b/src/libs/zbxicmpping/icmpping.c index f1b37bfd270..d2adaaca343 100644 --- a/src/libs/zbxicmpping/icmpping.c +++ b/src/libs/zbxicmpping/icmpping.c @@ -30,27 +30,32 @@ extern char *CONFIG_FPING6_LOCATION; #endif /* HAVE_IPV6 */ extern char *CONFIG_TMPDIR; -static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len) +static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { FILE *f; char filename[MAX_STRING_LEN], tmp[MAX_STRING_LEN], - *c, source_ip[64]; + *c, *c2, params[64]; /*usually this amount of memory is enough*/ int i; ZBX_FPING_HOST *host; + double sec; #ifdef HAVE_IPV6 char *fping; int family; #endif assert(hosts); - - zabbix_log(LOG_LEVEL_DEBUG, "In process_ping()"); - + zabbix_log(LOG_LEVEL_DEBUG, "In process_ping() [hosts_count:%d]", hosts_count); + + i = zbx_snprintf(params, sizeof(params), "-q -C%d", count); + if (0 != interval) + i += zbx_snprintf(params + i, sizeof(params) - i, " -p%d", interval); + if (0 != size) + i += zbx_snprintf(params + i, sizeof(params) - i, " -b%d", size); + if (0 != timeout) + i += zbx_snprintf(params + i, sizeof(params) - i, " -t%d", timeout); if (NULL != CONFIG_SOURCE_IP) - zbx_snprintf(source_ip, sizeof(source_ip), "-S%s ", CONFIG_SOURCE_IP); - else - *source_ip = '\0'; - + i += zbx_snprintf(params + i, sizeof(/*source_ip*/params) - i, " -S%s ", CONFIG_SOURCE_IP); + if (access(CONFIG_FPING_LOCATION, F_OK|X_OK) == -1) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", CONFIG_FPING_LOCATION, errno, strerror(errno)); @@ -77,25 +82,27 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int fping = CONFIG_FPING_LOCATION; else fping = CONFIG_FPING6_LOCATION; - - zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s", - fping, - source_ip, + + zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", + fping, + params, filename); } else - zbx_snprintf(tmp, sizeof(tmp), "%s -c3 2>/dev/null <%s;%s -c3 2>/dev/null <%s", + zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s;%s %s 2>&1 <%s", CONFIG_FPING_LOCATION, + params, filename, CONFIG_FPING6_LOCATION, + params, filename); #else /* HAVE_IPV6 */ - zbx_snprintf(tmp, sizeof(tmp), "%s %s-c3 2>/dev/null <%s", - CONFIG_FPING_LOCATION, - source_ip, + zbx_snprintf(tmp, sizeof(tmp), "%s %s 2>&1 <%s", + CONFIG_FPING_LOCATION, + params, filename); -#endif /* HAVE_IPV6 */ - +#endif /* HAVE_IPV6 */ + if (NULL == (f = fopen(filename, "w"))) { zbx_snprintf(error, max_error_len, "%s: [%d] %s", filename, errno, strerror(errno)); return NOTSUPPORTED; @@ -127,7 +134,7 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int tmp); /* 12fc::21 : [0], 76 bytes, 0.39 ms (0.39 avg, 0% loss) */ - + host = NULL; if (NULL != (c = strchr(tmp, ' '))) { @@ -137,16 +144,36 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int host = &hosts[i]; break; } + *c = ' '; } - if (NULL != host) { - c++; - if (NULL != (c = strchr(c, '('))) { - c++; - host->alive = 1; - host->sec = atof(c)/1000; + if (NULL == host) + continue; + + if (NULL == (c = strstr(tmp, " : "))) + continue; + + c += 3; + + do { + if (NULL != (c2 = strchr(c, ' '))) + *c2 = '\0'; + + if (0 != strcmp(c, "-")) + { + sec = atof(c); + + if (host->rcv == 0 || host->min > sec) + host->min = sec; + if (host->rcv == 0 || host->max < sec) + host->max = sec; + host->avg = (host->avg * host->rcv + sec)/(host->rcv + 1); + host->rcv++; } - } + + if (NULL != c2) + *c2++ = ' '; + } while (NULL != (c = c2)); } pclose(f); @@ -173,14 +200,14 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int * Comments: use external binary 'fping' to avoid superuser priviledges * * * ******************************************************************************/ -int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, char *error, int max_error_len) +int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len) { int res; zabbix_log(LOG_LEVEL_DEBUG, "In do_ping(hosts_count:%d)", hosts_count); - if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, error, max_error_len))) + if (NOTSUPPORTED == (res = process_ping(hosts, hosts_count, count, interval, size, timeout, error, max_error_len))) { zabbix_log(LOG_LEVEL_ERR, "%s", error); zabbix_syslog("%s", error); diff --git a/src/zabbix_server/discoverer/discoverer.c b/src/zabbix_server/discoverer/discoverer.c index bfd500f09d6..d9ea12a6deb 100644 --- a/src/zabbix_server/discoverer/discoverer.c +++ b/src/zabbix_server/discoverer/discoverer.c @@ -744,13 +744,30 @@ static int discover_service(DB_DCHECK *check, char *ip, int port) zbx_host_key_string_by_item(&item), value.msg); break; - case SVC_ICMPPING: + case SVC_ICMPPING: memset(&host, 0, sizeof(host)); + /* + #define ZBX_FPING_HOST struct zbx_fping_host + ZBX_FPING_HOST + { + char *addr; + double min, avg, max; + int rcv; + }; + */ + zbx_malloc(host.addr, HOST_ADDR_LEN_MAX); strscpy(host.addr, ip); - host.useip = 1; - - if (SUCCEED != do_ping(&host, 1, error, sizeof(error)) || 0 == host.alive) + /*host.useip = 1;*/ + + /*if (SUCCEED != do_ping(&host, 1, error, sizeof(error)) || 0 == host.alive) + ret = FAIL;*/ + + /*int do_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int interval, int size, int timeout, char *error, int max_error_len);*/ + /*`count is mandatory, `interval', `size', timeout' are not*/ + if (SUCCEED != do_ping(&host, 1, 3, 0, 0, 0, error, sizeof(error)) || 0 == host.rcv) ret = FAIL; + + zbx_free(host.addr); break; default: break; diff --git a/src/zabbix_server/pinger/pinger.c b/src/zabbix_server/pinger/pinger.c index 894c5950043..fe918e0582d 100644 --- a/src/zabbix_server/pinger/pinger.c +++ b/src/zabbix_server/pinger/pinger.c @@ -24,37 +24,41 @@ #include "log.h" #include "zlog.h" #include "sysinfo.h" -#include "zbxserver.h" #include "zbxicmpping.h" +#include "zbxserver.h" #include "pinger.h" #include "dbcache.h" static zbx_process_t zbx_process; -static int pinger_num; +static int pinger_num; -static ZBX_FPING_HOST *hosts = NULL; -static int hosts_allocated = 4; +/*some defines so the `fping' and `fping6' could successfully process pings*/ +#define MIN_COUNT 1 +#define MAX_COUNT 10000 +#define MIN_INTERVAL 10 +#define MIN_SIZE 24 +#define MAX_SIZE 65507 +#define MIN_TIMEOUT 50 +/*end some defines*/ /****************************************************************************** - * * - * Function: process_value * - * * - * Purpose: process new item value * - * * - * Parameters: key - item key * - * host - host name * - * value - new value of the item * - * * - * Return value: SUCCEED - new value successfully processed * - * FAIL - otherwise * - * * - * Author: Alexei Vladishev * - * * - * Comments: can be done in process_data() * - * * + * * + * Function: process_value * + * * + * Purpose: process new item value * + * * + * Parameters: itemid - id of the item to process * + * * + * Return value: SUCCEED - new value successfully processed * + * FAIL - otherwise * + * * + * Author: Alexei Vladishev, Aleksander Vladishev * + * * + * Comments: can be done in process_data() * + * * ******************************************************************************/ -static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_ui64, double *value_dbl, int now, int *items, int ping_result, const char *error) +static void process_value(zbx_uint64_t itemid, zbx_uint64_t *value_ui64, double *value_dbl, struct timeb *tp, int ping_result, char *error) { DB_RESULT result; DB_ROW row; @@ -64,10 +68,8 @@ static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_u assert(value_ui64 || value_dbl); - zabbix_log(LOG_LEVEL_DEBUG, "In process_value(%s@%s)", - key, - host->addr); - + zabbix_log(LOG_LEVEL_DEBUG, "In process_value()"); + if (0 != CONFIG_REFRESH_UNSUPPORTED) zbx_snprintf(istatus, sizeof(istatus), "%d,%d", ITEM_STATUS_ACTIVE, @@ -77,20 +79,18 @@ static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_u ITEM_STATUS_ACTIVE); result = DBselect("select %s where " ZBX_SQL_MOD(h.hostid,%d) "=%d and h.status=%d and h.hostid=i.hostid" - " and h.proxy_hostid=0 and h.useip=%d and h.%s='%s' and i.key_='%s' and i.status in (%s)" + " and i.itemid=" ZBX_FS_UI64 " and h.proxy_hostid=0 and i.status in (%s)" " and i.type=%d and i.nextcheck<=%d and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, ZBX_SQL_ITEM_SELECT, CONFIG_PINGER_FORKS, pinger_num - 1, HOST_STATUS_MONITORED, - host->useip, - host->useip ? "ip" : "dns", - host->addr, - key, + itemid, istatus, ITEM_TYPE_SIMPLE, - now, - HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, + tp->time, + HOST_MAINTENANCE_STATUS_OFF, + MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); while (NULL != (row = DBfetch(result))) { @@ -102,12 +102,12 @@ static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_u { DBbegin(); - DBupdate_item_status_to_notsupported(&item, now, error); + DBupdate_item_status_to_notsupported(&item, tp->time, error); DBcommit(); } else - DCadd_nextcheck(&item, now, 0, error); + DCadd_nextcheck(&item, (time_t)tp->time, 0, error); } else { @@ -127,10 +127,10 @@ static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_u switch (zbx_process) { case ZBX_PROCESS_SERVER: - process_new_value(&item, &value, now); + process_new_value(&item, &value, (time_t)tp->time); break; case ZBX_PROCESS_PROXY: - proxy_process_new_value(&item, &value, now); + proxy_process_new_value(&item, &value, (time_t)tp->time); break; } @@ -138,64 +138,224 @@ static void process_value(char *key, ZBX_FPING_HOST *host, zbx_uint64_t *value_u DBcommit(); if (0 != CONFIG_DBSYNCER_FORKS) - DCadd_nextcheck(&item, now, 0, NULL); + DCadd_nextcheck(&item, (time_t)tp->time, 0, NULL); free_result(&value); - } - - (*items)++; + } } DBfree_result(result); } /****************************************************************************** - * * - * Function: process_values * - * * - * Purpose: process new item value * - * * - * Parameters: * - * * - * Return value: successfully processed items * - * * - * Author: Alexei Vladishev * - * * - * Comments: can be done in process_data() * - * * + * * + * Function: process_values * + * * + * Purpose: process new item value * + * * + * Parameters: * + * * + * Return value: successfully processed items * + * * + * Author: Alexei Vladishev, Aleksander Vladishev * + * * + * Comments: can be done in process_data() * + * * ******************************************************************************/ -static int process_values(ZBX_FPING_HOST *hosts, int hosts_count, int now) +static void process_values(icmpitem_t *items, int first_index, int last_index, ZBX_FPING_HOST *hosts, int hosts_count, struct timeb *tp, int ping_result, char *error) { - int i, items = 0, ping_result; - char error[ITEM_ERROR_LEN_MAX]; - - zabbix_log(LOG_LEVEL_DEBUG, "In process_values()"); - - zbx_setproctitle("pinger [pinging hosts]"); - - ping_result = do_ping(hosts, hosts_count, error, sizeof(error)); + int i, h; + zbx_uint64_t value_uint64; + double value_dbl; + + zabbix_log(LOG_LEVEL_DEBUG, "In process_values()"); if (0 != CONFIG_DBSYNCER_FORKS) DCinit_nextchecks(); - - for (i = 0; i < hosts_count; i++) { + + for (h = 0; h < hosts_count; h++) + { if (ping_result == NOTSUPPORTED) zabbix_log(LOG_LEVEL_DEBUG, "Host [%s] %s", - hosts[i].addr, + hosts[h].addr, error); else - zabbix_log(LOG_LEVEL_DEBUG, "Host [%s] alive [" ZBX_FS_UI64 "] " ZBX_FS_DBL " sec.", - hosts[i].addr, - hosts[i].alive, - hosts[i].sec); - - process_value(SERVER_ICMPPING_KEY, &hosts[i], &hosts[i].alive, NULL, now, &items, ping_result, error); - process_value(SERVER_ICMPPINGSEC_KEY, &hosts[i], NULL, &hosts[i].sec, now, &items, ping_result, error); + zabbix_log(LOG_LEVEL_DEBUG, "Host [%s] rcv=%d min/max/avg=" ZBX_FS_DBL "/" ZBX_FS_DBL "/" ZBX_FS_DBL, + hosts[h].addr, + hosts[h].rcv, + hosts[h].min, + hosts[h].max, + hosts[h].avg); + + for (i = first_index; i < last_index; i++) + if (0 == strcmp(items[i].addr, hosts[h].addr)) + { + switch (items[i].icmpping) { + case ICMPPING: + value_uint64 = hosts[h].rcv ? 1 : 0; + process_value(items[i].itemid, &value_uint64, NULL, tp, ping_result, error); + break; + case ICMPPINGSEC: + switch (items[i].type) { + case ICMPPINGSEC_MIN : value_dbl = hosts[h].min; break; + case ICMPPINGSEC_MAX : value_dbl = hosts[h].max; break; + case ICMPPINGSEC_AVG : value_dbl = hosts[h].avg; break; + } + process_value(items[i].itemid, NULL, &value_dbl, tp, ping_result, error); + break; + case ICMPPINGLOSS: + value_dbl = 100 * (1 - (double)hosts[h].rcv / (double)items[i].count); + process_value(items[i].itemid, NULL, &value_dbl, tp, ping_result, error); + break; + } + } } - + if (0 != CONFIG_DBSYNCER_FORKS) DCflush_nextchecks(); +} + +static int parse_key_params(const char *key, const char *host_addr, icmpping_t *icmpping, char **addr, int *count, int *interval, int *size, + int *timeout, icmppingsec_type_t *type) +{ + char cmd[MAX_STRING_LEN], params[MAX_STRING_LEN], buffer[MAX_STRING_LEN]; + int num_params; + + if (0 == parse_command(key, cmd, sizeof(cmd), params, sizeof(params))) + return NOTSUPPORTED; + + num_params = num_param(params); + + if (0 == strcmp(cmd, "icmpping")) + { + if (num_params > 5) + return NOTSUPPORTED; + *icmpping = ICMPPING; + } + else if (0 == strcmp(cmd, "icmppingloss")) + { + if (num_params > 5) + return NOTSUPPORTED; + *icmpping = ICMPPINGLOSS; + } + else if (0 == strcmp(cmd, "icmppingsec")) + { + if (num_params > 6) + return NOTSUPPORTED; + *icmpping = ICMPPINGSEC; + } + else + return NOTSUPPORTED; + + if (0 != get_param(params, 2, buffer, sizeof(buffer)) || *buffer == '\0') + *count = 3; + else if ( ( ( *count = atoi(buffer) ) < MIN_COUNT ) || ( *count > MAX_COUNT ) ) + return NOTSUPPORTED; + + if (0 != get_param(params, 3, buffer, sizeof(buffer)) || *buffer == '\0') + *interval = 0; + else if ( ( *interval = atoi(buffer) ) < MIN_INTERVAL ) + return NOTSUPPORTED; + + if (0 != get_param(params, 4, buffer, sizeof(buffer)) || *buffer == '\0') + *size = 0; + else if ( ( *size = atoi(buffer) ) < MIN_SIZE || ( *size > MAX_SIZE ) ) + return NOTSUPPORTED; + + if (0 != get_param(params, 5, buffer, sizeof(buffer)) || *buffer == '\0') + *timeout = 0; + else if ( ( *timeout = atoi(buffer) ) < MIN_TIMEOUT ) + return NOTSUPPORTED; + + if (0 != get_param(params, 6, buffer, sizeof(buffer)) || *buffer == '\0') + *type = ICMPPINGSEC_AVG; + else + { + if (0 == strcmp(buffer, "min")) + *type = ICMPPINGSEC_MIN; + else if (0 == strcmp(buffer, "avg")) + *type = ICMPPINGSEC_AVG; + else if (0 == strcmp(buffer, "max")) + *type = ICMPPINGSEC_MAX; + else + return NOTSUPPORTED; + } + + if (0 != get_param(params, 1, buffer, sizeof(buffer)) || *buffer == '\0') + *addr = strdup(host_addr); + else + *addr = strdup(buffer); + + return SUCCEED; +} + +static int get_icmpping_nearestindex(icmpitem_t *items, int items_count, int count, int interval, int size, int timeout) +{ + int first_index, last_index, index; + icmpitem_t *item; + + if (items_count == 0) + return 0; + + first_index = 0; + last_index = items_count - 1; + while (1) + { + index = first_index + (last_index - first_index) / 2; + item = &items[index]; + + if (item->count == count && item->interval == interval && item->size == size && item->timeout == timeout) + return index; + else if (last_index == first_index) + { + if (item->count < count || + (item->count == count && item->interval < interval) || + (item->count == count && item->interval == interval && item->size < size) || + (item->count == count && item->interval == interval && item->size == size && item->timeout < timeout)) + index++; + return index; + } + else if (item->count < count || + (item->count == count && item->interval < interval) || + (item->count == count && item->interval == interval && item->size < size) || + (item->count == count && item->interval == interval && item->size == size && item->timeout < timeout)) + first_index = index + 1; + else + last_index = index; + } +} + +static void add_icmpping_item(icmpitem_t **items, int *items_alloc, int *items_count, int count, int interval, int size, int timeout, + zbx_uint64_t itemid, char *addr, icmpping_t icmpping, icmppingsec_type_t type) +{ + int index; + icmpitem_t *item; + size_t sz; + + zabbix_log(LOG_LEVEL_DEBUG, "In add_icmpping_item() addr=%s count=%d interval=%d size=%d timeout=%d", + addr, count, interval, size, timeout); + + index = get_icmpping_nearestindex(*items, *items_count, count, interval, size, timeout); + + if (*items_alloc == *items_count) + { + *items_alloc += 4; + sz = *items_alloc * sizeof(icmpitem_t); + *items = zbx_realloc(*items, sz); + } + + memmove(&(*items)[index + 1], &(*items)[index], sizeof(icmpitem_t) * (*items_count - index)); + + item = &(*items)[index]; + item->count = count; + item->interval = interval; + item->size = size; + item->timeout = timeout; + item->itemid = itemid; + item->addr = addr; + item->icmpping = icmpping; + item->type = type; - return items; + (*items_count)++; } /****************************************************************************** @@ -214,13 +374,20 @@ static int process_values(ZBX_FPING_HOST *hosts, int hosts_count, int now) * Comments: * * * ******************************************************************************/ -static int get_pinger_hosts(int now) +static void get_pinger_hosts(icmpitem_t **items, int *items_alloc, int *items_count, int now) { + DB_ITEM item; /*used for compatibility with `DBupdate_item_status_to_notsupported' from the trunk version*/ DB_RESULT result; DB_ROW row; - int hosts_count = 0; char istatus[16]; - + char *addr = NULL; + int count, interval, size, timeout; + icmpping_t icmpping; + icmppingsec_type_t type; + zbx_uint64_t itemid; + + memset(&item, '\0', sizeof(DB_ITEM)); + zabbix_log(LOG_LEVEL_DEBUG, "In get_pinger_hosts()"); if (0 != CONFIG_REFRESH_UNSUPPORTED) @@ -230,72 +397,41 @@ static int get_pinger_hosts(int now) else zbx_snprintf(istatus, sizeof(istatus), "%d", ITEM_STATUS_ACTIVE); - - /* Select hosts monitored by IP */ - result = DBselect("select distinct h.ip from hosts h,items i where " ZBX_SQL_MOD(h.hostid,%d) "=%d" - " and i.hostid=h.hostid and h.proxy_hostid=0 and h.status=%d and i.key_ in ('%s','%s')" - " and i.type=%d and i.status in (%s) and h.useip=1 and i.nextcheck<=%d" - " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, + + result = DBselect("select i.itemid,i.key_,case when h.useip=1 then h.ip else h.dns end" + " from hosts h,items i where " ZBX_SQL_MOD(h.hostid,%d) "=%d" + " and i.hostid=h.hostid and h.proxy_hostid=0 and h.status=%d and i.key_ like '%s%%'" + " and i.type=%d and i.status in (%s) and i.nextcheck<=%d" + " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, CONFIG_PINGER_FORKS, pinger_num - 1, HOST_STATUS_MONITORED, - SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, + SERVER_ICMPPING_KEY, ITEM_TYPE_SIMPLE, istatus, now, - HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, + HOST_MAINTENANCE_STATUS_OFF, + MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); - + while (NULL != (row = DBfetch(result))) { - if (hosts_count == hosts_allocated) { - hosts_allocated *= 2; - hosts = zbx_realloc(hosts, hosts_allocated * sizeof(ZBX_FPING_HOST)); - } - - memset(&hosts[hosts_count], '\0', sizeof(ZBX_FPING_HOST)); - strscpy(hosts[hosts_count].addr, row[0]); - hosts[hosts_count].useip = 1; - - zabbix_log(LOG_LEVEL_DEBUG, "IP [%s]", hosts[hosts_count].addr); - - hosts_count++; - } - DBfree_result(result); + itemid = zbx_atoui64(row[0]); - /* Select hosts monitored by hostname */ - result = DBselect("select distinct h.dns from hosts h,items i where " ZBX_SQL_MOD(h.hostid,%d) "=%d" - " and i.hostid=h.hostid and h.proxy_hostid=0 and h.status=%d and i.key_ in ('%s','%s')" - " and i.type=%d and i.status in (%s) and h.useip=0 and i.nextcheck<=%d" - " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, - CONFIG_PINGER_FORKS, - pinger_num - 1, - HOST_STATUS_MONITORED, - SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, - ITEM_TYPE_SIMPLE, - istatus, - now, - HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, - DBnode_local("h.hostid")); - - while (NULL != (row = DBfetch(result))) { - if (hosts_count == hosts_allocated) { - hosts_allocated *= 2; - hosts = zbx_realloc(hosts, hosts_allocated * sizeof(ZBX_FPING_HOST)); + if (SUCCEED == parse_key_params(row[1], row[2], &icmpping, &addr, &count, &interval, &size, &timeout, &type)) + add_icmpping_item(items, items_alloc, items_count, count, interval, size, timeout, itemid, addr, icmpping, type); + else + { + item.itemid = itemid; + DBbegin(); + DBupdate_item_status_to_notsupported(&item, now, NULL); + DBcommit(); + memset(&item, '\0', sizeof(DB_ITEM)); } - - memset(&hosts[hosts_count], '\0', sizeof(ZBX_FPING_HOST)); - strscpy(hosts[hosts_count].addr, row[0]); - hosts[hosts_count].useip = 0; - - zabbix_log(LOG_LEVEL_DEBUG, "DNS name [%s]", hosts[hosts_count].addr); - - hosts_count++; } + DBfree_result(result); - zabbix_log(LOG_LEVEL_DEBUG, "End of get_pinger_hosts():%d", hosts_count); - - return hosts_count; + zabbix_log(LOG_LEVEL_DEBUG, "End of get_pinger_hosts():%d", *items_count); } /****************************************************************************** @@ -304,7 +440,7 @@ static int get_pinger_hosts(int now) * * * Purpose: calculate when we have to process earliest simple check * * * - * Parameters: now - current timestamp * + * Parameters: * * * * Return value: timestamp of earliest check or -1 if not found * * * @@ -328,18 +464,19 @@ static int get_minnextcheck() ITEM_STATUS_NOTSUPPORTED); else zbx_snprintf(istatus, sizeof(istatus), "%d", - ITEM_STATUS_ACTIVE); - + ITEM_STATUS_ACTIVE); + result = DBselect("select count(*),min(i.nextcheck) from items i,hosts h where " ZBX_SQL_MOD(h.hostid,%d) "=%d" - " and h.status=%d and h.hostid=i.hostid and h.proxy_hostid=0 and i.key_ in ('%s','%s')" - " and i.type=%d and i.status in (%s) and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, + " and h.status=%d and h.hostid=i.hostid and h.proxy_hostid=0 and i.key_ like '%s%%'" + " and i.type=%d and i.status in (%s) and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE, CONFIG_PINGER_FORKS, pinger_num - 1, HOST_STATUS_MONITORED, - SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, + SERVER_ICMPPING_KEY, ITEM_TYPE_SIMPLE, istatus, - HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, + HOST_MAINTENANCE_STATUS_OFF, + MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); if (NULL == (row = DBfetch(result)) || DBis_null(row[0]) == SUCCEED || DBis_null(row[1]) == SUCCEED) @@ -363,6 +500,93 @@ static int get_minnextcheck() return res; } +static void free_hosts(icmpitem_t **items, int *items_count) +{ + int i; + + zabbix_log(LOG_LEVEL_DEBUG, "In free_hosts()"); + + for (i = 0; i < *items_count; i++) + zbx_free((*items)[i].addr); + + *items_count = 0; +} + +static void add_pinger_host(ZBX_FPING_HOST **hosts, int *hosts_alloc, int *hosts_count, char *addr) +{ + int i; + size_t sz; + ZBX_FPING_HOST *h; + + zabbix_log(LOG_LEVEL_DEBUG, "In add_pinger_host() addr=%s", addr); + + for (i = 0; i < *hosts_count; i ++) + if (0 == strcmp(addr, (*hosts)[i].addr)) + return; + + (*hosts_count)++; + + if (*hosts_alloc < *hosts_count) + { + *hosts_alloc += 4; + sz = *hosts_alloc * sizeof(ZBX_FPING_HOST); + *hosts = zbx_realloc(*hosts, sz); + } + + h = &(*hosts)[*hosts_count - 1]; + memset(h, 0, sizeof(ZBX_FPING_HOST)); + h->addr = addr; +} + +/****************************************************************************** + * * + * Function: process_pinger_hosts * + * * + * Purpose: * + * * + * Parameters: * + * * + * Return value: * + * * + * Author: Aleksander Vladishev * + * * + * Comments: * + * * + ******************************************************************************/ +static void process_pinger_hosts(icmpitem_t *items, int items_count) +{ + int i, first_index = 0, ping_result; + char error[ITEM_ERROR_LEN_MAX]; + static ZBX_FPING_HOST *hosts = NULL; + static int hosts_alloc = 4; + int hosts_count = 0; + struct timeb tp; + + zabbix_log(LOG_LEVEL_DEBUG, "In process_pinger_hosts()"); + + if (NULL == hosts) + hosts = zbx_malloc(hosts, sizeof(ZBX_FPING_HOST) * hosts_alloc); + + for (i = 0; i < items_count; i++) + { + add_pinger_host(&hosts, &hosts_alloc, &hosts_count, items[i].addr); + + if (i == items_count - 1 || items[i].count != items[i + 1].count || items[i].interval != items[i + 1].interval || + items[i].size != items[i + 1].size || items[i].timeout != items[i + 1].timeout) + { + zbx_setproctitle("pinger [pinging hosts]"); + + ftime(&tp); + ping_result = do_ping(hosts, hosts_count, items[i].count, items[i].interval, items[i].size, items[i].timeout, error, sizeof(error)); + + process_values(items, first_index, i + 1, hosts, hosts_count, &tp, ping_result, error); + + hosts_count = 0; + first_index = i + 1; + } + } +} + /****************************************************************************** * * * Function: main_pinger_loop * @@ -379,18 +603,21 @@ static int get_minnextcheck() * * ******************************************************************************/ void main_pinger_loop(zbx_process_t p, int num) -{ - int now, nextcheck, sleeptime; - int hosts_count, items; - double sec; - +{ + int now, nextcheck, sleeptime; + double sec; + static icmpitem_t *items = NULL; + static int items_alloc = 4; + int items_count = 0; + zabbix_log(LOG_LEVEL_DEBUG, "In main_pinger_loop(num:%d)", num); zbx_process = p; - pinger_num = num; - - hosts = zbx_malloc(hosts, hosts_allocated * sizeof(ZBX_FPING_HOST)); + pinger_num = num; + + if (NULL == items) + items = zbx_malloc(items, sizeof(icmpitem_t) * items_alloc); zbx_setproctitle("pinger [connecting to the database]"); @@ -400,11 +627,10 @@ void main_pinger_loop(zbx_process_t p, int num) { now = time(NULL); sec = zbx_time(); - - items = 0; - if (0 < (hosts_count = get_pinger_hosts(now))) - items = process_values(hosts, hosts_count, now); - + + get_pinger_hosts(&items, &items_alloc, &items_count, now); + process_pinger_hosts(items, items_count); + sec = zbx_time() - sec; nextcheck = get_minnextcheck(); @@ -419,12 +645,14 @@ void main_pinger_loop(zbx_process_t p, int num) else if (sleeptime > CONFIG_PINGER_FREQUENCY) sleeptime = CONFIG_PINGER_FREQUENCY; } - + zabbix_log(LOG_LEVEL_DEBUG, "Pinger spent " ZBX_FS_DBL " seconds while processing %d items." " Nextcheck after %d sec.", sec, - items, + items_count, sleeptime); + + free_hosts(&items, &items_count); if (sleeptime > 0) { zbx_setproctitle("pinger [sleeping for %d seconds]", diff --git a/src/zabbix_server/poller/poller.c b/src/zabbix_server/poller/poller.c index 1241d59e07f..ca8483e1afc 100644 --- a/src/zabbix_server/poller/poller.c +++ b/src/zabbix_server/poller/poller.c @@ -277,7 +277,8 @@ static int get_values(int now, int *nextcheck) " where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)" " and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from!=0 and h.hostid=i.hostid and h.proxy_hostid=0" - " and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)" + " and not i.key_ like '%s' and not i.key_ like '%s%%' and not i.key_ like '%s'" + " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " group by h.hostid", CONFIG_UNREACHABLE_POLLER_FORKS, poller_num-1, @@ -286,7 +287,7 @@ static int get_values(int now, int *nextcheck) ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI, HOST_STATUS_MONITORED, now, - SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, + SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; @@ -294,7 +295,8 @@ static int get_values(int now, int *nextcheck) result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)" " and i.type in (%d) and h.status=%d and h.disable_until<=%d" " and h.errors_from=0 and h.hostid=i.hostid and h.proxy_hostid=0" - " and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" + " and " ZBX_SQL_MOD(h.hostid,%d) "=%d" + " and not i.key_ like '%s' and not i.key_ like '%s%%' and not i.key_ like '%s'" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, @@ -304,7 +306,7 @@ static int get_values(int now, int *nextcheck) now, CONFIG_IPMIPOLLER_FORKS, poller_num-1, - SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, + SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); break; @@ -312,7 +314,8 @@ static int get_values(int now, int *nextcheck) result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)" " and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))" " and (h.proxy_hostid=0 or i.type in (%d))" - " and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')" + " and " ZBX_SQL_MOD(i.itemid,%d) "=%d" + " and not i.key_ like '%s' and not i.key_ like '%s%%' and not i.key_ like '%s'" " and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck", ZBX_SQL_ITEM_SELECT, now + POLLER_DELAY, @@ -324,7 +327,7 @@ static int get_values(int now, int *nextcheck) ITEM_TYPE_INTERNAL, CONFIG_POLLER_FORKS, poller_num-1, - SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY, + SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ZABBIXLOG_KEY, HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL, DBnode_local("h.hostid")); } |