Example #1
0
/******************************************************************************
 *                                                                            *
 * Function: get_values                                                       *
 *                                                                            *
 * Purpose: retrieve values of metrics from monitored hosts                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: always SUCCEED                                                   *
 *                                                                            *
 ******************************************************************************/
static int get_values(int now, int *nextcheck)
{
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW	row;
	DB_ROW	row2;

	int		delay;
	int		res;
	DB_ITEM		item;
	AGENT_RESULT	agent;
	int		stop = 0, items = 0;

	static char	*unreachable_hosts = NULL;
	static int	unreachable_hosts_alloc = 32;
	int		unreachable_hosts_offset = 0;

	char		istatus[16];

	zabbix_log( LOG_LEVEL_DEBUG, "In get_values()");

	if (0 != CONFIG_DBSYNCER_FORKS)
		DCinit_nextchecks();

	now = time(NULL);
	*nextcheck = FAIL;

	if (NULL == unreachable_hosts)
		unreachable_hosts = zbx_malloc(unreachable_hosts, unreachable_hosts_alloc);
	*unreachable_hosts = '\0';

	if (0 != CONFIG_REFRESH_UNSUPPORTED)
		zbx_snprintf(istatus, sizeof(istatus), "%d,%d",
				ITEM_STATUS_ACTIVE,
				ITEM_STATUS_NOTSUPPORTED);
	else
		zbx_snprintf(istatus, sizeof(istatus), "%d",
				ITEM_STATUS_ACTIVE);

	switch (poller_type) {
	case ZBX_POLLER_TYPE_UNREACHABLE:
		result = DBselect("select h.hostid,min(i.itemid) from hosts h,items i"
				" where " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.nextcheck<=%d and i.status in (%d)"
				" and i.type in (%d,%d,%d,%d,%d) and h.status=%d and h.disable_until<=%d"
				" and h.errors_from!=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))"
				" and i.key_ not in ('%s','%s','%s','%s') and (h.maintenance_status=%d or h.maintenance_type=%d)"
				DB_NODE " group by h.hostid",
				CONFIG_UNREACHABLE_POLLER_FORKS,
				poller_num-1,
				now + POLLER_DELAY,
				ITEM_STATUS_ACTIVE,
				ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3, ITEM_TYPE_IPMI,
				HOST_STATUS_MONITORED,
				now,
				ITEM_TYPE_INTERNAL,
				SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY,
				HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL,
				DBnode_local("h.hostid"));
		break;
	case ZBX_POLLER_TYPE_IPMI:
		result = DBselect("select %s where i.nextcheck<=%d and i.status in (%s)"
				" and i.type in (%d) and h.status=%d and h.disable_until<=%d"
				" and h.errors_from=0 and h.hostid=i.hostid and (h.proxy_hostid=0 or i.type in (%d))"
				" and " ZBX_SQL_MOD(h.hostid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')"
				" and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck",
				ZBX_SQL_ITEM_SELECT,
				now + POLLER_DELAY,
				istatus,
				ITEM_TYPE_IPMI,
				HOST_STATUS_MONITORED,
				now,
				ITEM_TYPE_INTERNAL,
				CONFIG_IPMIPOLLER_FORKS,
				poller_num-1,
				SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY,
				HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL,
				DBnode_local("h.hostid"));
		break;
	default:	/* ZBX_POLLER_TYPE_NORMAL */
		result = DBselect("select %s where i.nextcheck<=%d and h.hostid=i.hostid and h.status=%d and i.status in (%s)"
				" and ((h.disable_until<=%d and h.errors_from=0 and i.type in (%d,%d,%d,%d)) or i.type in (%d,%d,%d,%d,%d))"
				" and (h.proxy_hostid=0 or i.type in (%d))"
				" and " ZBX_SQL_MOD(i.itemid,%d) "=%d and i.key_ not in ('%s','%s','%s','%s')"
				" and (h.maintenance_status=%d or h.maintenance_type=%d)" DB_NODE " order by i.nextcheck",
				ZBX_SQL_ITEM_SELECT,
				now + POLLER_DELAY,
				HOST_STATUS_MONITORED,
				istatus,
				now,
				ITEM_TYPE_ZABBIX, ITEM_TYPE_SNMPv1, ITEM_TYPE_SNMPv2c, ITEM_TYPE_SNMPv3,
				ITEM_TYPE_SIMPLE, ITEM_TYPE_INTERNAL, ITEM_TYPE_AGGREGATE, ITEM_TYPE_EXTERNAL, ITEM_TYPE_DB_MONITOR,
				ITEM_TYPE_INTERNAL,
				CONFIG_POLLER_FORKS,
				poller_num-1,
				SERVER_STATUS_KEY, SERVER_ICMPPING_KEY, SERVER_ICMPPINGSEC_KEY, SERVER_ZABBIXLOG_KEY,
				HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL,
				DBnode_local("h.hostid"));
	}

	/* Do not stop when select is made by poller for unreachable hosts */
	while((row=DBfetch(result))&&(stop==0 || poller_type == ZBX_POLLER_TYPE_UNREACHABLE))
	{
		/* This code is just to avoid compilation warining about use of uninitialized result2 */
		result2 = result;
		/* */

		/* Poller for unreachable hosts */
		if(poller_type == ZBX_POLLER_TYPE_UNREACHABLE)
		{
			result2 = DBselect("select %s where h.hostid=i.hostid and h.proxy_hostid=0 and i.itemid=%s" DB_NODE,
				ZBX_SQL_ITEM_SELECT,
				row[1],
				DBnode_local("h.hostid"));

			row2 = DBfetch(result2);

			if(!row2)
			{
				DBfree_result(result2);
				continue;
			}
			DBget_item_from_db(&item,row2);
		}
		else
		{
			DBget_item_from_db(&item,row);
			/* Skip unreachable hosts but do not break the loop. */
			if(uint64_in_list(unreachable_hosts,item.hostid) == SUCCEED)
			{
				zabbix_log( LOG_LEVEL_DEBUG, "Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
					item.hostid,item.key);
				continue;
			}
		}

		if (item.nextcheck > time(NULL))
		{
			if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck))
				*nextcheck = item.nextcheck;
			if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE)
				DBfree_result(result2);
			continue;
		}

		init_result(&agent);

		res = get_value(&item, &agent);

		now = time(NULL);

		if (res == SUCCEED)
		{
			if (HOST_AVAILABLE_TRUE != item.host_available)
			{
				DBbegin();
		
				enable_host(&item, now);
				stop = 1;

				DBcommit();
			}

			if (item.host_errors_from != 0)
			{
				DBbegin();
		
				DBexecute("update hosts set errors_from=0 where hostid=" ZBX_FS_UI64,
						item.hostid);
				stop = 1;

				DBcommit();
			}

			if (0 == CONFIG_DBSYNCER_FORKS)
				DBbegin();
		
			switch (zbx_process) {
			case ZBX_PROCESS_SERVER:
				process_new_value(&item, &agent, now);
				break;
			case ZBX_PROCESS_PROXY:
				proxy_process_new_value(&item, &agent, now);
				break;
			}

			if (0 == CONFIG_DBSYNCER_FORKS)
				DBcommit();

			if (0 != CONFIG_DBSYNCER_FORKS)
				DCadd_nextcheck(&item, now, 0, NULL);

			if (poller_type == ZBX_POLLER_TYPE_NORMAL || poller_type == ZBX_POLLER_TYPE_IPMI)
				if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck))
					*nextcheck = item.nextcheck;
		}
		else if (res == NOTSUPPORTED || res == AGENT_ERROR)
		{
			if (item.status != ITEM_STATUS_NOTSUPPORTED)
			{
				zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] is not supported by agent on host [%s] Old status [%d]",
						item.key,
						item.host_name,
						item.status);
				zabbix_syslog("Parameter [%s] is not supported by agent on host [%s]",
						item.key,
						item.host_name);
			}

			if (0 == CONFIG_DBSYNCER_FORKS)
			{
				DBbegin();
		
				DBupdate_item_status_to_notsupported(&item, now, agent.msg);

				DBcommit();
			}
			else
				DCadd_nextcheck(&item, now, 0, agent.msg);

			if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE)
				if (*nextcheck == FAIL || (item.nextcheck != 0 && *nextcheck > item.nextcheck))
					*nextcheck = item.nextcheck;

			if (HOST_AVAILABLE_TRUE != item.host_available) {
				DBbegin();
		
				enable_host(&item, now);
				stop = 1;

				DBcommit();
			}
		}
		else if (res == NETWORK_ERROR)
		{
			DBbegin();
		
			/* First error */
			if (item.host_errors_from == 0)
			{
				zabbix_log( LOG_LEVEL_WARNING, "Host [%s]: first network error, wait for %d seconds",
						item.host_name,
						CONFIG_UNREACHABLE_DELAY);
				zabbix_syslog("Host [%s]: first network error, wait for %d seconds",
						item.host_name,
						CONFIG_UNREACHABLE_DELAY);

				DBexecute("update hosts set errors_from=%d,disable_until=%d where hostid=" ZBX_FS_UI64,
						now,
						now + CONFIG_UNREACHABLE_DELAY,
						item.hostid);

				item.host_errors_from = now;

				delay = MIN(4*item.delay, 300);

				zabbix_log(LOG_LEVEL_WARNING, "Parameter [%s] will be checked after %d seconds on host [%s]",
						item.key,
						delay,
						item.host_name);

				DBexecute("update items set nextcheck=%d where itemid=" ZBX_FS_UI64,
						now + delay,
						item.itemid);
			}
			else
			{
				if (now - item.host_errors_from > CONFIG_UNREACHABLE_PERIOD)
				{
					disable_host(&item, now, agent.msg);
				}
				else
				{
					/* Still unavailable, but won't change status to UNAVAILABLE yet */
					zabbix_log(LOG_LEVEL_WARNING, "Host [%s]: another network error, wait for %d seconds",
							item.host_name,
							CONFIG_UNREACHABLE_DELAY);
					zabbix_syslog("Host [%s]: another network error, wait for %d seconds",
							item.host_name,
							CONFIG_UNREACHABLE_DELAY);

					DBexecute("update hosts set disable_until=%d where hostid=" ZBX_FS_UI64,
							now + CONFIG_UNREACHABLE_DELAY,
							item.hostid);
				}
			}

			DBcommit();

			zbx_snprintf_alloc(&unreachable_hosts, &unreachable_hosts_alloc, &unreachable_hosts_offset, 32,
					"%s" ZBX_FS_UI64,
					0 == unreachable_hosts_offset ? "" : ",",
					item.hostid);
		}
		else
		{
			zabbix_log(LOG_LEVEL_CRIT, "Unknown response code returned.");
			assert(0==1);
		}

		items++;

		/* Poller for unreachable hosts */
		if (poller_type == ZBX_POLLER_TYPE_UNREACHABLE)
		{
			/* We cannot freeit earlier because items has references to the structure */
			DBfree_result(result2);
		}
		free_result(&agent);
	}

	DBfree_result(result);

	if (0 != CONFIG_DBSYNCER_FORKS)
		DCflush_nextchecks();

	zabbix_log(LOG_LEVEL_DEBUG, "End get_values()");

	return items;
}
Example #2
0
/******************************************************************************
 *                                                                            *
 * Function: process_data                                                     *
 *                                                                            *
 * Purpose: process new item value                                            *
 *                                                                            *
 * Parameters: sockfd - descriptor of agent-server socket connection          *
 *             server - server name                                           *
 *             key - item's key                                               *
 *             value - new value of server:key                                *
 *             lastlogsize - if key=log[*], last size of log file             *
 *                                                                            *
 * Return value: SUCCEED - new value processed sucesfully                     *
 *               FAIL - otherwise                                             *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: for trapper server process                                       *
 *                                                                            *
 ******************************************************************************/
static void	process_mass_data(zbx_sock_t *sock, zbx_uint64_t proxy_hostid, AGENT_VALUE *values, int value_num,
		int *processed, time_t proxy_timediff)
{
	AGENT_RESULT	agent;
	DB_RESULT	result;
	DB_ROW		row;
	DB_ITEM		item;
	char		host_esc[MAX_STRING_LEN], key_esc[MAX_STRING_LEN];
	static char	*sql = NULL;
	static int	sql_allocated = 65536;
	int		sql_offset = 0, i;

	zabbix_log(LOG_LEVEL_DEBUG, "In process_mass_data()");

	if (NULL == sql)
		sql = zbx_malloc(sql, sql_allocated);

	DCinit_nextchecks();

	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 2048,
			"select %s where h.hostid=i.hostid and h.proxy_hostid=" ZBX_FS_UI64
			" and h.status=%d and i.status in (%d,%d)",
			ZBX_SQL_ITEM_SELECT,
			proxy_hostid,
			HOST_STATUS_MONITORED,
			ITEM_STATUS_ACTIVE, ITEM_STATUS_NOTSUPPORTED);

	if (proxy_hostid == 0)
	{
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64,
				" and i.type in (%d,%d)",
				ITEM_TYPE_TRAPPER,
				ITEM_TYPE_ZABBIX_ACTIVE);
	}
	else
	{
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 64,
				" and i.type in (%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)",
				ITEM_TYPE_ZABBIX,
				ITEM_TYPE_SNMPv1,
				ITEM_TYPE_TRAPPER,
				ITEM_TYPE_SIMPLE,
				ITEM_TYPE_SNMPv2c,
				ITEM_TYPE_SNMPv3,
				ITEM_TYPE_ZABBIX_ACTIVE,
				ITEM_TYPE_HTTPTEST,
				ITEM_TYPE_EXTERNAL,
				ITEM_TYPE_IPMI);
	}

	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, " and (");

	for (i = 0; i < value_num; i++)
	{
		DBescape_string(values[i].host_name, host_esc, sizeof(host_esc));
		DBescape_string(values[i].key, key_esc, sizeof(key_esc));
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 512,
				"(h.host='%s' and i.key_='%s') or ",
				host_esc,
				key_esc);
	}

	sql_offset -= 4;
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, ")" DB_NODE,
			DBnode_local("h.hostid"));

	result = DBselect("%s", sql);

	while (NULL != (row = DBfetch(result))) {
		DBget_item_from_db(&item, row);

		if (item.type == ITEM_TYPE_ZABBIX_ACTIVE && FAIL == zbx_tcp_check_security(sock, item.trapper_hosts, 1))
			continue;

		if (item.maintenance_status == HOST_MAINTENANCE_STATUS_ON && item.maintenance_type == MAINTENANCE_TYPE_NODATA &&
				item.maintenance_from <= values[i].clock)
			continue;

		for (i = 0; i < value_num; i++)
		{
			if (0 == strcmp(item.host_name, values[i].host_name) && 0 == strcmp(item.key_orig, values[i].key)) {
/*				zabbix_log(LOG_LEVEL_DEBUG, "Processing [%s@%s: \"%s\"]",
						item.key,
						item.host_name,
						values[i].value);*/

				if (0 == strcmp(values[i].value, "ZBX_NOTSUPPORTED"))
				{
					zabbix_log(LOG_LEVEL_WARNING, "Active parameter [%s] is not supported by agent on host [%s]",
							item.key_orig,
							item.host_name);
					zabbix_syslog("Active parameter [%s] is not supported by agent on host [%s]",
							item.key_orig,
							item.host_name);

					DCadd_nextcheck(&item, values[i].clock, proxy_timediff, "Not supported by ZABBIX agent");

					if (NULL != processed)
						(*processed)++;
				}
				else
				{
					if (0 == strncmp(item.key, "log[", 4) || 0 == strncmp(item.key, "eventlog[", 9))
					{
						item.lastlogsize = values[i].lastlogsize;
						item.timestamp = values[i].timestamp;

						calc_timestamp(values[i].value, &item.timestamp, item.logtimefmt);

						item.eventlog_severity = values[i].severity;
						item.eventlog_source = values[i].source;

/*						zabbix_log(LOG_LEVEL_DEBUG, "Value [%s] Lastlogsize [%s] Timestamp [%s]",
								values[i].value,
								item.lastlogsize,
								item.timestamp);*/
					}

					init_result(&agent);

					if (SUCCEED == set_result_type(&agent, item.value_type, item.data_type, values[i].value))
					{
						if (0 == CONFIG_DBSYNCER_FORKS)
							DBbegin();

						switch (zbx_process) {
						case ZBX_PROCESS_SERVER:
							process_new_value(&item, &agent, values[i].clock);
							break;
						case ZBX_PROCESS_PROXY:
							proxy_process_new_value(&item, &agent, values[i].clock);
							break;
						}

						if (0 == CONFIG_DBSYNCER_FORKS)
							DBcommit();

						if (NULL != processed)
							(*processed)++;

						/* only for screen Administration|Queue */
						if (item.type != ITEM_TYPE_TRAPPER && item.type != ITEM_TYPE_HTTPTEST &&
								item.value_type != ITEM_VALUE_TYPE_LOG &&
								0 != strcmp(item.key, SERVER_STATUS_KEY) &&
								0 != strcmp(item.key, SERVER_ICMPPING_KEY) &&
								0 != strcmp(item.key, SERVER_ICMPPINGSEC_KEY) &&
								0 != strcmp(item.key, SERVER_ZABBIXLOG_KEY))
							DCadd_nextcheck(&item, values[i].clock, proxy_timediff, NULL);
					}
					else
					{
						if (GET_MSG_RESULT(&agent))
							zabbix_log(LOG_LEVEL_WARNING, "Item [%s] error: %s",
									zbx_host_key_string_by_item(&item),
									agent.msg);
					}
					free_result(&agent);
			 	}
			}
		}
	}
	DBfree_result(result);

	DCflush_nextchecks();
}
Example #3
0
/******************************************************************************
 *                                                                            *
 * Function: get_values                                                       *
 *                                                                            *
 * Purpose: retrieve values of metrics from monitored hosts                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: always SUCCEED                                                   *
 *                                                                            *
 ******************************************************************************/
static int	get_values(unsigned char poller_type)
{
	const char	*__function_name = "get_values";
	DC_ITEM		items[MAX_REACHABLE_ITEMS];
	AGENT_RESULT	agent;
	zbx_uint64_t	*ids = NULL, *snmpids = NULL, *ipmiids = NULL;
	int		ids_alloc = 0, snmpids_alloc = 0, ipmiids_alloc = 0,
			ids_num = 0, snmpids_num = 0, ipmiids_num = 0,
			i, now, num, res;
	static char	*key = NULL, *ipmi_ip = NULL, *params = NULL,
			*username = NULL, *publickey = NULL, *privatekey = NULL,
			*password = NULL, *snmp_community = NULL, *snmp_oid = NULL,
			*snmpv3_securityname = NULL, *snmpv3_authpassphrase = NULL,
			*snmpv3_privpassphrase = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	DCinit_nextchecks();

	num = DCconfig_get_poller_items(poller_type, items, ZBX_POLLER_TYPE_UNREACHABLE != poller_type
								? MAX_REACHABLE_ITEMS : MAX_UNREACHABLE_ITEMS);

	for (i = 0; i < num; i++)
	{
		zbx_free(key);
		key = strdup(items[i].key_orig);
		substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
				&key, MACRO_TYPE_ITEM_KEY, NULL, 0);
		items[i].key = key;

		switch (items[i].type)
		{
			case ITEM_TYPE_SNMPv3:
				zbx_free(snmpv3_securityname);
				zbx_free(snmpv3_authpassphrase);
				zbx_free(snmpv3_privpassphrase);

				snmpv3_securityname = strdup(items[i].snmpv3_securityname_orig);
				snmpv3_authpassphrase = strdup(items[i].snmpv3_authpassphrase_orig);
				snmpv3_privpassphrase = strdup(items[i].snmpv3_privpassphrase_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_securityname, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_authpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_privpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmpv3_securityname = snmpv3_securityname;
				items[i].snmpv3_authpassphrase = snmpv3_authpassphrase;
				items[i].snmpv3_privpassphrase = snmpv3_privpassphrase;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
				zbx_free(snmp_community);
				zbx_free(snmp_oid);

				snmp_community = strdup(items[i].snmp_community_orig);
				snmp_oid = strdup(items[i].snmp_oid_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_community, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_oid, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmp_community = snmp_community;
				items[i].snmp_oid = snmp_oid;
				break;
			case ITEM_TYPE_IPMI:
				zbx_free(ipmi_ip);
				ipmi_ip = strdup(items[i].host.ipmi_ip_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&ipmi_ip, MACRO_TYPE_HOST_IPMI_IP, NULL, 0);
				items[i].host.ipmi_ip = ipmi_ip;
				break;
			case ITEM_TYPE_DB_MONITOR:
				zbx_free(params);
				params = strdup(items[i].params_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				items[i].params = params;
				break;
			case ITEM_TYPE_SSH:
				zbx_free(username);
				zbx_free(publickey);
				zbx_free(privatekey);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				publickey = strdup(items[i].publickey_orig);
				privatekey = strdup(items[i].privatekey_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&publickey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&privatekey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].publickey = publickey;
				items[i].privatekey = privatekey;
				items[i].password = password;
				items[i].params = params;
				break;
			case ITEM_TYPE_TELNET:
				zbx_free(username);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].password = password;
				items[i].params = params;
				break;
		}

		/* Skip unreachable hosts but do not break the loop. */
		switch (items[i].type)
		{
			case ITEM_TYPE_ZABBIX:
				if (SUCCEED == uint64_array_exists(ids, ids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "Zabbix Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
			case ITEM_TYPE_SNMPv3:
				if (SUCCEED == uint64_array_exists(snmpids, snmpids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "SNMP Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_IPMI:
				if (SUCCEED == uint64_array_exists(ipmiids, ipmiids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "IPMI Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			default:
				/* nothing to do */;
		}

		init_result(&agent);

		res = get_value(&items[i], &agent);
		now = time(NULL);

		if (res == SUCCEED)
		{
			activate_host(&items[i], now);

			dc_add_history(items[i].itemid, items[i].value_type, &agent, now, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_ACTIVE, now);
		}
		else if (res == NOTSUPPORTED || res == AGENT_ERROR)
		{
			if (ITEM_STATUS_NOTSUPPORTED != items[i].status)
			{
				zabbix_log(LOG_LEVEL_WARNING, "Item [%s:%s] is not supported",
						items[i].host.host, items[i].key_orig);
				zabbix_syslog("Item [%s:%s] is not supported",
						items[i].host.host, items[i].key_orig);
			}

			activate_host(&items[i], now);

			DCadd_nextcheck(items[i].itemid, now, agent.msg);	/* update error & status field in items table */
			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_NOTSUPPORTED, now);
		}
		else if (res == NETWORK_ERROR)
		{
			deactivate_host(&items[i], now, agent.msg);

			switch (items[i].type)
			{
				case ITEM_TYPE_ZABBIX:
					uint64_array_add(&ids, &ids_alloc, &ids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_SNMPv1:
				case ITEM_TYPE_SNMPv2c:
				case ITEM_TYPE_SNMPv3:
					uint64_array_add(&snmpids, &snmpids_alloc, &snmpids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_IPMI:
					uint64_array_add(&ipmiids, &ipmiids_alloc, &ipmiids_num, items[i].host.hostid, 1);
					break;
				default:
					/* nothing to do */;
			}

			DCrequeue_unreachable_item(items[i].itemid);
		}
		else
		{
			zbx_error("unknown response code returned: %d", res);
			assert(0);
		}

		free_result(&agent);
	}

	zbx_free(key);
	zbx_free(ipmi_ip);
	zbx_free(params);
	zbx_free(username);
	zbx_free(publickey);
	zbx_free(privatekey);
	zbx_free(password);
	zbx_free(snmp_community);
	zbx_free(snmp_oid);
	zbx_free(snmpv3_securityname);
	zbx_free(snmpv3_authpassphrase);
	zbx_free(snmpv3_privpassphrase);

	zbx_free(ids);
	zbx_free(snmpids);
	zbx_free(ipmiids);

	DCflush_nextchecks();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);

	return num;
}