Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Borovikov <git-no-replydmitry@zabbix.com>2009-08-10 17:50:01 +0400
committerDmitry Borovikov <git-no-replydmitry@zabbix.com>2009-08-10 17:50:01 +0400
commit712764362c9a5c60456b0a176b830faa3aa88537 (patch)
treeab7d00ac0f848b622a2440b30270bda2ffd672ec
parentc2d836594c66d3873f8eb45ecbe817115df2362d (diff)
- [DEV-416] new simple check `icmppingloss' added; ICMP ckecks now support additional parameters (Dmitry)
-rw-r--r--ChangeLog1
-rw-r--r--create/data/data.sql6
-rw-r--r--include/common.h2
-rw-r--r--include/zbxicmpping.h38
-rw-r--r--src/libs/zbxdbhigh/db.c11
-rw-r--r--src/libs/zbxicmpping/icmpping.c85
-rw-r--r--src/zabbix_server/discoverer/discoverer.c25
-rw-r--r--src/zabbix_server/pinger/pinger.c532
-rw-r--r--src/zabbix_server/poller/poller.c15
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[&lt;ip&gt;,&lt;count&gt;,&lt;interval&gt;,&lt;size&gt;,&lt;timeout&gt;]','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[&lt;ip&gt;,&lt;count&gt;,&lt;interval&gt;,&lt;size&gt;,&lt;timeout&gt;]','Returns percentage of lost ICMP ping packets');
+insert into help_items values (3,'icmppingsec[&lt;ip&gt;,&lt;count&gt;,&lt;interval&gt;,&lt;size&gt;,&lt;timeout&gt;,&lt;type&gt;]','Returns ICMP ping response time Number of seconds Example: 0.02');
insert into help_items values (3,'ftp&lt;,port&gt;','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&lt;,port&gt;','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&lt;,port&gt;','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"));
}