static int	get_minnextcheck(int now)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		res = FAIL;

	result = DBselect(
			"select count(*),min(nextcheck)"
			" from drules"
			" where proxy_hostid is null"
				" and status=%d"
				" and " ZBX_SQL_MOD(druleid,%d) "=%d"
				DB_NODE,
			DRULE_STATUS_MONITORED, CONFIG_DISCOVERER_FORKS, process_num - 1,
			DBnode_local("druleid"));

	row = DBfetch(result);

	if (NULL == row || DBis_null(row[0]) == SUCCEED || DBis_null(row[1]) == SUCCEED)
		zabbix_log(LOG_LEVEL_DEBUG, "get_minnextcheck(): no items to update");
	else if (0 != atoi(row[0]))
		res = atoi(row[1]);

	DBfree_result(result);

	return res;
}
/******************************************************************************
 *                                                                            *
 * Function: get_minnextcheck                                                 *
 *                                                                            *
 * Purpose: calculate when we have to process earliest httptest               *
 *                                                                            *
 * Parameters: now - current timestamp (not used)                             *
 *                                                                            *
 * Return value: timestamp of earliest check or -1 if not found               *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	get_minnextcheck(int now)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		res;

	result = DBselect(
			"select min(t.nextcheck)"
			" from httptest t,applications a,hosts h"
			" where t.applicationid=a.applicationid"
				" and a.hostid=h.hostid"
				" and " ZBX_SQL_MOD(t.httptestid,%d) "=%d"
				" and t.status=%d"
				" and h.proxy_hostid is null"
				" and h.status=%d"
				" and (h.maintenance_status=%d or h.maintenance_type=%d)"
				DB_NODE,
			CONFIG_HTTPPOLLER_FORKS, process_num - 1,
			HTTPTEST_STATUS_MONITORED,
			HOST_STATUS_MONITORED,
			HOST_MAINTENANCE_STATUS_OFF, MAINTENANCE_TYPE_NORMAL,
			DBnode_local("t.httptestid"));

	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "No httptests to process in get_minnextcheck.");
		res = FAIL;
	}
	else
		res = atoi(row[0]);

	DBfree_result(result);

	return res;
}
Exemple #3
0
/******************************************************************************
 *                                                                            *
 * Function: get_proxy_id                                                     *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Aleksander Vladishev                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	get_proxy_id(struct zbx_json_parse *jp, zbx_uint64_t *hostid)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		host[HOST_HOST_LEN_MAX], host_esc[MAX_STRING_LEN];
	int		res = FAIL;

	if (SUCCEED == zbx_json_value_by_name(jp, ZBX_PROTO_TAG_HOST, host, sizeof(host))) {
		DBescape_string(host, host_esc, sizeof(host_esc));

		result = DBselect("select hostid from hosts where host='%s'"
				" and status in (%d)" DB_NODE,
				host_esc,
				HOST_STATUS_PROXY,
				DBnode_local("hostid"));

		if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0])) {
			*hostid	= zbx_atoui64(row[0]);
			res	= SUCCEED;
		} else
			zabbix_log(LOG_LEVEL_WARNING, "Unknown proxy \"%s\"",
					host);

		DBfree_result(result);
	} else {
		zabbix_log(LOG_LEVEL_WARNING, "Incorrect data. %s",
				zbx_json_strerror());
		zabbix_syslog("Incorrect data. %s",
				zbx_json_strerror());
	}

	return res;
}
Exemple #4
0
static int housekeeping_events(int now)
{
	int		event_history;
	DB_RESULT	result;
	DB_ROW		row1;
	int		res = SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In housekeeping_events(%d)",
		now);

	result = DBselect("select event_history from config");

	row1=DBfetch(result);
	
	if(!row1 || DBis_null(row1[0])==SUCCEED)
	{
		zabbix_log( LOG_LEVEL_ERR, "No records in table 'config'.");
		res = FAIL;
	}
	else
	{
		event_history=atoi(row1[0]);
		DBexecute ("delete from events where clock < %d", now-24*3600*event_history);
	}
	
	DBfree_result(result);
	return res;
}
Exemple #5
0
static int housekeeping_alerts(int now)
{
	int	alert_history;
	DB_RESULT	result;
	DB_ROW		row;
	int		res = SUCCEED;
	int		deleted;

	zabbix_log( LOG_LEVEL_DEBUG, "In housekeeping_alerts(%d)",
		now);

	result = DBselect("select alert_history from config");

	row=DBfetch(result);

	if(!row || DBis_null(row[0])==SUCCEED)
	{
		zabbix_log( LOG_LEVEL_ERR, "No records in table 'config'.");
		res = FAIL;
	}
	else
	{
		alert_history=atoi(row[0]);

		deleted = DBexecute("delete from alerts where clock<%d",
			now-24*3600*alert_history);
		zabbix_log( LOG_LEVEL_DEBUG, "Deleted [%ld] records from table [alerts]",
			deleted);
	}

	DBfree_result(result);
	return res;
}
/******************************************************************************
 *                                                                            *
 * Function: delete_history                                                   *
 *                                                                            *
 * Purpose: remove outdated information from historical table                 *
 *                                                                            *
 * Parameters: now - current timestamp                                        *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	delete_history(const char *table, zbx_uint64_t itemid, int keep_history, int now)
{
	const char	*__function_name = "delete_history";
	DB_RESULT       result;
	DB_ROW          row;
	int             min_clock, deleted;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' itemid:" ZBX_FS_UI64 " keep_history:%d now:%d",
		__function_name, table, itemid, keep_history, now);

	result = DBselect("select min(clock) from %s where itemid=" ZBX_FS_UI64, table, itemid);

	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
	{
		DBfree_result(result);
		return 0;
	}

	min_clock = atoi(row[0]);
	min_clock = MIN(now - keep_history * SEC_PER_DAY, min_clock + 4 * CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR);
	DBfree_result(result);

	deleted = DBexecute("delete from %s where itemid=" ZBX_FS_UI64 " and clock<%d", table, itemid, min_clock);

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

	return deleted;
}
Exemple #7
0
/******************************************************************************
 *                                                                            *
 * Function: register_host                                                    *
 *                                                                            *
 * Purpose: register host if one does not exist                               *
 *                                                                            *
 * Parameters: host ip address                                                *
 *                                                                            *
 * Return value: dhostid or 0 if we didn't add host                           *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void register_host(DB_DHOST *host,DB_DCHECK *check, zbx_uint64_t druleid, char *ip)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		hostname[MAX_STRING_LEN], hostname_esc[MAX_STRING_LEN];

	assert(host);
	assert(check);
	assert(ip);

	zabbix_log(LOG_LEVEL_DEBUG, "In register_host(ip:%s)",
		ip);

	host->dhostid=0;
	result = DBselect("select dhostid,druleid,ip,status,lastup,lastdown from dhosts where ip='%s'", ip);
	row=DBfetch(result);
	if(!row || DBis_null(row[0])==SUCCEED)
	{
		/* Add host only if service is up */
		if(check->status == DOBJECT_STATUS_UP)
		{
			alarm(CONFIG_TIMEOUT);
			zbx_gethost_by_ip(ip, hostname, sizeof(hostname));
			alarm(0);

			if (hostname[0] != '\0')
				DBescape_string(hostname, hostname_esc, sizeof(hostname_esc));
			else
				hostname_esc[0] = '\0';

			zabbix_log(LOG_LEVEL_DEBUG, "New host discovered at %s (%s)",
				ip, hostname);

			host->dhostid = DBget_maxid("dhosts","dhostid");
			DBexecute("insert into dhosts (dhostid, druleid, dns, ip) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ", '%s','%s')",
				host->dhostid,
				druleid,
				hostname_esc,
				ip);
			host->druleid	= druleid;
			strscpy(host->ip,ip);
			host->status	= 0;
			host->lastup	= 0;
			host->lastdown  = 0;
		}
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "Host is already in database");
		ZBX_STR2UINT64(host->dhostid,row[0]);
		ZBX_STR2UINT64(host->druleid,row[1]);
		strscpy(host->ip,	row[2]);
		host->status		= atoi(row[3]);
		host->lastup		= atoi(row[4]);
		host->lastdown		= atoi(row[5]);
	}
	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End register_host()");
}
/******************************************************************************
 *                                                                            *
 * Function: get_host_permission                                              *
 *                                                                            *
 * Purpose: Return user permissions for access to the host                    *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: PERM_DENY - if host or user not found,                       *
 *                   or permission otherwise                                  *
 *                                                                            *
 * Author:                                                                    *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	get_host_permission(zbx_uint64_t userid, zbx_uint64_t hostid)
{
	const char	*__function_name = "get_host_permission";
	DB_RESULT	result;
	DB_ROW		row;
	int		user_type = -1, perm = PERM_DENY;

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

	result = DBselect("select type from users where userid=" ZBX_FS_UI64,
			userid);

	if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0]))
		user_type = atoi(row[0]);

	DBfree_result(result);

	if (-1 == user_type)
		goto out;

	if (USER_TYPE_SUPER_ADMIN == user_type)
	{
		perm = PERM_MAX;
		goto out;
	}

	result = DBselect(
			"select min(r.permission)"
			" from rights r,hosts_groups hg,users_groups ug"
			" where r.groupid=ug.usrgrpid"
				" and r.id=hg.groupid"
				" and hg.hostid=" ZBX_FS_UI64
				" and ug.userid=" ZBX_FS_UI64,
			hostid, userid);

	if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0]))
		perm = atoi(row[0]);

	DBfree_result(result);
out:
	zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __function_name, zbx_permission_string(perm));

	return perm;
}
static int housekeeping_events(int now)
{
	int		event_history;
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row1;
	DB_ROW		row2;
	zbx_uint64_t	eventid;
	int		res = SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In housekeeping_events(%d)",
		now);

	result = DBselect("select event_history from config");

	row1=DBfetch(result);

	if(!row1 || DBis_null(row1[0])==SUCCEED)
	{
		zabbix_log( LOG_LEVEL_ERR, "No records in table 'config'.");
		res = FAIL;
	}
	else
	{
		event_history=atoi(row1[0]);

		result2 = DBselect("select eventid from events where clock<%d",
			now-24*3600*event_history);
		while((row2=DBfetch(result2)))
		{
			ZBX_STR2UINT64(eventid,row2[0]);

			DBexecute("delete from acknowledges where eventid=" ZBX_FS_UI64,
				eventid);

			DBexecute("delete from events where eventid=" ZBX_FS_UI64,
				eventid);
		}
		DBfree_result(result2);

	}

	DBfree_result(result);
	return res;
}
Exemple #10
0
/******************************************************************************
 *                                                                            *
 * Function: check_perm2system                                                *
 *                                                                            *
 * Purpose: Checking user permissions to access system.                       *
 *                                                                            *
 * Parameters: userid - user ID                                               *
 *                                                                            *
 * Return value: SUCCEED - prermission is positive, FAIL - otherwise          *
 *                                                                            *
 * Author:                                                                    *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	check_perm2system(zbx_uint64_t userid)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		res = SUCCEED;

	result = DBselect( "select count(g.usrgrpid) from usrgrp g,users_groups ug where ug.userid=" ZBX_FS_UI64
			" and g.usrgrpid = ug.usrgrpid and g.users_status=%d",
			userid,
			GROUP_STATUS_DISABLED);

	if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]) && atoi(row[0]) > 0)
		res = FAIL;

	DBfree_result(result);

	return res;
}
Exemple #11
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_process_rule                                        *
 *                                                                            *
 * Purpose: removes old records from a table according to the specified rule  *
 *                                                                            *
 * Parameters: now  - [IN] the current time in seconds                        *
 *             rule - [IN/OUT] the housekeeping rule specifying table to      *
 *                    clean and the required data (fields, filters, time)     *
 *                                                                            *
 * Return value: the number of deleted records                                *
 *                                                                            *
 * Author: Andris Zeila                                                       *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_process_rule(int now, zbx_hk_rule_t *rule)
{
    const char	*__function_name = "housekeeping_process_rule";

    DB_RESULT	result;
    DB_ROW		row;
    int		keep_from, deleted = 0;
    int		rc;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' filter:'%s' min_clock:%d now:%d",
               __function_name, rule->table, rule->filter, rule->min_clock, now);

    /* initialize min_clock with the oldest record timestamp from database */
    if (0 == rule->min_clock)
    {
        result = DBselect("select min(clock) from %s%s%s", rule->table,
                          ('\0' != *rule->filter ? " where " : ""), rule->filter);
        if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]))
            rule->min_clock = atoi(row[0]);
        else
            rule->min_clock = now;

        DBfree_result(result);
    }

    /* Delete the old records from database. Don't remove more than 4 x housekeeping */
    /* periods worth of data to prevent database stalling.                           */
    keep_from = now - *rule->phistory * SEC_PER_DAY;
    if (keep_from > rule->min_clock)
    {
        rule->min_clock = MIN(keep_from, rule->min_clock +
                              HK_MAX_DELETE_PERIODS * CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR);

        rc = DBexecute("delete from %s where %s%sclock<%d", rule->table, rule->filter,
                       ('\0' != *rule->filter ? " and " : ""), rule->min_clock);

        if (ZBX_DB_OK <= rc)
            deleted = rc;
    }

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

    return deleted;
}
/******************************************************************************
 *                                                                            *
 * Function: is_master_node                                                   *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - master_nodeid is a master node of current_nodeid  *
 *                FAIL - otherwise                                            *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	is_master_node(int current_nodeid, int master_nodeid)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		res = FAIL;

	result = DBselect("select masterid from nodes where nodeid=%d",
		current_nodeid);

	if (NULL != (row = DBfetch(result)))
	{
		current_nodeid = (SUCCEED == DBis_null(row[0])) ? 0 : atoi(row[0]);
		if (current_nodeid == master_nodeid)
			res = SUCCEED;
		else if (0 != current_nodeid)
			res = is_master_node(current_nodeid, master_nodeid);
	}
	DBfree_result(result);

	return res;
}
Exemple #13
0
/******************************************************************************
 *                                                                            *
 * Function: delete_history                                                   *
 *                                                                            *
 * Purpose: remove outdated information from historical table                 *
 *                                                                            *
 * Parameters: now - current timestamp                                        *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int delete_history(char *table, zbx_uint64_t itemid, int keep_history, int now)
{
	DB_RESULT       result;
	DB_ROW          row;
	int             min_clock;

	zabbix_log( LOG_LEVEL_DEBUG, "In delete_history(%s," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d)",
		table,
		itemid,
		keep_history,
		now);

	result = DBselect("select min(clock) from %s where itemid=" ZBX_FS_UI64,
		table,
		itemid);

	row=DBfetch(result);

	if(!row || DBis_null(row[0]) == SUCCEED)
	{
		DBfree_result(result);
		return 0;
	}

	min_clock = atoi(row[0]);
	DBfree_result(result);

/*	zabbix_log( LOG_LEVEL_DEBUG, "Now %d keep_history %d Itemid " ZBX_FS_UI64 " min %d new min %d",
		now,
		keep_history,
		itemid,
		min_clock,
		MIN(now-24*3600*keep_history, min_clock+4*3600*CONFIG_HOUSEKEEPING_FREQUENCY));*/

	return DBexecute("delete from %s where itemid=" ZBX_FS_UI64 " and clock<%d",
		table,
		itemid,
		MIN(now-24*3600*keep_history, min_clock+4*3600*CONFIG_HOUSEKEEPING_FREQUENCY)
	);
}
Exemple #14
0
/******************************************************************************
 *                                                                            *
 * Function: add_host_event                                                   *
 *                                                                            *
 * Purpose: generate host UP/DOWN event if required                           *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void add_host_event(char *ip)
{
	DB_RESULT	result;
	DB_ROW		row;
	DB_EVENT	event;
	int		now;
	int		status;
	zbx_uint64_t	dhostid;

	assert(ip);

	zabbix_log(LOG_LEVEL_DEBUG, "In add_host_event(ip:%s)",
		ip);

	result = DBselect("select status,dhostid from dhosts where ip='%s'",
		ip);
	row=DBfetch(result);
	if(row && DBis_null(row[0])!=SUCCEED)
	{
		now = time(NULL); 
		status = atoi(row[0]);
		ZBX_STR2UINT64(dhostid, row[1]);

		memset(&event,0,sizeof(DB_EVENT));

		event.eventid		= 0;
		event.source		= EVENT_SOURCE_DISCOVERY;
		event.object		= EVENT_OBJECT_DHOST;
		event.objectid		= dhostid;
		event.clock 		= now;
		event.value 		= status;
		event.acknowledged 	= 0;

		process_event(&event);
	}
	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End add_host_event()");
}
/******************************************************************************
 *                                                                            *
 * Function: send_history_last_id                                             *
 *                                                                            *
 * Purpose: send list of last historical tables IDs                           *
 *                                                                            *
 * Parameters: sock - opened socket of node-node connection                   *
 *             record                                                         *
 *                                                                            *
 * Return value:  SUCCEED - sent successfully                                 *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	send_history_last_id(zbx_sock_t *sock, const char *data)
{
	DB_RESULT	result;
	DB_ROW		row;
	const char	*r;
	const ZBX_TABLE	*table;
	size_t		buffer_offset;
	int		sender_nodeid = (-1), nodeid = (-1), res;

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

	buffer_alloc = 320;
	buffer = zbx_malloc(buffer, buffer_alloc);

	r = data;
	if (NULL == r)
		goto error;

	zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* constant 'ZBX_GET_HISTORY_LAST_ID' */
	if (NULL == r)
		goto error;

	zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* sender_nodeid */
	sender_nodeid = atoi(buffer);
	if (NULL == r)
		goto error;

	if (FAIL == is_direct_slave_node(sender_nodeid))
	{
		zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received data from node %d that is not a direct slave node [%s]",
				CONFIG_NODEID, sender_nodeid, data);
		goto fail;
	}

	zbx_get_next_field(&r, &buffer, &buffer_alloc, '\n'); /* nodeid */
	nodeid = atoi(buffer);
	if (NULL == r)
		goto error;

	if (FAIL == is_slave_node(CONFIG_NODEID, nodeid))
	{
		zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received data for unknown slave node %d [%s]",
				CONFIG_NODEID, nodeid, data);
		goto fail;
	}

	zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* table name */
	if (NULL == (table = DBget_table(buffer)))
		goto error;

	if (0 == (table->flags & ZBX_HISTORY))
		goto error;

	if (NULL == r)
		goto error;

	zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER); /* field name */
	if (0 != strcmp(buffer, table->recid))
		goto error;

	buffer_offset= 0;
	zbx_snprintf_alloc(&buffer, &buffer_alloc, &buffer_offset,
			"select max(%s)"
			" from %s"
			" where 1=1" DB_NODE,
			table->recid,
			table->table,
			DBnode(table->recid, nodeid));

	buffer_offset= 0;
	result = DBselect("%s", buffer);
	if (NULL != (row = DBfetch(result)))
		zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, SUCCEED == DBis_null(row[0]) ? "0" : row[0]);
	DBfree_result(result);

	if (buffer_offset == 0)
		goto error;

	alarm(CONFIG_TIMEOUT);
	res = send_data_to_node(sender_nodeid, sock, buffer);
	alarm(0);

	zbx_free(buffer);

	return res;
error:
	zabbix_log(LOG_LEVEL_ERR, "NODE %d: Received invalid record from node %d for node %d [%s]",
		CONFIG_NODEID, sender_nodeid, nodeid, data);
fail:
	buffer_offset= 0;
	zbx_strcpy_alloc(&buffer, &buffer_alloc, &buffer_offset, "FAIL");

	alarm(CONFIG_TIMEOUT);
	res = send_data_to_node(sender_nodeid, sock, buffer);
	alarm(0);

	zbx_free(buffer);

	return FAIL;
}
Exemple #16
0
/******************************************************************************
 *                                                                            *
 * Function: check_trigger_condition                                          *
 *                                                                            *
 * Purpose: check if event matches single condition                           *
 *                                                                            *
 * Parameters: event - trigger event to check                                 *
 *                                  (event->source == EVENT_SOURCE_TRIGGERS)  *
 *             condition - condition for matching                             *
 *                                                                            *
 * Return value: SUCCEED - matches, FAIL - otherwise                          *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	check_trigger_condition(DB_EVENT *event, DB_CONDITION *condition)
{
	const char	*__function_name = "check_trigger_condition";
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	condition_value;
	int		nodeid;
	char		*tmp_str = NULL;
	int		ret = FAIL;

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

	if (condition->conditiontype == CONDITION_TYPE_HOST_GROUP)
	{
		ZBX_STR2UINT64(condition_value, condition->value);

		result = DBselect(
				"select distinct hg.groupid"
				" from hosts_groups hg,hosts h,items i,functions f,triggers t"
				" where hg.hostid=h.hostid"
					" and h.hostid=i.hostid"
					" and i.itemid=f.itemid"
					" and f.triggerid=t.triggerid"
					" and t.triggerid=" ZBX_FS_UI64
					" and hg.groupid=" ZBX_FS_UI64,
				event->objectid,
				condition_value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
			if (NULL != DBfetch(result))
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_NOT_EQUAL:
			if (NULL == DBfetch(result))
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
		DBfree_result(result);
	}
	else if (condition->conditiontype == CONDITION_TYPE_HOST_TEMPLATE)
	{
		zbx_uint64_t	hostid, triggerid;

		ZBX_STR2UINT64(condition_value, condition->value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
		case CONDITION_OPERATOR_NOT_EQUAL:
			triggerid = event->objectid;

			do
			{
				result = DBselect(
						"select distinct i.hostid,t.templateid"
						" from items i,functions f,triggers t"
						" where i.itemid=f.itemid"
							" and f.triggerid=t.templateid"
							" and t.triggerid=" ZBX_FS_UI64,
						triggerid);

				if (NULL != (row = DBfetch(result)))
				{
					ZBX_STR2UINT64(hostid, row[0]);
					ZBX_STR2UINT64(triggerid, row[1]);

					if (hostid == condition_value)
					{
						ret = SUCCEED;
						break;
					}
				}
				else
					triggerid = 0;
				DBfree_result(result);
			} while (SUCCEED != ret && 0 != triggerid);

			if (CONDITION_OPERATOR_NOT_EQUAL == condition->operator)
				ret = (SUCCEED == ret) ? FAIL : SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_HOST)
	{
		ZBX_STR2UINT64(condition_value, condition->value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
		case CONDITION_OPERATOR_NOT_EQUAL:
			result = DBselect(
					"select distinct i.hostid"
					" from items i,functions f,triggers t"
					" where i.itemid=f.itemid"
						" and f.triggerid=t.triggerid"
						" and t.triggerid=" ZBX_FS_UI64
						" and i.hostid=" ZBX_FS_UI64,
					event->objectid,
					condition_value);

			if (NULL != DBfetch(result))
				ret = SUCCEED;
			DBfree_result(result);

			if (CONDITION_OPERATOR_NOT_EQUAL == condition->operator)
				ret = (SUCCEED == ret) ? FAIL : SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator, condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_TRIGGER)
	{
		zbx_uint64_t	triggerid;

		ZBX_STR2UINT64(condition_value, condition->value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
		case CONDITION_OPERATOR_NOT_EQUAL:
			if (event->objectid == condition_value)
				ret = SUCCEED;
			/* Processing of templated triggers */
			else
			{
				for (triggerid = event->objectid; 0 != triggerid && FAIL == ret;)
				{
					result = DBselect(
							"select templateid"
							" from triggers"
							" where triggerid=" ZBX_FS_UI64,
							triggerid);

					if (NULL == (row = DBfetch(result)))
						triggerid = 0;
					else
					{
						ZBX_STR2UINT64(triggerid, row[0]);
						if (triggerid == condition_value)
							ret = SUCCEED;
					}
					DBfree_result(result);
				}
			}

			if (CONDITION_OPERATOR_NOT_EQUAL == condition->operator)
				ret = (SUCCEED == ret) ? FAIL : SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator, condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_TRIGGER_NAME)
	{
		tmp_str = zbx_strdup(tmp_str, event->trigger.description);

		substitute_simple_macros(event, NULL, NULL, NULL, NULL, &tmp_str, MACRO_TYPE_TRIGGER_DESCRIPTION, NULL, 0);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_LIKE:
			if (NULL != strstr(tmp_str, condition->value))
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_NOT_LIKE:
			if (NULL == strstr(tmp_str, condition->value))
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
		zbx_free(tmp_str);
	}
	else if (condition->conditiontype == CONDITION_TYPE_TRIGGER_SEVERITY)
	{
		condition_value = atoi(condition->value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
			if (event->trigger.priority == condition_value)
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_NOT_EQUAL:
			if (event->trigger.priority != condition_value)
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_MORE_EQUAL:
			if (event->trigger.priority >= condition_value)
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_LESS_EQUAL:
			if (event->trigger.priority <= condition_value)
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_TRIGGER_VALUE)
	{
		condition_value = atoi(condition->value);

		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
			if (event->value == condition_value)
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_TIME_PERIOD)
	{
		switch (condition->operator)
		{
		case CONDITION_OPERATOR_IN:
			if (SUCCEED == check_time_period(condition->value, (time_t)NULL))
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_NOT_IN:
			if (FAIL == check_time_period(condition->value, (time_t)NULL))
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_MAINTENANCE)
	{
		switch (condition->operator) {
		case CONDITION_OPERATOR_IN:
			result = DBselect(
					"select count(*)"
					" from hosts h,items i,functions f,triggers t"
					" where h.hostid=i.hostid"
						" and h.maintenance_status=%d"
						" and i.itemid=f.itemid"
						" and f.triggerid=t.triggerid"
						" and t.triggerid=" ZBX_FS_UI64,
					HOST_MAINTENANCE_STATUS_ON,
					event->objectid);

			if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0]) && 0 != atoi(row[0]))
				ret = SUCCEED;
			DBfree_result(result);
			break;
		case CONDITION_OPERATOR_NOT_IN:
			result = DBselect(
					"select count(*)"
					" from hosts h,items i,functions f,triggers t"
					" where h.hostid=i.hostid"
						" and h.maintenance_status=%d"
						" and i.itemid=f.itemid"
						" and f.triggerid=t.triggerid"
						" and t.triggerid=" ZBX_FS_UI64,
					HOST_MAINTENANCE_STATUS_OFF,
					event->objectid);

			if (NULL != (row = DBfetch(result)) && FAIL == DBis_null(row[0]) && 0 != atoi(row[0]))
				ret = SUCCEED;
			DBfree_result(result);
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_NODE)
	{
		nodeid = get_nodeid_by_id(event->objectid);
		condition_value = atoi(condition->value);

		switch (condition->operator) {
		case CONDITION_OPERATOR_EQUAL:
			if (nodeid == condition_value)
				ret = SUCCEED;
			break;
		case CONDITION_OPERATOR_NOT_EQUAL:
			if (nodeid != condition_value)
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
	}
	else if (condition->conditiontype == CONDITION_TYPE_EVENT_ACKNOWLEDGED)
	{
		result = DBselect(
				"select acknowledged"
				" from events"
				" where acknowledged=%d"
					" and eventid=" ZBX_FS_UI64,
				atoi(condition->value),
				event->eventid);


		switch (condition->operator)
		{
		case CONDITION_OPERATOR_EQUAL:
			if (NULL != (row = DBfetch(result)))
				ret = SUCCEED;
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
		DBfree_result(result);
	}
	else if (condition->conditiontype == CONDITION_TYPE_APPLICATION)
	{
		result = DBselect(
				"select distinct a.name"
				" from applications a,items_applications i,functions f,triggers t"
				" where a.applicationid=i.applicationid"
					" and i.itemid=f.itemid"
					" and f.triggerid=t.triggerid"
					" and t.triggerid=" ZBX_FS_UI64,
				event->objectid);

		switch (condition->operator) {
		case CONDITION_OPERATOR_EQUAL:
			while (NULL != (row = DBfetch(result)))
			{
				if (0 == strcmp(row[0], condition->value))
				{
					ret = SUCCEED;
					break;
				}
			}
			break;
		case CONDITION_OPERATOR_LIKE:
			while (NULL != (row = DBfetch(result)))
			{
				if (NULL != strstr(row[0], condition->value))
				{
					ret = SUCCEED;
					break;
				}
			}
			break;
		case CONDITION_OPERATOR_NOT_LIKE:
			ret = SUCCEED;
			while (NULL != (row = DBfetch(result)))
			{
				if (NULL != strstr(row[0], condition->value))
				{
					ret = FAIL;
					break;
				}
			}
			break;
		default:
			zabbix_log(LOG_LEVEL_ERR, "Unsupported operator [%d] for condition id [" ZBX_FS_UI64 "]",
					condition->operator,
					condition->conditionid);
		}
		DBfree_result(result);
	}
	else
	{
		zabbix_log(LOG_LEVEL_ERR, "Unsupported condition type [%d] for condition id [" ZBX_FS_UI64 "]",
				condition->conditiontype,
				condition->conditionid);
	}

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

	return ret;
}
static void	execute_operations(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action)
{
	const char	*__function_name = "execute_operations";
	DB_RESULT	result;
	DB_ROW		row;
	DB_OPERATION	operation;
	int		esc_period = 0, operations = 0;
	ZBX_USER_MSG	*user_msg = NULL, *p;

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

	if (0 == action->esc_period)
	{
		result = DBselect(
				"select o.operationid,o.operationtype,o.esc_period,o.evaltype,"
					"m.operationid,m.default_msg,subject,message,mediatypeid"
				" from operations o"
					" left join opmessage m"
						" on m.operationid=o.operationid"
				" where o.actionid=" ZBX_FS_UI64
					" and o.operationtype in (%d,%d)",
				action->actionid,
				OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND);
	}
	else
	{
		escalation->esc_step++;

		result = DBselect(
				"select o.operationid,o.operationtype,o.esc_period,o.evaltype,"
					"m.operationid,m.default_msg,subject,message,mediatypeid"
				" from operations o"
					" left join opmessage m"
						" on m.operationid=o.operationid"
				" where o.actionid=" ZBX_FS_UI64
					" and o.operationtype in (%d,%d)"
					" and o.esc_step_from<=%d"
					" and (o.esc_step_to=0 or o.esc_step_to>=%d)",
				action->actionid,
				OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND,
				escalation->esc_step,
				escalation->esc_step);
	}

	while (NULL != (row = DBfetch(result)))
	{
		memset(&operation, 0, sizeof(operation));

		ZBX_STR2UINT64(operation.operationid, row[0]);
		operation.actionid = action->actionid;
		operation.operationtype = atoi(row[1]);
		operation.esc_period = atoi(row[2]);
		operation.evaltype = (unsigned char)atoi(row[3]);

		if (SUCCEED == check_operation_conditions(event, operation.operationid, operation.evaltype))
		{
			unsigned char	default_msg;
			char		*subject, *message;
			zbx_uint64_t	mediatypeid;

			zabbix_log(LOG_LEVEL_DEBUG, "Conditions match our event. Execute operation.");

			if (0 == esc_period || esc_period > operation.esc_period)
				esc_period = operation.esc_period;

			switch (operation.operationtype)
			{
				case OPERATION_TYPE_MESSAGE:
					if (SUCCEED == DBis_null(row[4]))
						break;

					default_msg = (unsigned char)atoi(row[5]);
					ZBX_DBROW2UINT64(mediatypeid, row[8]);

					if (0 == default_msg)
					{
						subject = row[6];
						message = row[7];
					}
					else
					{
						subject = action->shortdata;
						message = action->longdata;
					}

					add_object_msg(operation.operationid, mediatypeid, &user_msg, subject, message,
							event->source, event->objectid);
					break;
				case OPERATION_TYPE_COMMAND:
					execute_commands(event, action->actionid, operation.operationid, escalation->esc_step);
					break;
			}
		}
		else
			zabbix_log(LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operation.");

		operations = 1;
	}
	DBfree_result(result);

	while (NULL != user_msg)
	{
		p = user_msg;
		user_msg = user_msg->next;

		add_message_alert(escalation, event, action, p->userid, p->mediatypeid, p->subject, p->message);

		zbx_free(p->subject);
		zbx_free(p->message);
		zbx_free(p);
	}

	if (0 == action->esc_period)
	{
		escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED;
	}
	else
	{
		if (0 == operations)
		{
			result = DBselect("select operationid from operations where actionid=" ZBX_FS_UI64 " and esc_step_from>%d",
					action->actionid,
					escalation->esc_step);

			if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]))
				operations = 1;

			DBfree_result(result);
		}

		if (1 == operations)
		{
			esc_period = (0 != esc_period) ? esc_period : action->esc_period;
			escalation->nextcheck = time(NULL) + esc_period;
		}
		else
			escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED;
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Exemple #18
0
/******************************************************************************
 *                                                                            *
 * Function: update_checksums                                                 *
 *                                                                            *
 * Purpose: overwrite old checksums with new ones                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - calculated successfully                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int update_checksums(int nodeid, int synked_nodetype, int synked, const char *tablename, const zbx_uint64_t id, char *fields)
{
	const char	*__function_name = "update_checksums";
	char		*r[2], *d[2], sync[129], *s;
	char		c[2], sql[2][256];
	char		cksum[32*64+32], *ck;
	char		*exsql = NULL;
	int		exsql_alloc = 65536, exsql_offset = 0, cksumtype;
	DB_RESULT	result;
	DB_ROW		row;
	int		f;
	const ZBX_TABLE	*table;

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

	exsql = zbx_malloc(exsql, exsql_alloc);

	DBbegin();

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 8, "begin\n");
#endif

	c[0] = synked == SUCCEED ? '1' : ' ';	/* for new and updated records */
	c[1] = synked == SUCCEED ? '2' : ' ';	/* for deleted records */

	if (NULL != tablename) {
		zbx_snprintf(sql[0], sizeof(sql[0]), " and curr.tablename='%s' and curr.recordid=" ZBX_FS_UI64,
			tablename, id);
		zbx_snprintf(sql[1], sizeof(sql[1]), " and prev.tablename='%s' and prev.recordid=" ZBX_FS_UI64,
			tablename, id);
	} else {
		*sql[0] = '\0';
		*sql[1] = '\0';
	}

	/* Find updated records */
	result = DBselect("select curr.tablename,curr.recordid,prev.cksum,curr.cksum,prev.sync "
		"from node_cksum curr, node_cksum prev "
		"where curr.nodeid=%d and prev.nodeid=curr.nodeid and "
		"curr.tablename=prev.tablename and curr.recordid=prev.recordid and "
		"curr.cksumtype=%d and prev.cksumtype=%d%s "
		"union all "
	/* Find new records */
		"select curr.tablename,curr.recordid,prev.cksum,curr.cksum,NULL "
		"from node_cksum curr left join node_cksum prev "
		"on prev.nodeid=curr.nodeid and prev.tablename=curr.tablename and "
		"prev.recordid=curr.recordid and prev.cksumtype=%d "
		"where curr.nodeid=%d and curr.cksumtype=%d and prev.tablename is null%s "
		"union all "
	/* Find deleted records */
		"select prev.tablename,prev.recordid,prev.cksum,curr.cksum,prev.sync "
		"from node_cksum prev left join node_cksum curr "
		"on curr.nodeid=prev.nodeid and curr.tablename=prev.tablename and "
		"curr.recordid=prev.recordid and curr.cksumtype=%d "
		"where prev.nodeid=%d and prev.cksumtype=%d and curr.tablename is null%s",
		nodeid, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD, sql[0],
		NODE_CKSUM_TYPE_OLD, nodeid, NODE_CKSUM_TYPE_NEW, sql[0],
		NODE_CKSUM_TYPE_NEW, nodeid, NODE_CKSUM_TYPE_OLD, sql[1]);

	while (NULL != (row = DBfetch(result)))
	{
		/* Found table */
		if (NULL == (table = DBget_table(row[0])))
		{
			zabbix_log(LOG_LEVEL_WARNING, "Cannot find table [%s]",
					row[0]);
			continue;
		}

		if (FAIL == DBis_null(row[4]))
			zbx_strlcpy(sync, row[4], sizeof(sync));
		else
			memset(sync, ' ', sizeof(sync));

		s = sync;
		ck = cksum;
		*ck = '\0';

		/* Special (simpler) processing for operation DELETE */
		if (SUCCEED == DBis_null(row[3]))
		{
			if (synked == SUCCEED)
			{
				if (synked_nodetype == ZBX_NODE_SLAVE)
					s[0] = c[1];
				else if (synked_nodetype == ZBX_NODE_MASTER)
					s[1] = c[1];
			}

			if ((0 == CONFIG_MASTER_NODEID || s[1] == c[1]) &&
					(CONFIG_NODEID == nodeid || s[0] == c[1]))
			{
				zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 256,
						"delete from node_cksum"
						" where nodeid=%d"
							" and cksumtype=%d"
							" and tablename='%s'"
							" and recordid=%s;\n",
						nodeid, NODE_CKSUM_TYPE_OLD, row[0], row[1]);

				DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset);
				continue;
			}

			s += 2;
		}
		else
		{
			r[0] = DBis_null(row[2]) == SUCCEED ? NULL : row[2];
			r[1] = row[3];
			f = 0;

			do {
				while ((table->fields[f].flags & ZBX_SYNC) == 0)
					f++;

				d[0] = NULL;
				d[1] = NULL;
				if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ',')))
					*d[0] = '\0';
				if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ',')))
					*d[1] = '\0';

				if (NULL == tablename || SUCCEED == str_in_list(fields, table->fields[f].name, ','))
				{
					ck += zbx_snprintf(ck, 64, "%s,", NULL != r[1] ? r[1] : r[0]);

					if (r[0] == NULL || r[1] == NULL || strcmp(r[0], r[1]) != 0)
					{
						if (synked_nodetype == ZBX_NODE_SLAVE)
						{
							s[0] = c[0];
							s[1] = ' ';
						}
						else if (synked_nodetype == ZBX_NODE_MASTER)
						{
							s[0] = ' ';
							s[1] = c[0];
						}
					}
					else
					{
						if (synked == SUCCEED)
						{
							if (synked_nodetype == ZBX_NODE_SLAVE)
								s[0] = c[0];
							else if (synked_nodetype == ZBX_NODE_MASTER)
								s[1] = c[0];
						}
					}
				}
				else
					ck += zbx_snprintf(ck, 64, "%s,", NULL != r[0] ? r[0] : "");
				s += 2;
				f++;

				if (d[0] != NULL)
				{
					*d[0] = ',';
					r[0] = d[0] + 1;
				}
				else
					r[0] = NULL;

				if (d[1] != NULL)
				{
					*d[1] = ',';
					r[1] = d[1] + 1;
				}
				else
					r[1] = NULL;
			} while (d[0] != NULL || d[1] != NULL);

			*--ck = '\0';
		}

		*s = '\0';

		if (SUCCEED == DBis_null(row[2]) || SUCCEED == DBis_null(row[3]) ||
				0 != strcmp(row[4], sync) || 0 != strcmp(row[2], row[3]))
		{
			cksumtype = (DBis_null(row[2]) == SUCCEED) ? NODE_CKSUM_TYPE_NEW : NODE_CKSUM_TYPE_OLD;
			zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 2560,
					"update node_cksum"
					" set cksumtype=%d,"
						"cksum='%s',"
						"sync='%s'"
					" where nodeid=%d"
						" and cksumtype=%d"
						" and tablename='%s'"
						" and recordid=%s;\n",
					NODE_CKSUM_TYPE_OLD, cksum, sync,
					nodeid, cksumtype, row[0], row[1]);

			DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset);
		}
	}
	DBfree_result(result);

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset, 8, "end;\n");
#endif

	if (exsql_offset > 16) /* In ORACLE always present begin..end; */
		DBexecute("%s", exsql);
	zbx_free(exsql);

	DBcommit();

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

	return SUCCEED;
}
Exemple #19
0
/******************************************************************************
 *                                                                            *
 * Function: get_config_data                                                  *
 *                                                                            *
 * Purpose: obtain configuration changes to required node                     *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - processed successfully                             *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
char	*get_config_data(int nodeid, int dest_nodetype)
{
	const char	*__function_name = "get_config_data";
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row;
	DB_ROW		row2;
	const ZBX_TABLE	*table;

	char	*data = NULL, *hex = NULL, *sql = NULL, c[2], sync[129], *s, *r[2], *d[2];
	int	data_offset = 0, sql_offset = 0;
	int	data_allocated = 1024, hex_allocated = 1024, sql_allocated = 8192;
	int	f, j, rowlen;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() node:%d dest_nodetype:%s", __function_name,
			nodeid, (dest_nodetype == ZBX_NODE_MASTER) ? "MASTER" : "SLAVE");

	data = zbx_malloc(data, data_allocated);
	hex = zbx_malloc(hex, hex_allocated);
	sql = zbx_malloc(sql, sql_allocated);
	c[0] = '1';	/* for new and updated records */
	c[1] = '2';	/* for deleted records */

	zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 16, "Data%c%d%c%d",
			ZBX_DM_DELIMITER, CONFIG_NODEID, ZBX_DM_DELIMITER, nodeid);

	/* Find updated records */
	result = DBselect("select curr.tablename,curr.recordid,prev.cksum,curr.cksum,prev.sync "
		"from node_cksum curr, node_cksum prev "
		"where curr.nodeid=%d and prev.nodeid=curr.nodeid and "
		"curr.tablename=prev.tablename and curr.recordid=prev.recordid and "
		"curr.cksumtype=%d and prev.cksumtype=%d "
		"union all "
	/* Find new records */
		"select curr.tablename,curr.recordid,prev.cksum,curr.cksum,curr.sync "
		"from node_cksum curr left join node_cksum prev "
		"on prev.nodeid=curr.nodeid and prev.tablename=curr.tablename and "
		"prev.recordid=curr.recordid and prev.cksumtype=%d "
		"where curr.nodeid=%d and curr.cksumtype=%d and prev.tablename is null "
		"union all "
	/* Find deleted records */
		"select prev.tablename,prev.recordid,prev.cksum,curr.cksum,prev.sync "
		"from node_cksum prev left join node_cksum curr "
		"on curr.nodeid=prev.nodeid and curr.tablename=prev.tablename and "
		"curr.recordid=prev.recordid and curr.cksumtype=%d "
		"where prev.nodeid=%d and prev.cksumtype=%d and curr.tablename is null",
		nodeid, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD,
		NODE_CKSUM_TYPE_OLD, nodeid, NODE_CKSUM_TYPE_NEW,
		NODE_CKSUM_TYPE_NEW, nodeid, NODE_CKSUM_TYPE_OLD);

	while (NULL != (row = DBfetch(result)))
	{
		/* Found table */
		if (NULL == (table = DBget_table(row[0])))
		{
			zabbix_log(LOG_LEVEL_WARNING, "Cannot find table [%s]",
					row[0]);
			continue;
		}

		if (FAIL == DBis_null(row[4]))
			zbx_strlcpy(sync, row[4], sizeof(sync));
		else
			memset(sync, ' ', sizeof(sync));

		s = sync;

		/* Special (simpler) processing for operation DELETE */
		if (SUCCEED == DBis_null(row[3]))
		{
			if ((dest_nodetype == ZBX_NODE_SLAVE && s[0] != c[1]) ||
					(dest_nodetype == ZBX_NODE_MASTER && s[1] != c[1]))
			{
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n%s%c%s%c%d",
						row[0], ZBX_DM_DELIMITER,
						row[1], ZBX_DM_DELIMITER,
						NODE_CONFIGLOG_OP_DELETE);
			}
			continue;
		}

		r[0] = (SUCCEED == DBis_null(row[2]) ? NULL : row[2]);
		r[1] = row[3];
		f = 0;
		sql_offset = 0;

		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "select ");
		do
		{
			while (0 == (table->fields[f].flags & ZBX_SYNC))
				f++;

			d[0] = NULL;
			d[1] = NULL;
			if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ',')))
				*d[0] = '\0';
			if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ',')))
				*d[1] = '\0';

			if (NULL == r[0] || NULL == r[1] ||
					(ZBX_NODE_SLAVE == dest_nodetype && s[0] != c[0]) ||
					(ZBX_NODE_MASTER == dest_nodetype && s[1] != c[0]) ||
					0 != strcmp(r[0], r[1]))
			{
				zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "%s,",
						table->fields[f].name);

				if (table->fields[f].type == ZBX_TYPE_BLOB)
				{
					zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, "length(%s),",
							table->fields[f].name);
				}
			}
			s += 2;
			f++;

			if (d[0] != NULL)
			{
				*d[0] = ',';
				r[0] = d[0] + 1;
			}
			else
				r[0] = NULL;
			if (d[1] != NULL)
			{
				*d[1] = ',';
				r[1] = d[1] + 1;
			}
			else
				r[1] = NULL;
		}
		while (NULL != d[0] || NULL != d[1]);

		if (sql[sql_offset-1] != ',')
			continue;

		sql_offset--;
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128, " from %s where %s=%s",
			row[0],
			table->recid,
			row[1]);

		result2 = DBselect("%s", sql);
		if (NULL == (row2 = DBfetch(result2)))
			goto out;

		zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n%s%c%s%c%d",
			row[0],
			ZBX_DM_DELIMITER,
			row[1],
			ZBX_DM_DELIMITER,
			NODE_CONFIGLOG_OP_UPDATE);

		r[0] = DBis_null(row[2]) == SUCCEED ? NULL : row[2];
		r[1] = row[3];
		s = sync;
		f = 0;
		j = 0;

		do
		{
			while ((table->fields[f].flags & ZBX_SYNC) == 0)
				f++;

			d[0] = NULL;
			d[1] = NULL;
			if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ',')))
				*d[0] = '\0';
			if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ',')))
				*d[1] = '\0';

			if (r[0] == NULL || r[1] == NULL || (dest_nodetype == ZBX_NODE_SLAVE && *s != c[0]) ||
				(dest_nodetype == ZBX_NODE_MASTER && *(s+1) != c[0]) || strcmp(r[0], r[1]) != 0) {

				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%c%s%c%d%c",
						ZBX_DM_DELIMITER, table->fields[f].name,
						ZBX_DM_DELIMITER, table->fields[f].type,
						ZBX_DM_DELIMITER);

				/* Fieldname, type, value */
				if (SUCCEED == DBis_null(row2[j]))
				{
					zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 5, "NULL");
				}
				else if (table->fields[f].type == ZBX_TYPE_INT ||
					table->fields[f].type == ZBX_TYPE_UINT ||
					table->fields[f].type == ZBX_TYPE_ID ||
					table->fields[f].type == ZBX_TYPE_FLOAT)
				{
					zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "%s", row2[j]);
				}
				else
				{
					if (ZBX_TYPE_BLOB == table->fields[f].type)
						rowlen = atoi(row2[j + 1]);
					else
						rowlen = strlen(row2[j]);
					zbx_binary2hex((u_char *)row2[j], rowlen, &hex, &hex_allocated);
					zbx_snprintf_alloc(&data, &data_allocated, &data_offset, strlen(hex) + 128, "%s", hex);
				}

				if (ZBX_TYPE_BLOB == table->fields[f].type)
					j += 2;
				else
					j++;
			}
			s += 2;
			f++;

			if (NULL != d[0])
			{
				*d[0] = ',';
				r[0] = d[0] + 1;
			}
			else
				r[0] = NULL;

			if (NULL != d[1])
			{
				*d[1] = ',';
				r[1] = d[1] + 1;
			}
			else
				r[1] = NULL;
		}
		while (NULL != d[0] || NULL != d[1]);
out:
		DBfree_result(result2);
	}
	DBfree_result(result);

	zbx_free(hex);
	zbx_free(sql);

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

	return data;
}
Exemple #20
0
/******************************************************************************
 *                                                                            *
 * Function: update_functions                                                 *
 *                                                                            *
 * Purpose: re-calculate and updates values of functions related to the item  *
 *                                                                            *
 * Parameters: item - item to update functions for                            *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	update_functions(DB_ITEM *item, time_t now)
{
	DB_FUNCTION	function;
	DB_RESULT	result;
	DB_ROW		row;
	char		value[MAX_STRING_LEN];
	char		*value_esc, *function_esc, *parameter_esc;
	char		*lastvalue;
	int		ret=SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In update_functions(" ZBX_FS_UI64 ")",
		item->itemid);

/* Oracle does'n support this */
/*	zbx_snprintf(sql,sizeof(sql),"select function,parameter,itemid,lastvalue from functions where itemid=%d group by function,parameter,itemid order by function,parameter,itemid",item->itemid);*/
	result = DBselect("select distinct function,parameter,itemid,lastvalue from functions where itemid=" ZBX_FS_UI64,
		item->itemid);

	while((row=DBfetch(result)))
	{
		function.function=row[0];
		function.parameter=row[1];
		ZBX_STR2UINT64(function.itemid,row[2]);
/*		function.itemid=atoi(row[2]); */
/*		It is not required to check lastvalue for NULL here */
		lastvalue=row[3];

		zabbix_log( LOG_LEVEL_DEBUG, "ItemId:" ZBX_FS_UI64 " Evaluating %s(%s)",
			function.itemid,
			function.function,
			function.parameter);

		ret = evaluate_function(value, item, function.function, function.parameter, now);
		if( FAIL == ret)	
		{
			zabbix_log( LOG_LEVEL_DEBUG, "Evaluation failed for function:%s",
				function.function);
			continue;
		}
		if (ret == SUCCEED)
		{
			/* Update only if lastvalue differs from new one */
			if (DBis_null(lastvalue) == SUCCEED || 0 != strcmp(lastvalue, value))
			{
				value_esc = DBdyn_escape_string_len(value, FUNCTION_LASTVALUE_LEN);
				function_esc = DBdyn_escape_string(function.function);
				parameter_esc = DBdyn_escape_string(function.parameter);

				DBexecute("update functions set lastvalue='%s' where itemid=" ZBX_FS_UI64 " and function='%s' and parameter='%s'",
						value_esc,
						function.itemid,
						function_esc,
						parameter_esc);

				zbx_free(parameter_esc);
				zbx_free(function_esc);
				zbx_free(value_esc);
			}
			else
				zabbix_log( LOG_LEVEL_DEBUG, "Do not update functions, same value");
		}
	}

	DBfree_result(result);

	zabbix_log( LOG_LEVEL_DEBUG, "End update_functions()");
}
Exemple #21
0
static void	execute_operations(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action)
{
	DB_RESULT	result;
	DB_ROW		row;
	DB_OPERATION	operation;
	int		esc_period = 0, operations = 0;
	ZBX_USER_MSG	*user_msg = NULL, *p;
	char		*shortdata, *longdata;

	if (0 == action->esc_period)
	{
		result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata"
				",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64 " and operationtype in (%d,%d)",
				action->actionid,
				OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND);
	}
	else
	{
		escalation->esc_step++;

		result = DBselect("select operationid,operationtype,object,objectid,default_msg,shortdata,longdata"
				",esc_period,evaltype from operations where actionid=" ZBX_FS_UI64 " and operationtype in (%d,%d)"
				" and esc_step_from<=%d and (esc_step_to=0 or esc_step_to>=%d)",
				action->actionid,
				OPERATION_TYPE_MESSAGE, OPERATION_TYPE_COMMAND,
				escalation->esc_step,
				escalation->esc_step);
	}

	while (NULL != (row = DBfetch(result))) {
		memset(&operation, 0, sizeof(operation));
		ZBX_STR2UINT64(operation.operationid, row[0]);
		operation.actionid	= action->actionid;
		operation.operationtype	= atoi(row[1]);
		operation.object	= atoi(row[2]);
		ZBX_STR2UINT64(operation.objectid, row[3]);
		operation.default_msg	= atoi(row[4]);
		operation.shortdata	= strdup(row[5]);
		operation.longdata	= strdup(row[6]);
		operation.esc_period	= atoi(row[7]);
		operation.evaltype	= atoi(row[8]);

		if (SUCCEED == check_operation_conditions(event, &operation)) {
			zabbix_log(LOG_LEVEL_DEBUG, "Conditions match our event. Execute operation.");

			substitute_macros(event, action, NULL, &operation.shortdata);
			substitute_macros(event, action, NULL, &operation.longdata);

			if (0 == esc_period || esc_period > operation.esc_period)
				esc_period = operation.esc_period;

			switch (operation.operationtype) {
				case	OPERATION_TYPE_MESSAGE:
					if (0 == operation.default_msg) {
						shortdata = operation.shortdata;
						longdata = operation.longdata;
					} else {
						shortdata = action->shortdata;
						longdata = action->longdata;
					}

					add_object_msg(event->source, escalation->triggerid, &operation, &user_msg, shortdata, longdata);
					break;
				case	OPERATION_TYPE_COMMAND:
					add_command_alert(escalation, event, action, operation.longdata);
					break;
				default:
					break;
			}
		} else
			zabbix_log(LOG_LEVEL_DEBUG, "Conditions do not match our event. Do not execute operation.");

		zbx_free(operation.shortdata);
		zbx_free(operation.longdata);

		operations = 1;
	}

	DBfree_result(result);

	while (NULL != user_msg) {
		p = user_msg;
		user_msg = user_msg->next;

		add_message_alert(escalation, event, action, p->userid, p->mediatypeid, p->subject, p->message);

		zbx_free(p->subject);
		zbx_free(p->message);
		zbx_free(p);
	}

	if (0 == action->esc_period) {
		escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED;
	} else {
		if (0 == operations) {
			result = DBselect("select operationid from operations where actionid=" ZBX_FS_UI64 " and esc_step_from>%d",
					action->actionid,
					escalation->esc_step);

			if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]))
				operations = 1;

			DBfree_result(result);
		}

		if (1 == operations) {
			esc_period = (0 != esc_period) ? esc_period : action->esc_period;
			escalation->nextcheck = time(NULL) + esc_period;
		} else
			escalation->status = (action->recovery_msg == 1) ? ESCALATION_STATUS_SLEEP : ESCALATION_STATUS_COMPLETED;
	}
}
Exemple #22
0
/******************************************************************************
 *                                                                            *
 * Function: ja_log                                                           *
 *                                                                            *
 * Purpose: output a message to the log file                                  *
 *          it also performs error notification app                           *
 *                                                                            *
 * Parameters: message_id (in) - message id                                   *
 *             inner_jobnet_id (in) - inner jobnet id                         *
 *             jobnet_id (in) - jobnet id                                     *
 *             inner_job_id (in) - inner job id                               *
 *             ... - additional information (variable parameters)             *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - Processing error occurs                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	ja_log(char *message_id, zbx_uint64_t inner_jobnet_id, char *jobnet_id, zbx_uint64_t inner_job_id, ...)
{
	FILE		*fp;
	struct tm	*tm;
	time_t		now;
	DIR		*dir;
	struct dirent	*dp;
	va_list		ap;
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row;
	DB_ROW		row2;
	int		log_type, log_level, send_flag, rc, hit, m, n, cnt, job_type, host_flag, get_host_flag;
	int		state, zbxsnd;
	zbx_uint64_t	w_inner_jobnet_id, inner_jobnet_main_id;
	char		*now_date, *message = NULL, *name = NULL, *type = NULL, *send = NULL, *msg = NULL;
	char		*after_value_esc, *user_name_esc, *host_name_esc, *jobnet_name_esc, *job_name_esc;
	char		s_jobnet_id[JA_DATA_BUFFER_LEN] = "none";
	char		s_user_name[JA_DATA_BUFFER_LEN] = "none";
	char		s_job_id[JA_DATA_BUFFER_LEN] = "none";
	char		s_job_id_full[JA_DATA_BUFFER_LEN] = "none";
	char		line[AP_MESSAGE_BUF_SIZE];
	char		cmd[AP_MESSAGE_BUF_SIZE];
	char		host_name[JA_DATA_BUFFER_LEN] = "";
	char		jobnet_name[JA_JOBNET_NAME_LEN] = "";
	char		job_name[JA_JOB_NAME_LEN] = "";
	char		now_time[20];
	const char	*__function_name = "ja_log";

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() message_id: %s inner_jobnet_id: " ZBX_FS_UI64 " inner_job_id: " ZBX_FS_UI64,
	           __function_name, message_id, inner_jobnet_id, inner_job_id);

	w_inner_jobnet_id    = inner_jobnet_id;
	inner_jobnet_main_id = 0;

	/* message file open */
	fp = fopen(CONFIG_JA_LOG_MESSAGE_FILE, "r");
	if (fp == NULL)
	{
		zabbix_log(LOG_LEVEL_ERR, "failed to open the log message file: [%s] (%s)", CONFIG_JA_LOG_MESSAGE_FILE, strerror(errno));
		return FAIL;
	}

	/* message get */
	cnt = 0;
	hit = 0;
	while (fgets(line, sizeof(line), fp) != NULL)
	{
		cnt = cnt + 1;

		if (line[0] == '#' || line[0] == '\n' || line[0] == '\r' )
		{
			continue;
		}

		if (strlen(line) > 0)
		{
			if (line[strlen(line)-1] == '\n')
			{
				line[strlen(line)-1] = '\0';
			}
		}

		if (strlen(line) > 0)
		{
			if (line[strlen(line)-1] == '\r')
			{
				line[strlen(line)-1] = '\0';
			}
		}

		n = 0;
		m = 0;
		name = line;
		type = NULL;
		send = NULL;
		msg  = NULL;
		while (line[++n])
		{
			if (line[n] == ',')
			{
				if (m == 0)
				{
					line[n] = '\0';
					type = &line[n + 1];
					m++;
				}
				else if (m == 1)
				{
					line[n] = '\0';
					send = &line[n + 1];
					m++;
				}
				else if (m == 2)
				{
					line[n] = '\0';
					msg = &line[n + 1];
					break;
				}
			}
		}

		lrtrim_spaces(name);

		if (strcmp(name, message_id) == 0)
		{
			hit = 1;
			break;
		}
	}
	fclose(fp);

	/* message hit check */
	if (hit == 0)
	{
		zabbix_log(LOG_LEVEL_ERR, "could not find an appropriate message: [%s]", message_id);
		return FAIL;
	}

	/* message get check */
	if (name == NULL || type == NULL || send == NULL || msg == NULL)
	{
		zabbix_log(LOG_LEVEL_ERR, "line data in the message file is invalid: line(%d) id[%s] file[%s]",
			cnt, message_id, CONFIG_JA_LOG_MESSAGE_FILE);
		return FAIL;
	}

	lrtrim_spaces(type);
	lrtrim_spaces(send);

	/* check the empty data */
	if (strlen(type) <= 0 || strlen(send) <= 0 || strlen(msg) <= 0)
	{
		zabbix_log(LOG_LEVEL_ERR, "line data in the message file is invalid: line(%d) id[%s] file[%s]",
			cnt, message_id, CONFIG_JA_LOG_MESSAGE_FILE);
		return FAIL;
	}

	/* log type check */
	log_level = LOG_LEVEL_INFORMATION;
	log_type  = atoi(type);
	switch (log_type)
	{
		case JALOG_TYPE_INFO:
			log_level = LOG_LEVEL_INFORMATION;
			break;

		case JALOG_TYPE_CRIT:
			log_level = LOG_LEVEL_CRIT;
			break;

		case JALOG_TYPE_ERR:
			log_level = LOG_LEVEL_ERR;
			break;

		case JALOG_TYPE_WARN:
			log_level = LOG_LEVEL_WARNING;
			break;

		case JALOG_TYPE_DEBUG:
			log_level = LOG_LEVEL_DEBUG;
			break;

		default:
			zabbix_log(LOG_LEVEL_ERR, "detected an invalid log type: line(%d) type[%s] id[%s] file[%s]",
				cnt, type, message_id, CONFIG_JA_LOG_MESSAGE_FILE);
			return FAIL;
	}

	/* send flad check */
	send_flag = atoi(send);
	if (send_flag == JASENDER_OFF || send_flag == JASENDER_ON)
	{
		/* OK */
	}
	else
	{
		zabbix_log(LOG_LEVEL_ERR, "detected an invalid jasender flag: line(%d) flag[%s] id[%s] file[%s]",
			cnt, send, message_id, CONFIG_JA_LOG_MESSAGE_FILE);
		return FAIL;
	}

	/* message body edit */
	va_start(ap, inner_job_id);
	message = zbx_dvsprintf(message, msg, ap);
	va_end(ap);

	if (strlen(message) > AP_MESSAGE_BUF_SIZE)
	{
		*(message + (AP_MESSAGE_BUF_SIZE - 1)) = '\0';
	}

	/* get the current time */
	time(&now);
	tm = localtime(&now);
	strftime(now_time, sizeof(now_time), "%Y%m%d%H%M%S", tm);
	now_date = zbx_dsprintf(NULL, "%04d/%02d/%02d %02d:%02d:%02d",
				(tm->tm_year + 1900),
				(tm->tm_mon  + 1),
				 tm->tm_mday,
				 tm->tm_hour,
				 tm->tm_min,
				 tm->tm_sec);

	/* get the inner jobnet id */
	if (w_inner_jobnet_id == 0 && inner_job_id != 0)
	{
		result = DBselect("select inner_jobnet_id from ja_run_job_table"
				" where inner_job_id = " ZBX_FS_UI64,
				inner_job_id);

		if (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(w_inner_jobnet_id, row[0]);
		}
		DBfree_result(result);
	}

	/* get the host name and job id */
	if (inner_job_id != 0)
	{
		zbx_strlcpy(s_job_id_full, ja_get_jobid(inner_job_id), sizeof(s_job_id_full));

		job_type = -1;
		result = DBselect("select job_type, job_id, job_name"
				" from ja_run_job_table"
				" where inner_job_id = " ZBX_FS_UI64,
				inner_job_id);

		if (NULL != (row = DBfetch(result)))
		{
			job_type = atoi(row[0]);
			zbx_strlcpy(s_job_id, row[1], sizeof(s_job_id));
			if (SUCCEED != DBis_null(row[2]))
			{
				zbx_strlcpy(job_name, row[2], sizeof(job_name));
			}
		}

		DBfree_result(result);

		get_host_flag = 0;
		switch (job_type)
		{
			case JA_JOB_TYPE_JOB:
				get_host_flag = 1;
				result = DBselect("select host_flag, host_name"
						" from ja_run_icon_job_table"
						" where inner_job_id = " ZBX_FS_UI64, inner_job_id);
				break;

			case JA_JOB_TYPE_FCOPY:
				get_host_flag = 1;
				result = DBselect("select from_host_flag, from_host_name"
						" from ja_run_icon_fcopy_table"
						" where inner_job_id = " ZBX_FS_UI64, inner_job_id);
				break;

			case JA_JOB_TYPE_FWAIT:
				get_host_flag = 1;
				result = DBselect("select host_flag, host_name"
						" from ja_run_icon_fwait_table"
						" where inner_job_id = " ZBX_FS_UI64, inner_job_id);
				break;

			case JA_JOB_TYPE_REBOOT:
				get_host_flag = 1;
				result = DBselect("select host_flag, host_name"
						" from ja_run_icon_reboot_table"
						" where inner_job_id = " ZBX_FS_UI64, inner_job_id);
				break;

			case JA_JOB_TYPE_LESS:
				get_host_flag = 1;
				result = DBselect("select host_flag, host_name"
						" from ja_run_icon_agentless_table"
						" where inner_job_id = " ZBX_FS_UI64, inner_job_id);
				break;
		}

		/* host name acquisition target icon */
		if (get_host_flag != 0)
		{
			if (NULL != (row = DBfetch(result)))
			{
				if (SUCCEED != DBis_null(row[1]))
				{
					host_flag = atoi(row[0]);
					if (host_flag == USE_HOSTNAME)
					{
						zbx_strlcpy(host_name, row[1], sizeof(host_name));
					}
					else
					{
						/* get the host name from the job controller variable */
						result2 = DBselect("select before_value"
								" from ja_run_value_before_table"
								" where inner_job_id = " ZBX_FS_UI64 " and value_name = '%s'",
								inner_job_id, row[1]);

						if (NULL != (row2 = DBfetch(result2)))
						{
							zbx_strlcpy(host_name, row2[0], sizeof(host_name));
						}
						DBfree_result(result2);
					}
				}
			}
			DBfree_result(result);
		}
	}

	/* get the user id */
	if (w_inner_jobnet_id != 0 || jobnet_id != NULL)
	{
		if (w_inner_jobnet_id != 0)
		{
			result = DBselect("select inner_jobnet_id, inner_jobnet_main_id, jobnet_id, user_name, jobnet_name"
					" from ja_run_jobnet_table"
					" where inner_jobnet_id = " ZBX_FS_UI64,
					w_inner_jobnet_id);

			if (NULL != (row = DBfetch(result)))
			{
				ZBX_STR2UINT64(inner_jobnet_main_id, row[1]);
				if (strcmp(row[0], row[1]) != 0)
				{
					result2 = DBselect("select jobnet_id, user_name, jobnet_name"
							" from ja_run_jobnet_table"
							" where inner_jobnet_id = %s",
							row[1]);

					if (NULL != (row2 = DBfetch(result2)))
					{
						zbx_strlcpy(s_jobnet_id, row2[0], sizeof(s_jobnet_id));
						zbx_strlcpy(s_user_name, row2[1], sizeof(s_user_name));
						zbx_strlcpy(jobnet_name, row2[2], sizeof(jobnet_name));
					}
					DBfree_result(result2);
				}
				else
				{
					zbx_strlcpy(s_jobnet_id, row[2], sizeof(s_jobnet_id));
					zbx_strlcpy(s_user_name, row[3], sizeof(s_user_name));
					zbx_strlcpy(jobnet_name, row[4], sizeof(jobnet_name));
				}
			}
		}
		else
		{
			result = DBselect("select jobnet_id, user_name, jobnet_name"
					" from ja_jobnet_control_table"
					" where jobnet_id = '%s' and valid_flag = %d",
					jobnet_id, VALID_FLAG_ON);

			if (NULL != (row = DBfetch(result)))
			{
				zbx_strlcpy(s_jobnet_id, row[0], sizeof(s_jobnet_id));
				zbx_strlcpy(s_user_name, row[1], sizeof(s_user_name));
				zbx_strlcpy(jobnet_name, row[2], sizeof(jobnet_name));
			}
		}
		DBfree_result(result);
	}

	/* log write */
	zabbix_log(log_level, "[%s] %s", message_id, message);

	/* register the error message variable */
	if (w_inner_jobnet_id == 0 || inner_job_id == 0 ||
	    log_level == LOG_LEVEL_INFORMATION || log_level == LOG_LEVEL_DEBUG)
	{
		/* skip the registration */
	}
	else
	{
		after_value_esc = DBdyn_escape_string(message);
		/* to add a variable */
		rc = DBexecute("insert into ja_run_value_after_table ("
				"inner_job_id, inner_jobnet_id, value_name, after_value) "
				"values (" ZBX_FS_UI64 ", " ZBX_FS_UI64 ", '%s', '[%s] %s')",
				inner_job_id, w_inner_jobnet_id, JOBARG_MESSAGE, message_id, after_value_esc);

		if (rc <= ZBX_DB_OK)
		{
			zabbix_log(LOG_LEVEL_ERR, "failed to insert the ja_run_value_after_table (ja_log): "
				" message id[%s] inner job id[" ZBX_FS_UI64 "] value name[%s]",
				message_id, inner_job_id, JOBARG_MESSAGE);
			zbx_free(after_value_esc);
			zbx_free(message);
			zbx_free(now_date);
			return FAIL;
		}
		zbx_free(after_value_esc);
	}

	/* no notification of message ? */
	if (send_flag == JASENDER_OFF)
	{
		zbx_free(message);
		zbx_free(now_date);
		return SUCCEED;
	}

	/* get zabbix notification existence */
	zbxsnd = ja_get_zbxsnd_on();

	/* with no notice of Zabbix ? */
	if (zbxsnd == ZBXSND_NOTICE_ON)
	{
		/* registration of the send message information */
		after_value_esc = DBdyn_escape_string(message);
		user_name_esc   = DBdyn_escape_string(s_user_name);
		host_name_esc   = DBdyn_escape_string(host_name);
		jobnet_name_esc = DBdyn_escape_string(jobnet_name);
		job_name_esc    = DBdyn_escape_string(job_name);

		rc = DBexecute("insert into ja_send_message_table ("
				"message_date, inner_jobnet_id, inner_jobnet_main_id, send_status, retry_count, retry_date, send_date, send_error_date, "
				"message_type, user_name, host_name, jobnet_id, jobnet_name, job_id, job_id_full, job_name, "
				"log_message_id, log_message) "
				"values (%s, " ZBX_FS_UI64 ", " ZBX_FS_UI64 ", %d, 0, 0, 0, 0, "
				"%d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', "
				"'%s', '%s')",
				now_time, w_inner_jobnet_id, inner_jobnet_main_id, JA_SNT_SEND_STATUS_BEGIN,
				log_type, user_name_esc, host_name_esc, s_jobnet_id, jobnet_name_esc, s_job_id, s_job_id_full, job_name_esc,
				message_id, after_value_esc);

		if (rc <= ZBX_DB_OK)
		{
			zabbix_log(LOG_LEVEL_ERR, "failed to insert the ja_send_message_table (ja_log): "
				" message date[%s] message id[%s]",
				now_time, message_id);
			zbx_free(after_value_esc);
			zbx_free(user_name_esc);
			zbx_free(host_name_esc);
			zbx_free(jobnet_name_esc);
			zbx_free(job_name_esc);
			zbx_free(message);
			zbx_free(now_date);
			return FAIL;
		}
		zbx_free(after_value_esc);
		zbx_free(user_name_esc);
		zbx_free(host_name_esc);
		zbx_free(jobnet_name_esc);
		zbx_free(job_name_esc);

		/* application execution error notification */
		dir = opendir(CONFIG_ERROR_CMD_PATH);
		if (dir == NULL)
		{
			zabbix_log(LOG_LEVEL_ERR, "failed to open the error notification directory: [%s]", CONFIG_ERROR_CMD_PATH);
			zbx_free(message);
			zbx_free(now_date);
			return FAIL;
		}

		while ((dp = readdir(dir)) != NULL)
		{
			if (dp->d_name[0] == '.')
			{
				continue;
			}
			/* start command in the background */
			zbx_snprintf(cmd, sizeof(cmd), "%s/%s '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' &",
				CONFIG_ERROR_CMD_PATH, dp->d_name, s_user_name, s_jobnet_id, now_date, message_id, type, message, host_name, s_job_id_full);
			rc = system(cmd);
			zabbix_log(LOG_LEVEL_DEBUG, "application execution [%s] (%d)", cmd, rc);
			if (rc != EXIT_SUCCESS)
			{
				if (WIFEXITED(rc))
				{
					state = WEXITSTATUS(rc);
				}
				else
				{
					state = rc;
				}
				zabbix_log(LOG_LEVEL_ERR, "failed to run the error notification application: (%d) [%s]", state, cmd);
				zbx_free(message);
				zbx_free(now_date);
				closedir(dir);
				return FAIL;
			}
		}
		closedir(dir);

		zbx_free(message);
		zbx_free(now_date);
	}

	return SUCCEED;
}
Exemple #23
0
/******************************************************************************
 *                                                                            *
 * Function: DMcolect_table_data                                              *
 *                                                                            *
 * Purpose: obtain configuration changes to required node                     *
 *                                                                            *
 * Return value: SUCCESS - processed successfully                             *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments: the changes are collected into data parameter                    *
 *                                                                            *
 ******************************************************************************/
static void	DMcollect_table_data(int nodeid, unsigned char dest_nodetype, const ZBX_TABLE *table,
		char **data, size_t *data_alloc, size_t *data_offset)
{
#define ZBX_REC_UPDATED	'1'
#define ZBX_REC_DELETED	'2'
	const char	*__function_name = "DMcolect_table_data";
	DB_RESULT	result;
	DB_RESULT	result2;
	DB_ROW		row;
	DB_ROW		row2;

	const char	*s;
	char		*hex = NULL, *sql = NULL, sync[128],
			*curr_cksum, *d_curr_cksum, *prev_cksum, *d_prev_cksum;
	size_t		sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0,
			hex_alloc = ZBX_KIBIBYTE, rowlen;
	int		f, j;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s'", __function_name, table->table);

	hex = zbx_malloc(hex, hex_alloc);
	sql = zbx_malloc(sql, sql_alloc);

	result = DBselect(
			/* new records */
			"select curr.recordid,prev.cksum,curr.cksum,curr.sync"
			" from node_cksum curr"
				" left join node_cksum prev"
					" on prev.nodeid=curr.nodeid"
						" and prev.tablename=curr.tablename"
						" and prev.recordid=curr.recordid"
						" and prev.cksumtype=%d"
			" where curr.nodeid=%d"
				" and curr.tablename='%s'"
				" and curr.cksumtype=%d"
				" and prev.tablename is null"
			" union all "
			/* updated records */
			"select curr.recordid,prev.cksum,curr.cksum,prev.sync"
			" from node_cksum curr,node_cksum prev"
			" where curr.nodeid=prev.nodeid"
				" and curr.tablename=prev.tablename"
				" and curr.recordid=prev.recordid"
				" and curr.nodeid=%d"
				" and curr.tablename='%s'"
				" and curr.cksumtype=%d"
				" and prev.cksumtype=%d"
			" union all "
			/* deleted records */
			"select prev.recordid,prev.cksum,curr.cksum,prev.sync"
			" from node_cksum prev"
				" left join node_cksum curr"
					" on curr.nodeid=prev.nodeid"
						" and curr.tablename=prev.tablename"
						" and curr.recordid=prev.recordid"
						" and curr.cksumtype=%d"
			" where prev.nodeid=%d"
				" and prev.tablename='%s'"
				" and prev.cksumtype=%d"
				" and curr.tablename is null",
			NODE_CKSUM_TYPE_OLD, nodeid, table->table, NODE_CKSUM_TYPE_NEW,
			nodeid, table->table, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD,
			NODE_CKSUM_TYPE_NEW, nodeid, table->table, NODE_CKSUM_TYPE_OLD);

	while (NULL != (row = DBfetch(result)))
	{
		memset(sync, ' ', sizeof(sync));
		memcpy(sync, row[3], strlen(row[3]));
		s = sync;

		/* special (simpler) processing for operation DELETE */
		if (SUCCEED == DBis_null(row[2]))
		{
			if (ZBX_REC_DELETED != s[dest_nodetype])
			{
				zbx_snprintf_alloc(data, data_alloc, data_offset, "\n%s%c%s%c%d",
						table->table, ZBX_DM_DELIMITER, row[0], ZBX_DM_DELIMITER,
						NODE_CONFIGLOG_OP_DELETE);
			}
			continue;
		}

		prev_cksum = (SUCCEED == DBis_null(row[1]) ? NULL : row[1]);
		curr_cksum = row[2];
		f = 0;

		sql_offset = 0;
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select ");

		do
		{
			while (0 == (table->fields[f].flags & ZBX_SYNC))
				f++;

			d_prev_cksum = NULL;
			if (NULL != prev_cksum && NULL != (d_prev_cksum = strchr(prev_cksum, ',')))
				*d_prev_cksum = '\0';

			d_curr_cksum = NULL;
			if (NULL != curr_cksum && NULL != (d_curr_cksum = strchr(curr_cksum, ',')))
				*d_curr_cksum = '\0';

			if (NULL == prev_cksum || NULL == curr_cksum || ZBX_REC_UPDATED != s[dest_nodetype] ||
					0 != strcmp(prev_cksum, curr_cksum))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%s,", table->fields[f].name);

				if (table->fields[f].type == ZBX_TYPE_BLOB)
				{
					zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "length(%s),",
							table->fields[f].name);
				}
			}

			/* "host_inventory" table has more than 64 fields */
			/* remaining fields are processed as one */
			if (126 > s - sync)
				s += 2;
			f++;

			if (d_prev_cksum != NULL)
			{
				*d_prev_cksum = ',';
				prev_cksum = d_prev_cksum + 1;
			}
			else
				prev_cksum = NULL;

			if (d_curr_cksum != NULL)
			{
				*d_curr_cksum = ',';
				curr_cksum = d_curr_cksum + 1;
			}
			else
				curr_cksum = NULL;
		}
		while (NULL != d_prev_cksum || NULL != d_curr_cksum);

		if (sql[sql_offset - 1] != ',')
			continue;

		sql_offset--;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s where %s=%s",
				table->table, table->recid, row[0]);

		result2 = DBselect("%s", sql);
		if (NULL == (row2 = DBfetch(result2)))
			goto out;

		zbx_snprintf_alloc(data, data_alloc, data_offset, "\n%s%c%s%c%d",
				table->table, ZBX_DM_DELIMITER, row[0], ZBX_DM_DELIMITER,
				NODE_CONFIGLOG_OP_UPDATE);

		prev_cksum = DBis_null(row[1]) == SUCCEED ? NULL : row[1];
		curr_cksum = row[2];
		s = sync;
		f = 0;
		j = 0;

		do
		{
			while (0 == (table->fields[f].flags & ZBX_SYNC))
				f++;

			d_prev_cksum = NULL;
			if (NULL != prev_cksum && NULL != (d_prev_cksum = strchr(prev_cksum, ',')))
				*d_prev_cksum = '\0';

			d_curr_cksum = NULL;
			if (NULL != curr_cksum && NULL != (d_curr_cksum = strchr(curr_cksum, ',')))
				*d_curr_cksum = '\0';

			if (NULL == prev_cksum || NULL == curr_cksum || ZBX_REC_UPDATED != s[dest_nodetype] ||
					0 != strcmp(prev_cksum, curr_cksum))
			{
				/* fieldname, type */
				zbx_snprintf_alloc(data, data_alloc, data_offset, "%c%s%c%d%c",
						ZBX_DM_DELIMITER, table->fields[f].name,
						ZBX_DM_DELIMITER, table->fields[f].type,
						ZBX_DM_DELIMITER);

				/* value */
				if (SUCCEED == DBis_null(row2[j]))
				{
					zbx_strcpy_alloc(data, data_alloc, data_offset, "NULL");
				}
				else if (ZBX_TYPE_INT == table->fields[f].type ||
						ZBX_TYPE_UINT == table->fields[f].type ||
						ZBX_TYPE_ID == table->fields[f].type ||
						ZBX_TYPE_FLOAT == table->fields[f].type)
				{
					zbx_strcpy_alloc(data, data_alloc, data_offset, row2[j]);
				}
				else
				{
					if (table->fields[f].type == ZBX_TYPE_BLOB)
						rowlen = (size_t)atoi(row2[j + 1]);
					else
						rowlen = strlen(row2[j]);
					zbx_binary2hex((u_char *)row2[j], rowlen, &hex, &hex_alloc);
					zbx_strcpy_alloc(data, data_alloc, data_offset, hex);
				}

				if (table->fields[f].type == ZBX_TYPE_BLOB)
					j += 2;
				else
					j++;
			}

			/* "host_inventory" table has more than 64 fields */
			/* remaining fields are processed as one */
			if (126 > s - sync)
				s += 2;
			f++;

			if (d_prev_cksum != NULL)
			{
				*d_prev_cksum = ',';
				prev_cksum = d_prev_cksum + 1;
			}
			else
				prev_cksum = NULL;

			if (d_curr_cksum != NULL)
			{
				*d_curr_cksum = ',';
				curr_cksum = d_curr_cksum + 1;
			}
			else
				curr_cksum = NULL;
		}
		while (NULL != d_prev_cksum || NULL != d_curr_cksum);
out:
		DBfree_result(result2);
	}
	DBfree_result(result);

	zbx_free(hex);
	zbx_free(sql);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Exemple #24
0
/******************************************************************************
 *                                                                            *
 * Function: delete_history                                                   *
 *                                                                            *
 * Purpose: remove outdated information from historical table                 *
 *                                                                            *
 * Parameters: now - current timestamp                                        *
 *                                                                            *
 * Return value: number of rows records                                       *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	delete_history(const char *table, const char *fieldname, int now)
{
	const char	*__function_name = "delete_history";
	DB_RESULT       result;
	DB_ROW          row;
	int             minclock, records = 0;
	zbx_uint64_t	lastid, maxid;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() table:'%s' now:%d",
			__function_name, table, now);

	DBbegin();

	result = DBselect(
			"select nextid"
			" from ids"
			" where table_name='%s'"
				" and field_name='%s'",
			table, fieldname);

	if (NULL == (row = DBfetch(result)))
		goto rollback;

	ZBX_STR2UINT64(lastid, row[0]);
	DBfree_result(result);

	result = DBselect("select min(clock) from %s",
			table);

	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
		goto rollback;

	minclock = atoi(row[0]);
	DBfree_result(result);

	result = DBselect("select max(id) from %s",
			table);

	if (NULL == (row = DBfetch(result)) || SUCCEED == DBis_null(row[0]))
		goto rollback;

	ZBX_STR2UINT64(maxid, row[0]);
	DBfree_result(result);

	records = DBexecute(
			"delete from %s"
			" where id<" ZBX_FS_UI64
				" and (clock<%d"
					" or (id<=" ZBX_FS_UI64 " and clock<%d))",
			table, maxid,
			now - CONFIG_PROXY_OFFLINE_BUFFER * SEC_PER_HOUR,
			lastid,
			MIN(now - CONFIG_PROXY_LOCAL_BUFFER * SEC_PER_HOUR,
					minclock + HK_MAX_DELETE_PERIODS * hk_period));

	DBcommit();

	return records;
rollback:
	DBfree_result(result);

	DBrollback();

	return 0;
}
Exemple #25
0
/******************************************************************************
 *                                                                            *
 * Function: update_checksums                                                 *
 *                                                                            *
 * Purpose: overwrite old checksums with new ones                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - calculated successfully                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	update_checksums(int nodeid, int synked_nodetype, int synked, const char *tablename,
		const zbx_uint64_t id, const char *fields)
{
	const char	*__function_name = "update_checksums";
	char		*r[2], *d[2], sync[129], *s;
	char		c[2], sql[2][256];
	char		cksum[32 * 72 + 72], *ck;
	char		*exsql = NULL;
	size_t		exsql_alloc = 64 * ZBX_KIBIBYTE, exsql_offset = 0;
	int		cksumtype;
	DB_RESULT	result;
	DB_ROW		row;
	int		f;
	const ZBX_TABLE	*table;

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

	exsql = zbx_malloc(exsql, exsql_alloc);

	DBbegin();

	DBbegin_multiple_update(&exsql, &exsql_alloc, &exsql_offset);

	c[0] = SUCCEED == synked ? '1' : ' ';	/* for new and updated records */
	c[1] = SUCCEED == synked ? '2' : ' ';	/* for deleted records */

	if (NULL != tablename)
	{
		zbx_snprintf(sql[0], sizeof(sql[0]), " and curr.tablename='%s' and curr.recordid=" ZBX_FS_UI64,
				tablename, id);
		zbx_snprintf(sql[1], sizeof(sql[1]), " and prev.tablename='%s' and prev.recordid=" ZBX_FS_UI64,
				tablename, id);
	}
	else
	{
		*sql[0] = '\0';
		*sql[1] = '\0';
	}

	result = DBselect(
			/* new records */
			"select curr.tablename,curr.recordid,prev.cksum,curr.cksum,NULL"
			" from node_cksum curr"
				" left join node_cksum prev"
					" on prev.nodeid=curr.nodeid"
						" and prev.tablename=curr.tablename"
						" and prev.recordid=curr.recordid"
						" and prev.cksumtype=%d"
			" where curr.nodeid=%d"
				" and curr.cksumtype=%d"
				" and prev.tablename is null%s"
			" union all "
			/* updated records */
			"select curr.tablename,curr.recordid,prev.cksum,curr.cksum,prev.sync"
			" from node_cksum curr, node_cksum prev"
			" where curr.nodeid=%d"
				" and prev.nodeid=curr.nodeid"
				" and curr.tablename=prev.tablename"
				" and curr.recordid=prev.recordid"
				" and curr.cksumtype=%d"
				" and prev.cksumtype=%d%s"
			" union all "
			/* deleted records */
			"select prev.tablename,prev.recordid,prev.cksum,curr.cksum,prev.sync"
			" from node_cksum prev"
				" left join node_cksum curr"
					" on curr.nodeid=prev.nodeid"
						" and curr.tablename=prev.tablename"
						" and curr.recordid=prev.recordid"
						" and curr.cksumtype=%d"
			" where prev.nodeid=%d"
				" and prev.cksumtype=%d"
				" and curr.tablename is null%s",
			NODE_CKSUM_TYPE_OLD, nodeid, NODE_CKSUM_TYPE_NEW, sql[0],
			nodeid, NODE_CKSUM_TYPE_NEW, NODE_CKSUM_TYPE_OLD, sql[0],
			NODE_CKSUM_TYPE_NEW, nodeid, NODE_CKSUM_TYPE_OLD, sql[1]);

	while (NULL != (row = DBfetch(result)))
	{
		if (NULL == (table = DBget_table(row[0])))
		{
			zabbix_log(LOG_LEVEL_WARNING, "cannot find table [%s]", row[0]);
			continue;
		}

		memset(sync, ' ', sizeof(sync));
		if (FAIL == DBis_null(row[4]))
			memcpy(sync, row[4], strlen(row[4]));

		s = sync;
		ck = cksum;
		*ck = '\0';

		/* special (simpler) processing for operation DELETE */
		if (SUCCEED == DBis_null(row[3]))
		{
			if (SUCCEED == synked)
				s[synked_nodetype] = c[1];

			if ((0 == CONFIG_MASTER_NODEID || s[1] == c[1]) && (CONFIG_NODEID == nodeid || s[0] == c[1]))
			{
				zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset,
						"delete from node_cksum"
						" where nodeid=%d"
							" and cksumtype=%d"
							" and tablename='%s'"
							" and recordid=%s;\n",
						nodeid, NODE_CKSUM_TYPE_OLD, row[0], row[1]);

				DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset);
				continue;
			}

			s += 2;
		}
		else
		{
			r[0] = SUCCEED == DBis_null(row[2]) ? NULL : row[2];
			r[1] = row[3];
			f = 0;

			do {
				while ((table->fields[f].flags & ZBX_SYNC) == 0)
					f++;

				/* "host_inventory" table has more than 64 fields */
				/* remaining fields are processed as one */
				if (128 == s - sync)
					s -= 2;

				d[0] = NULL;
				d[1] = NULL;
				if (NULL != r[0] && NULL != (d[0] = strchr(r[0], ',')))
					*d[0] = '\0';
				if (NULL != r[1] && NULL != (d[1] = strchr(r[1], ',')))
					*d[1] = '\0';

				if (NULL == tablename || SUCCEED == str_in_list(fields, table->fields[f].name, ','))
				{
					ck += zbx_snprintf(ck, 64, "%s,", NULL != r[1] ? r[1] : r[0]);

					if (NULL == r[0] || NULL == r[1] || 0 != strcmp(r[0], r[1]))
					{
						s[0] = s[1] = ' ';
						s[synked_nodetype] = c[0];
					}
					else
					{
						if (SUCCEED == synked)
							s[synked_nodetype] = c[0];
					}
				}
				else
					ck += zbx_snprintf(ck, 64, "%s,", NULL != r[0] ? r[0] : "");

				s += 2;
				f++;

				if (d[0] != NULL)
				{
					*d[0] = ',';
					r[0] = d[0] + 1;
				}
				else
					r[0] = NULL;

				if (d[1] != NULL)
				{
					*d[1] = ',';
					r[1] = d[1] + 1;
				}
				else
					r[1] = NULL;
			} while (d[0] != NULL || d[1] != NULL);

			*--ck = '\0';
		}

		*s = '\0';

		if (SUCCEED == DBis_null(row[2]) || SUCCEED == DBis_null(row[3]) ||
				0 != strcmp(row[4], sync) || 0 != strcmp(row[2], row[3]))
		{
			cksumtype = (DBis_null(row[2]) == SUCCEED) ? NODE_CKSUM_TYPE_NEW : NODE_CKSUM_TYPE_OLD;
			zbx_snprintf_alloc(&exsql, &exsql_alloc, &exsql_offset,
					"update node_cksum"
					" set cksumtype=%d,"
						"cksum='%s',"
						"sync='%s'"
					" where nodeid=%d"
						" and cksumtype=%d"
						" and tablename='%s'"
						" and recordid=%s;\n",
					NODE_CKSUM_TYPE_OLD, cksum, sync,
					nodeid, cksumtype, row[0], row[1]);

			DBexecute_overflowed_sql(&exsql, &exsql_alloc, &exsql_offset);
		}
	}
	DBfree_result(result);

	DBend_multiple_update(&exsql, &exsql_alloc, &exsql_offset);

	if (exsql_offset > 16)	/* In ORACLE always present begin..end; */
		DBexecute("%s", exsql);
	zbx_free(exsql);

	DBcommit();

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

	return SUCCEED;
}
Exemple #26
0
/******************************************************************************
 *                                                                            *
 * Function: register_service                                                 *
 *                                                                            *
 * Purpose: register service if one does not exist                            *
 *                                                                            *
 * Parameters: host ip address                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void register_service(DB_DSERVICE *service,DB_DRULE *rule,DB_DCHECK *check,zbx_uint64_t dhostid,char *ip,int port)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		value_esc[MAX_STRING_LEN];
	char		key_esc[MAX_STRING_LEN];

	assert(service);
	assert(rule);
	assert(check);
	assert(ip);

	zabbix_log(LOG_LEVEL_DEBUG, "In register_service(ip:%s,port:%d)",
		ip,
		port);

	DBescape_string(check->key_, key_esc, sizeof(key_esc)-1);

	result = DBselect("select dserviceid,dhostid,type,port,status,lastup,lastdown,value,key_ from dservices where dhostid=" ZBX_FS_UI64 " and type=%d and port=%d and key_='%s'",
		dhostid,
		check->type,
		port,
		key_esc);
	row=DBfetch(result);
	if(!row || DBis_null(row[0])==SUCCEED)
	{
		/* Add host only if service is up */
		if(check->status == DOBJECT_STATUS_UP)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "New service discovered on port %d", port);

			service->dserviceid	= DBget_maxid("dservices","dserviceid");
			service->dhostid	= dhostid;
			service->type		= check->type;
			service->port		= port;
			service->status		= DOBJECT_STATUS_UP;
			service->lastup		= 0;
			service->lastdown	= 0;
			strscpy(service->value, check->value);
			strscpy(service->key_, check->key_);

			DBescape_string(service->value, value_esc, sizeof(value_esc)-1);
			DBescape_string(service->key_, key_esc, sizeof(key_esc)-1);

			DBexecute("insert into dservices (dhostid,dserviceid,type,port,status,value,key_) values (" ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d,%d,'%s','%s')",
				service->dhostid,
				service->dserviceid,
				check->type,
				service->port,
				service->status,
				value_esc,
				key_esc);
		}
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "Service is already in database");

		ZBX_STR2UINT64(service->dserviceid,	row[0]);
		ZBX_STR2UINT64(service->dhostid,	row[1]);
		service->type		= atoi(row[2]);
		service->port		= atoi(row[3]);
		service->status		= atoi(row[4]);
		service->lastup		= atoi(row[5]);
		service->lastdown	= atoi(row[6]);
		strscpy(service->value,row[7]);
		strscpy(service->key_,row[8]);
	}
	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End register_service()");
}
/******************************************************************************
 *                                                                            *
 * Function: get_template_items                                               *
 *                                                                            *
 * Purpose: read template items from database                                 *
 *                                                                            *
 * Parameters: hostid      - [IN] host id                                     *
 *             templateids - [IN] array of template IDs                       *
 *             items       - [OUT] the item data                              *
 *                                                                            *
 * Comments: The itemid and key are set depending on whether the item exists  *
 *           for the specified host.                                          *
 *           If item exists itemid will be set to its itemid and key will be  *
 *           set to NULL.                                                     *
 *           If item does not exist, itemid will be set to 0 and key will be  *
 *           set to item key.                                                 *
 *                                                                            *
 ******************************************************************************/
static void	get_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *templateids, zbx_vector_ptr_t *items)
{
	DB_RESULT		result;
	DB_ROW			row;
	char			*sql = NULL;
	size_t			sql_alloc = 0, sql_offset = 0, i;
	unsigned char		interface_type;
	zbx_template_item_t	*item;
	zbx_uint64_t		interfaceids[4];

	memset(&interfaceids, 0, sizeof(interfaceids));
	DBget_interfaces_by_hostid(hostid, interfaceids);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select ti.itemid,ti.name,ti.key_,ti.type,ti.value_type,ti.data_type,ti.delay,ti.delay_flex,"
				"ti.history,ti.trends,ti.status,ti.trapper_hosts,ti.units,ti.multiplier,ti.delta,"
				"ti.formula,ti.logtimefmt,ti.valuemapid,ti.params,ti.ipmi_sensor,ti.snmp_community,"
				"ti.snmp_oid,ti.snmpv3_securityname,ti.snmpv3_securitylevel,ti.snmpv3_authprotocol,"
				"ti.snmpv3_authpassphrase,ti.snmpv3_privprotocol,ti.snmpv3_privpassphrase,ti.authtype,"
				"ti.username,ti.password,ti.publickey,ti.privatekey,ti.flags,ti.description,"
				"ti.inventory_link,ti.lifetime,ti.snmpv3_contextname,hi.itemid,ti.evaltype,ti.port"
			" from items ti"
			" left join items hi on hi.key_=ti.key_"
				" and hi.hostid=" ZBX_FS_UI64
			" where",
			hostid);
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "ti.hostid", templateids->values, templateids->values_num);

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

	while (NULL != (row = DBfetch(result)))
	{
		item = zbx_malloc(NULL, sizeof(zbx_template_item_t));

		ZBX_STR2UINT64(item->templateid, row[0]);
		ZBX_STR2UCHAR(item->type, row[3]);
		ZBX_STR2UCHAR(item->value_type, row[4]);
		ZBX_STR2UCHAR(item->data_type, row[5]);
		item->delay = atoi(row[6]);
		item->history = atoi(row[8]);
		item->trends = atoi(row[9]);
		ZBX_STR2UCHAR(item->status, row[10]);
		ZBX_STR2UCHAR(item->multiplier, row[13]);
		ZBX_STR2UCHAR(item->delta, row[14]);
		ZBX_DBROW2UINT64(item->valuemapid, row[17]);
		ZBX_STR2UCHAR(item->snmpv3_securitylevel, row[23]);
		ZBX_STR2UCHAR(item->snmpv3_authprotocol, row[24]);
		ZBX_STR2UCHAR(item->snmpv3_privprotocol, row[26]);
		ZBX_STR2UCHAR(item->authtype, row[28]);
		ZBX_STR2UCHAR(item->flags, row[33]);
		ZBX_STR2UCHAR(item->inventory_link, row[35]);
		ZBX_STR2UCHAR(item->evaltype, row[39]);

		switch (interface_type = get_interface_type_by_item_type(item->type))
		{
			case INTERFACE_TYPE_UNKNOWN:
				item->interfaceid = 0;
				break;
			case INTERFACE_TYPE_ANY:
				for (i = 0; INTERFACE_TYPE_COUNT > i; i++)
				{
					if (0 != interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1])
						break;
				}
				item->interfaceid = interfaceids[INTERFACE_TYPE_PRIORITY[i] - 1];
				break;
			default:
				item->interfaceid = interfaceids[interface_type - 1];
		}

		item->name = zbx_strdup(NULL, row[1]);
		item->delay_flex = zbx_strdup(NULL, row[7]);
		item->trapper_hosts = zbx_strdup(NULL, row[11]);
		item->units = zbx_strdup(NULL, row[12]);
		item->formula = zbx_strdup(NULL, row[15]);
		item->logtimefmt = zbx_strdup(NULL, row[16]);
		item->params = zbx_strdup(NULL, row[18]);
		item->ipmi_sensor = zbx_strdup(NULL, row[19]);
		item->snmp_community = zbx_strdup(NULL, row[20]);
		item->snmp_oid = zbx_strdup(NULL, row[21]);
		item->snmpv3_securityname = zbx_strdup(NULL, row[22]);
		item->snmpv3_authpassphrase = zbx_strdup(NULL, row[25]);
		item->snmpv3_privpassphrase = zbx_strdup(NULL, row[27]);
		item->username = zbx_strdup(NULL, row[29]);
		item->password = zbx_strdup(NULL, row[30]);
		item->publickey = zbx_strdup(NULL, row[31]);
		item->privatekey = zbx_strdup(NULL, row[32]);
		item->description = zbx_strdup(NULL, row[34]);
		item->lifetime = zbx_strdup(NULL, row[36]);
		item->snmpv3_contextname = zbx_strdup(NULL, row[37]);
		item->port = zbx_strdup(NULL, row[40]);

		if (SUCCEED != DBis_null(row[38]))
		{
			item->key = NULL;
			ZBX_STR2UINT64(item->itemid, row[38]);
		}
		else
		{
			item->key = zbx_strdup(NULL, row[2]);
			item->itemid = 0;
		}

		zbx_vector_ptr_append(items, item);
	}
	DBfree_result(result);

	zbx_free(sql);

	zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
}
Exemple #28
0
int	MAIN_ZABBIX_ENTRY()
{
	DB_RESULT	result;
	DB_ROW		row;
	pid_t		pid;
	zbx_sock_t	listen_sock;
	int		i, server_num = 0, server_count = 0;

	if (NULL == CONFIG_LOG_FILE || '\0' == *CONFIG_LOG_FILE)
		zabbix_open_log(LOG_TYPE_SYSLOG, CONFIG_LOG_LEVEL, NULL);
	else
		zabbix_open_log(LOG_TYPE_FILE, CONFIG_LOG_LEVEL, CONFIG_LOG_FILE);

#ifdef HAVE_SNMP
#	define SNMP_FEATURE_STATUS	"YES"
#else
#	define SNMP_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_OPENIPMI
#	define IPMI_FEATURE_STATUS	"YES"
#else
#	define IPMI_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_LIBCURL
#	define LIBCURL_FEATURE_STATUS	"YES"
#else
#	define LIBCURL_FEATURE_STATUS	" NO"
#endif
#if defined(HAVE_LIBXML2) && defined(HAVE_LIBCURL)
#	define VMWARE_FEATURE_STATUS	"YES"
#else
#	define VMWARE_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_JABBER
#	define JABBER_FEATURE_STATUS	"YES"
#else
#	define JABBER_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_UNIXODBC
#	define ODBC_FEATURE_STATUS	"YES"
#else
#	define ODBC_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_SSH2
#	define SSH2_FEATURE_STATUS	"YES"
#else
#	define SSH2_FEATURE_STATUS	" NO"
#endif
#ifdef HAVE_IPV6
#	define IPV6_FEATURE_STATUS	"YES"
#else
#	define IPV6_FEATURE_STATUS	" NO"
#endif

	zabbix_log(LOG_LEVEL_INFORMATION, "Starting Zabbix Server. Zabbix %s (revision %s).",
			ZABBIX_VERSION, ZABBIX_REVISION);

	zabbix_log(LOG_LEVEL_INFORMATION, "****** Enabled features ******");
	zabbix_log(LOG_LEVEL_INFORMATION, "SNMP monitoring:           " SNMP_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "IPMI monitoring:           " IPMI_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "WEB monitoring:            " LIBCURL_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "VMware monitoring:         " VMWARE_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "Jabber notifications:      " JABBER_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "Ez Texting notifications:  " LIBCURL_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "ODBC:                      " ODBC_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "SSH2 support:              " SSH2_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "IPv6 support:              " IPV6_FEATURE_STATUS);
	zabbix_log(LOG_LEVEL_INFORMATION, "******************************");

	if (0 != CONFIG_NODEID)
	{
		zabbix_log(LOG_LEVEL_INFORMATION, "NodeID:                    %3d", CONFIG_NODEID);
		zabbix_log(LOG_LEVEL_INFORMATION, "******************************");
	}

	zabbix_log(LOG_LEVEL_INFORMATION, "using configuration file: %s", CONFIG_FILE);

	if (FAIL == load_modules(CONFIG_LOAD_MODULE_PATH, CONFIG_LOAD_MODULE, CONFIG_TIMEOUT, 1))
	{
		zabbix_log(LOG_LEVEL_CRIT, "loading modules failed, exiting...");
		exit(EXIT_FAILURE);
	}

	zbx_free_config();

	init_database_cache();
	init_configuration_cache();
	init_selfmon_collector();

	/* initialize vmware support */
	if (0 != CONFIG_VMWARE_FORKS)
		zbx_vmware_init();

	/* initialize history value cache */
	zbx_vc_init();

	zbx_create_itservices_lock();

#ifdef	HAVE_SQLITE3
	zbx_create_sqlite3_mutex();
#endif

	if (SUCCEED != DBcheck_version())
		exit(EXIT_FAILURE);

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	if (0 != CONFIG_NODEID)
	{
		result = DBselect("select masterid from nodes where nodeid=%d", CONFIG_NODEID);

		if (NULL != (row = DBfetch(result)) && SUCCEED != DBis_null(row[0]))
			CONFIG_MASTER_NODEID = atoi(row[0]);
		DBfree_result(result);
	}

	DCload_config();

	/* make initial configuration sync before worker processes are forked */
	DCsync_configuration();

	DBclose();

	if (ZBX_MUTEX_ERROR == zbx_mutex_create_force(&node_sync_access, ZBX_MUTEX_NODE_SYNC))
	{
		zbx_error("Unable to create mutex for node syncs");
		exit(FAIL);
	}

	threads_num = CONFIG_CONFSYNCER_FORKS + CONFIG_WATCHDOG_FORKS + CONFIG_POLLER_FORKS
			+ CONFIG_UNREACHABLE_POLLER_FORKS + CONFIG_TRAPPER_FORKS + CONFIG_PINGER_FORKS
			+ CONFIG_ALERTER_FORKS + CONFIG_HOUSEKEEPER_FORKS + CONFIG_TIMER_FORKS
			+ CONFIG_NODEWATCHER_FORKS + CONFIG_HTTPPOLLER_FORKS + CONFIG_DISCOVERER_FORKS
			+ CONFIG_HISTSYNCER_FORKS + CONFIG_ESCALATOR_FORKS + CONFIG_IPMIPOLLER_FORKS
			+ CONFIG_JAVAPOLLER_FORKS + CONFIG_SNMPTRAPPER_FORKS + CONFIG_PROXYPOLLER_FORKS
			+ CONFIG_SELFMON_FORKS + CONFIG_VMWARE_FORKS;
	threads = zbx_calloc(threads, threads_num, sizeof(pid_t));

	if (0 < CONFIG_TRAPPER_FORKS)
	{
		if (FAIL == zbx_tcp_listen(&listen_sock, CONFIG_LISTEN_IP, (unsigned short)CONFIG_LISTEN_PORT))
		{
			zabbix_log(LOG_LEVEL_CRIT, "listener failed: %s", zbx_tcp_strerror());
			exit(1);
		}
	}

	for (i = 0; i < threads_num; i++)
	{
		if (0 == (pid = zbx_child_fork()))
		{
			server_num = i + 1;	/* child processes are numbered starting from 1 */
			break;
		}
		else
			threads[i] = pid;
	}

	if (0 == server_num)
	{
		zabbix_log(LOG_LEVEL_INFORMATION, "server #0 started [main process]");

		while (-1 == wait(&i))	/* wait for any child to exit */
		{
			if (EINTR != errno)
			{
				zabbix_log(LOG_LEVEL_ERR, "failed to wait on child processes: %s", zbx_strerror(errno));
				break;
			}
		}

		/* all exiting child processes should be caught by signal handlers */
		THIS_SHOULD_NEVER_HAPPEN;

		zbx_on_exit();
	}
	else if (server_num <= (server_count += CONFIG_CONFSYNCER_FORKS))
	{
		/* !!! configuration syncer must be server #1 - child_signal_handler() uses threads[0] !!! */

		INIT_SERVER(ZBX_PROCESS_TYPE_CONFSYNCER, CONFIG_CONFSYNCER_FORKS);

		main_dbconfig_loop();
	}
	else if (server_num <= (server_count += CONFIG_WATCHDOG_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_WATCHDOG, CONFIG_WATCHDOG_FORKS);

		main_watchdog_loop();
	}
	else if (server_num <= (server_count += CONFIG_POLLER_FORKS))
	{
#ifdef HAVE_SNMP
		init_snmp("zabbix_server");
#endif

		INIT_SERVER(ZBX_PROCESS_TYPE_POLLER, CONFIG_POLLER_FORKS);

		main_poller_loop(ZBX_POLLER_TYPE_NORMAL);
	}
	else if (server_num <= (server_count += CONFIG_UNREACHABLE_POLLER_FORKS))
	{
#ifdef HAVE_SNMP
		init_snmp("zabbix_server");
#endif

		INIT_SERVER(ZBX_PROCESS_TYPE_UNREACHABLE, CONFIG_UNREACHABLE_POLLER_FORKS);

		main_poller_loop(ZBX_POLLER_TYPE_UNREACHABLE);
	}
	else if (server_num <= (server_count += CONFIG_TRAPPER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_TRAPPER, CONFIG_TRAPPER_FORKS);

		main_trapper_loop(&listen_sock);
	}
	else if (server_num <= (server_count += CONFIG_PINGER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_PINGER, CONFIG_PINGER_FORKS);

		main_pinger_loop();
	}
	else if (server_num <= (server_count += CONFIG_ALERTER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_ALERTER, CONFIG_ALERTER_FORKS);

		main_alerter_loop();
	}
	else if (server_num <= (server_count += CONFIG_HOUSEKEEPER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_HOUSEKEEPER, CONFIG_HOUSEKEEPER_FORKS);

		main_housekeeper_loop();
	}
	else if (server_num <= (server_count += CONFIG_TIMER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_TIMER, CONFIG_TIMER_FORKS);

		main_timer_loop();
	}
	else if (server_num <= (server_count += CONFIG_NODEWATCHER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_NODEWATCHER, CONFIG_NODEWATCHER_FORKS);

		main_nodewatcher_loop();
	}
	else if (server_num <= (server_count += CONFIG_HTTPPOLLER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_HTTPPOLLER, CONFIG_HTTPPOLLER_FORKS);

		main_httppoller_loop();
	}
	else if (server_num <= (server_count += CONFIG_DISCOVERER_FORKS))
	{
#ifdef HAVE_SNMP
		init_snmp("zabbix_server");
#endif

		INIT_SERVER(ZBX_PROCESS_TYPE_DISCOVERER, CONFIG_DISCOVERER_FORKS);

		main_discoverer_loop();
	}
	else if (server_num <= (server_count += CONFIG_HISTSYNCER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_HISTSYNCER, CONFIG_HISTSYNCER_FORKS);

		main_dbsyncer_loop();
	}
	else if (server_num <= (server_count += CONFIG_ESCALATOR_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_ESCALATOR, CONFIG_ESCALATOR_FORKS);

		main_escalator_loop();
	}
	else if (server_num <= (server_count += CONFIG_IPMIPOLLER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_IPMIPOLLER, CONFIG_IPMIPOLLER_FORKS);

		main_poller_loop(ZBX_POLLER_TYPE_IPMI);
	}
	else if (server_num <= (server_count += CONFIG_JAVAPOLLER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_JAVAPOLLER, CONFIG_JAVAPOLLER_FORKS);

		main_poller_loop(ZBX_POLLER_TYPE_JAVA);
	}
	else if (server_num <= (server_count += CONFIG_SNMPTRAPPER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_SNMPTRAPPER, CONFIG_SNMPTRAPPER_FORKS);

		main_snmptrapper_loop();
	}
	else if (server_num <= (server_count += CONFIG_PROXYPOLLER_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_PROXYPOLLER, CONFIG_PROXYPOLLER_FORKS);

		main_proxypoller_loop();
	}
	else if (server_num <= (server_count += CONFIG_SELFMON_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_SELFMON, CONFIG_SELFMON_FORKS);

		main_selfmon_loop();
	}
	else if (server_num <= (server_count += CONFIG_VMWARE_FORKS))
	{
		INIT_SERVER(ZBX_PROCESS_TYPE_VMWARE, CONFIG_VMWARE_FORKS);

		main_vmware_loop();
	}

	return SUCCEED;
}