示例#1
0
文件: poller.c 项目: rennhak/zabbix
/******************************************************************************
 *                                                                            *
 * 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;
}
示例#2
0
/* ARGSUSED */
void
control_dispatch_imsg(int fd, short event, void *arg)
{
	struct control_sock	*cs = arg;
	struct ctl_conn		*c;
	struct imsg		 imsg;
	struct ctl_id		 id;
	int			 n;
	int			 verbose;
	struct relayd		*env = cs->cs_env;

	if ((c = control_connbyfd(fd)) == NULL) {
		log_warn("%s: fd %d not found", __func__, fd);
		return;
	}

	if (event & EV_READ) {
		if (((n = imsg_read(&c->iev.ibuf)) == -1 && errno != EAGAIN) ||
		    n == 0) {
			control_close(fd, cs);
			return;
		}
	}

	if (event & EV_WRITE) {
		if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) {
			control_close(fd, cs);
			return;
		}
	}

	for (;;) {
		if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
			control_close(fd, cs);
			return;
		}

		if (n == 0)
			break;

		if (c->waiting) {
			log_debug("%s: unexpected imsg %d",
			    __func__, imsg.hdr.type);
			imsg_free(&imsg);
			control_close(fd, cs);
			return;
		}

		switch (imsg.hdr.type) {
		case IMSG_CTL_SHOW_SUM:
			show(c);
			break;
		case IMSG_CTL_SESSION:
			show_sessions(c);
			break;
		case IMSG_CTL_RDR_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_rdr(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_RDR_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_rdr(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_TABLE_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_table(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_TABLE_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_table(c, &id))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_HOST_DISABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (disable_host(c, &id, NULL))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_HOST_ENABLE:
			if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(id))
				fatalx("invalid imsg header len");
			memcpy(&id, imsg.data, sizeof(id));
			if (enable_host(c, &id, NULL))
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
			else {
				memcpy(imsg.data, &id, sizeof(id));
				control_imsg_forward(&imsg);
				imsg_compose_event(&c->iev, IMSG_CTL_OK,
				    0, 0, -1, NULL, 0);
			}
			break;
		case IMSG_CTL_SHUTDOWN:
		case IMSG_CTL_RELOAD:
			proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
			break;
		case IMSG_CTL_POLL:
			proc_compose(env->sc_ps, PROC_HCE, IMSG_CTL_POLL, NULL, 0);
			imsg_compose_event(&c->iev, IMSG_CTL_OK,
			    0, 0, -1, NULL, 0);
			break;
		case IMSG_CTL_NOTIFY:
			if (c->flags & CTL_CONN_NOTIFY) {
				log_debug("%s: "
				    "client requested notify more than once",
				    __func__);
				imsg_compose_event(&c->iev, IMSG_CTL_FAIL,
				    0, 0, -1, NULL, 0);
				break;
			}
			c->flags |= CTL_CONN_NOTIFY;
			break;
		case IMSG_CTL_VERBOSE:
			IMSG_SIZE_CHECK(&imsg, &verbose);

			memcpy(&verbose, imsg.data, sizeof(verbose));

			proc_forward_imsg(env->sc_ps, &imsg, PROC_PARENT, -1);
			proc_forward_imsg(env->sc_ps, &imsg, PROC_HCE, -1);
			proc_forward_imsg(env->sc_ps, &imsg, PROC_RELAY, -1);

			memcpy(imsg.data, &verbose, sizeof(verbose));
			control_imsg_forward(&imsg);
			log_verbose(verbose);
			break;
		default:
			log_debug("%s: error handling imsg %d",
			    __func__, imsg.hdr.type);
			break;
		}
		imsg_free(&imsg);
	}

	imsg_event_add(&c->iev);
}