示例#1
0
文件: housekeeper.c 项目: Shmuma/z
/******************************************************************************
 *                                                                            *
 * 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)
	);
}
static int	check_data_uniqueness(const char *table_name, const char *field_name)
{
	DB_RESULT	result;
	DB_ROW		row;
	int		ret = SUCCEED;

	if (NULL == (result = DBselect("select %s from %s group by %s having count(*)>1",
			field_name, table_name, field_name)))
	{
		return FAIL;
	}

	while (NULL != (row = DBfetch(result)))
	{
		zabbix_log(LOG_LEVEL_CRIT, "Duplicate data \"%s\" for field \"%s\" is found in table \"%s\"."
				" Remove it manually and restart the process.", row[0], field_name, table_name);
		ret = FAIL;
	}
	DBfree_result(result);

	return ret;
}
static int	DBpatch_2030024(void)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		*value, *macro_esc, *value_esc;
	int		ret = FAIL, rc;

	/* 1 - ZBX_FLAG_DISCOVERY_RULE*/
	if (NULL == (result = DBselect("select itemid,filter from items where filter<>'' and flags=1")))
		return FAIL;

	while (NULL != (row = DBfetch(result)))
	{
		if (NULL == (value = strchr(row[1], ':')) || 0 == strcmp(row[1], ":"))
			continue;

		*value++ = '\0';

		macro_esc = DBdyn_escape_string(row[1]);
		value_esc = DBdyn_escape_string(value);

		rc = DBexecute("insert into item_condition"
				" (item_conditionid,itemid,macro,value)"
				" values (%s,%s,'%s','%s')",
				row[0], row[0],  macro_esc, value_esc);

		zbx_free(value_esc);
		zbx_free(macro_esc);

		if (ZBX_DB_OK > rc)
			goto out;
	}

	ret = SUCCEED;
out:
	DBfree_result(result);

	return ret;
}
示例#4
0
/******************************************************************************
 *                                                                            *
 * Function: add_discovered_host_group                                        *
 *                                                                            *
 * Purpose: add group to host if not added already                            *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 ******************************************************************************/
static void	add_discovered_host_group(zbx_uint64_t hostid, zbx_uint64_t groupid)
{
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	hostgroupid;

	result = DBselect(
			"select hostgroupid"
			" from hosts_groups"
			" where groupid=" ZBX_FS_UI64
				" and hostid=" ZBX_FS_UI64,
			groupid, hostid);

	if (NULL == (row = DBfetch(result)))
	{
		hostgroupid = DBget_maxid("hosts_groups");
		DBexecute("insert into hosts_groups (hostgroupid,hostid,groupid)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ")",
				hostgroupid, hostid, groupid);
	}
	DBfree_result(result);
}
示例#5
0
文件: history.c 项目: rennhak/zabbix
/******************************************************************************
 *                                                                            *
 * Function: main_historysender                                               *
 *                                                                            *
 * Purpose: periodically sends historical data to master node                 *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              * 
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void main_historysender()
{
	DB_RESULT	result;
	DB_ROW		row;
	int		master_nodeid, nodeid;

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

	master_nodeid = CONFIG_MASTER_NODEID;
	if (0 == master_nodeid)
		return;

	result = DBselect("select nodeid from nodes");
	while ((row = DBfetch(result))) {
		nodeid = atoi(row[0]);
		if (SUCCEED == is_master_node(CONFIG_NODEID, nodeid))
			continue;

		process_history_tables(master_nodeid, nodeid);
	}
	DBfree_result(result);
}
示例#6
0
/******************************************************************************
 *                                                                            *
 * Function: get_next_point_to_node                                           *
 *                                                                            *
 * Purpose: find next point to slave node                                     *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	get_next_point_to_node(int current_nodeid, int slave_nodeid, int *nodeid)
{
	DB_RESULT	db_result;
	DB_ROW		db_row;
	int		id, res = FAIL;

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

	while (NULL != (db_row = DBfetch(db_result))) {
		id = atoi(db_row[0]);
		if (id == slave_nodeid || SUCCEED == get_next_point_to_node(id, slave_nodeid, NULL)) {
			if (NULL != nodeid)
				*nodeid = id;
			res = SUCCEED;
			break;
		}
	}
	DBfree_result(db_result);

	return res;
}
示例#7
0
文件: discoverer.c 项目: Shmuma/z
/******************************************************************************
 *                                                                            *
 * 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()");
}
示例#8
0
static void	DBget_version(int *mandatory, int *optional)
{
	DB_RESULT	result;
	DB_ROW		row;

	*mandatory = -1;
	*optional = -1;

	result = DBselect("select mandatory,optional from dbversion");

	if (NULL != (row = DBfetch(result)))
	{
		*mandatory = atoi(row[0]);
		*optional = atoi(row[1]);
	}
	DBfree_result(result);

	if (-1 == *mandatory)
	{
		zabbix_log(LOG_LEVEL_CRIT, "Cannot get the database version. Exiting ...");
		exit(EXIT_FAILURE);
	}
}
示例#9
0
/******************************************************************************
 *                                                                            *
 * Function:                                                                  *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int ja_host_unlock(const char *host)
{
    int db_ret;
    char *host_esc;
    const char *__function_name = "ja_host_unlock";

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

    DBfree_result(DBselect
                  ("select lock_host_name from ja_host_lock_table where lock_host_name = 'HOST_LOCK_RECORD' for update"));

    host_esc = DBdyn_escape_string(host);
    db_ret =
        DBexecute
        ("delete from ja_host_lock_table where lock_host_name = '%s'",
         host_esc);
    zbx_free(host_esc);

    if (db_ret < ZBX_DB_OK)
        return FAIL;
    else
        return SUCCEED;
}
示例#10
0
/******************************************************************************
 *                                                                            *
 * Function: convert_condition_values                                         *
 *                                                                            *
 * Purpose: special processing for "value" field in "conditions" table        *
 *                                                                            *
 * Parameters: old_id - old id, new_id - new node id                          *
 *                                                                            *
 * Return value: SUCCEED - converted successfully                             *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Aleksandrs Saveljevs                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int convert_condition_values(int old_id, int new_id, const char *rel_table_name, int type)
{
	zbx_uint64_t	prefix;
	const ZBX_TABLE	*r_table;
	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	value;

	if (NULL == (r_table = DBget_table(rel_table_name)))
	{
		printf("conditions.value FAILED\n");
		return FAIL;
	}

	prefix = (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)new_id;
	if (r_table->flags & ZBX_SYNC)
		prefix += (zbx_uint64_t)__UINT64_C(100000000000)*(zbx_uint64_t)new_id;

	result = DBselect("select conditionid,value"
			" from conditions"
			" where conditiontype=%d",
			type);

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(value, row[1]);
		value += prefix;
		DBexecute("update conditions"
			" set value='" ZBX_FS_UI64 "'"
			" where conditionid=%s",
			value,
			row[0]);
	}
	DBfree_result(result);

	return SUCCEED;
}
示例#11
0
/******************************************************************************
 *                                                                            *
 * Function:                                                                  *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int ja_setenv(const zbx_uint64_t inner_job_id)
{
    int ret;
    DB_RESULT result;
    DB_ROW row;
    char *key, *value;
    const char *__function_name = "ja_setenv";

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

    result =
        DBselect
        ("select value_name, before_value from ja_run_value_before_table"
         " where inner_job_id = " ZBX_FS_UI64, inner_job_id);

    ret = SUCCEED;
    while (NULL != (row = DBfetch(result))) {
        key = row[0];
        value = row[1];

        zabbix_log(LOG_LEVEL_DEBUG,
                   "In %s() inner_job_id: " ZBX_FS_UI64
                   ",  %s = %s", __function_name,
                   inner_job_id, key, value);

        if (setenv(key, value, 1) != 0) {
            ja_log("JAENV300001", 0, NULL, inner_job_id, __function_name,
                   inner_job_id, key, value);
            ret = FAIL;
            break;
        }
    }
    DBfree_result(result);
    return ret;
}
示例#12
0
/******************************************************************************
 *                                                                            *
 * Function: init_config                                                      *
 *                                                                            *
 * Purpose: init list of medias to send notifications in case if DB is down   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void init_config()
{
	DB_RESULT	result;
	DB_ROW		row;

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

	result = DBselect("select mt.mediatypeid, mt.type, mt.description, mt.smtp_server, mt.smtp_helo, mt.smtp_email, mt.exec_path, mt.gsm_modem, mt.username, mt.passwd, m.mediaid,m.userid,m.mediatypeid,m.sendto,m.severity,m.period from media m, users_groups u, config c,media_type mt where m.userid=u.userid and u.usrgrpid=c.alert_usrgrpid and m.mediatypeid=mt.mediatypeid and m.active=%d",
		MEDIA_STATUS_ACTIVE);
	while((row=DBfetch(result)))
	{
		if(num>=ZBX_MAX_RECIPIENTS)	break;

		memset(&recipients[num].mediatype, 0, sizeof(DB_MEDIATYPE));
		memset(&recipients[num].alert, 0, sizeof(DB_ALERT));

		ZBX_STR2UINT64(recipients[num].mediatype.mediatypeid,row[0]);
		recipients[num].mediatype.type=atoi(row[1]);
		recipients[num].mediatype.description=strdup(row[2]);
		recipients[num].mediatype.smtp_server=strdup(row[3]);
		recipients[num].mediatype.smtp_helo=strdup(row[4]);
		recipients[num].mediatype.smtp_email=strdup(row[5]);
		recipients[num].mediatype.exec_path=strdup(row[6]);
		recipients[num].mediatype.gsm_modem=strdup(row[7]);
		recipients[num].mediatype.username=strdup(row[8]);
		recipients[num].mediatype.passwd=strdup(row[9]);

		recipients[num].alert.sendto=strdup(row[13]);
		recipients[num].alert.subject=strdup("ZABBIX database is down.");
		recipients[num].alert.message=strdup("ZABBIX database is down.");

		num++;
	}

	DBfree_result(result);
}
示例#13
0
/******************************************************************************
 *                                                                            *
 * Function:                                                                  *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int ja_host_lockinfo(const char *host)
{
    int ret;
    DB_RESULT result;
    DB_ROW row;
    char *host_esc;
    const char *__function_name = "ja_host_lockinfo";

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

    ret = FAIL;
    host_esc = DBdyn_escape_string(host);
    result =
        DBselect
        ("select lock_host_name from ja_host_lock_table where lock_host_name = '%s'",
         host_esc);
    row = DBfetch(result);
    if (row != NULL)
        ret = SUCCEED;

    zbx_free(host_esc);
    DBfree_result(result);
    return ret;
}
示例#14
0
/******************************************************************************
 *                                                                            *
 * Function: convert_triggers_expression                                      *
 *                                                                            *
 * Purpose: convert trigger expressions to new node ID                        *
 *                                                                            *
 * Parameters: old_id - old id, new_id - new node id                          *
 *                                                                            *
 * Return value: SUCCEED - converted successfully                             *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int convert_triggers_expression(int old_id, int new_id)
{
	zbx_uint64_t	prefix;
	const ZBX_TABLE	*r_table;
	DB_RESULT	result;
	DB_ROW		row;
	char		new_expression[MAX_STRING_LEN];
	char		*new_expression_esc;

	if (NULL == (r_table = DBget_table("functions")))
	{
		printf("triggers.expression FAILED\n");
		return FAIL;
	}

	prefix = (zbx_uint64_t)__UINT64_C(100000000000000)*(zbx_uint64_t)new_id;
	if (r_table->flags & ZBX_SYNC)
		prefix += (zbx_uint64_t)__UINT64_C(100000000000)*(zbx_uint64_t)new_id;

	result = DBselect("select expression,triggerid from triggers");

	while (NULL != (row = DBfetch(result)))
	{
		memset(new_expression, 0, sizeof(new_expression));
		convert_expression(old_id, new_id, prefix, row[0], new_expression);

		new_expression_esc = DBdyn_escape_string_len(new_expression, TRIGGER_EXPRESSION_LEN);
		DBexecute("update triggers set expression='%s' where triggerid=%s",
				new_expression_esc,
				row[1]);
		zbx_free(new_expression_esc);
	}
	DBfree_result(result);

	return SUCCEED;
}
示例#15
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_history_and_trends                                  *
 *                                                                            *
 * Purpose: remove outdated information from history and trends               *
 *                                                                            *
 * Parameters: now - current timestamp                                        *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_history_and_trends(int now)
{
	const char	*__function_name = "housekeeping_history_and_trends";
	zbx_uint64_t	itemid;
	DB_RESULT       result;
	DB_ROW          row;
	int             history, trends, deleted = 0;

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

	result = DBselect(
			"select i.itemid,i.history,i.trends from items i,hosts h"
			" where i.hostid=h.hostid"
				" and h.status in (%d,%d)",
			HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED);

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(itemid, row[0]);
		history = atoi(row[1]);
		trends = atoi(row[2]);

		deleted += delete_history("history", itemid, history, now);
		deleted += delete_history("history_uint", itemid, history, now);
		deleted += delete_history("history_str", itemid, history, now);
		deleted += delete_history("history_text", itemid, history, now);
		deleted += delete_history("history_log", itemid, history, now);
		deleted += delete_history("trends", itemid, trends, now);
		deleted += delete_history("trends_uint", itemid, trends, now);
	}
	DBfree_result(result);

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

	return deleted;
}
/******************************************************************************
 *                                                                            *
 * Function: aggregate_get_items                                              *
 *                                                                            *
 * Purpose: get array of items specified by key for selected groups           *
 *                                                                            *
 * Parameters: itemids - [OUT] list of item ids                               *
 *             groups  - [IN] list of comma-separated host groups             *
 *             itemkey - [IN] item key to aggregate                           *
 *                                                                            *
 ******************************************************************************/
static void	aggregate_get_items(zbx_vector_uint64_t *itemids, const char *groups, const char *itemkey)
{
    const char	*__function_name = "aggregate_get_items";

    char		*group, *esc;
    DB_RESULT	result;
    DB_ROW		row;
    zbx_uint64_t	itemid;
    char		*sql = NULL;
    size_t		sql_alloc = ZBX_KIBIBYTE, sql_offset = 0;
    int		num, n;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() groups:'%s' itemkey:'%s'", __function_name, groups, itemkey);

    sql = zbx_malloc(sql, sql_alloc);

    esc = DBdyn_escape_string(itemkey);

    zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
                       "select distinct i.itemid"
                       " from items i,hosts h,hosts_groups hg,groups g"
                       " where i.hostid=h.hostid"
                       " and h.hostid=hg.hostid"
                       " and hg.groupid=g.groupid"
                       " and i.key_='%s'"
                       " and i.status=%d"
                       " and h.status=%d",
                       esc, ITEM_STATUS_ACTIVE, HOST_STATUS_MONITORED);

    zbx_free(esc);

    num = num_param(groups);

    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and g.name in (");

    for (n = 1; n <= num; n++)
    {
        if (NULL == (group = get_param_dyn(groups, n)))
            continue;

        esc = DBdyn_escape_string(group);

        zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "'%s'", esc);

        if (n != num)
            zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');

        zbx_free(esc);
        zbx_free(group);
    }

    zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ")" DB_NODE, DBnode_local("h.hostid"));

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

    zbx_free(sql);

    while (NULL != (row = DBfetch(result)))
    {
        ZBX_STR2UINT64(itemid, row[0]);
        zbx_vector_uint64_append(itemids, itemid);
    }
    DBfree_result(result);

    zbx_vector_uint64_sort(itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

    zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
示例#17
0
文件: alerter.c 项目: phedders/zabbix
/******************************************************************************
 *                                                                            *
 * Function: main_alerter_loop                                                *
 *                                                                            *
 * Purpose: periodically check table alerts and send notifications if needed  *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: never returns                                                    *
 *                                                                            *
 ******************************************************************************/
int main_alerter_loop()
{
	char			error[MAX_STRING_LEN], *error_esc;
	int			res, now;
	struct	sigaction	phan;
	DB_RESULT		result;
	DB_ROW			row;
	DB_ALERT		alert;
	DB_MEDIATYPE		mediatype;

/*	phan.sa_handler = child_signal_handler;*/
        phan.sa_sigaction = child_signal_handler;
	sigemptyset(&phan.sa_mask);
	phan.sa_flags = SA_SIGINFO;
	sigaction(SIGALRM, &phan, NULL);

	zbx_setproctitle("connecting to the database");

	DBconnect(ZBX_DB_CONNECT_NORMAL);

	for (;;) {
		now = time(NULL);

		result = DBselect("select a.alertid,a.mediatypeid,a.sendto,a.subject,a.message,a.status,mt.mediatypeid"
				",mt.type,mt.description,mt.smtp_server,mt.smtp_helo,mt.smtp_email,mt.exec_path"
				",mt.gsm_modem,mt.username,mt.passwd,a.retries from alerts a,media_type mt"
				" where a.status=%d and a.mediatypeid=mt.mediatypeid and a.alerttype=%d" DB_NODE
				" order by a.clock",
				ALERT_STATUS_NOT_SENT,
				ALERT_TYPE_MESSAGE,
				DBnode_local("mt.mediatypeid"));

		while (NULL != (row = DBfetch(result))) {
			res = FAIL;

			ZBX_STR2UINT64(alert.alertid, row[0]);
			alert.mediatypeid	= atoi(row[1]);
			alert.sendto		= row[2];
			alert.subject		= row[3];
			alert.message		= row[4];
			alert.status		= atoi(row[5]);

			ZBX_STR2UINT64(mediatype.mediatypeid, row[6]);
			mediatype.type		= atoi(row[7]);
			mediatype.description	= row[8];
			mediatype.smtp_server	= row[9];
			mediatype.smtp_helo	= row[10];
			mediatype.smtp_email	= row[11];
			mediatype.exec_path	= row[12];

			mediatype.gsm_modem	= row[13];
			mediatype.username	= row[14];
			mediatype.passwd	= row[15];

			alert.retries		= atoi(row[16]);

			*error = '\0';
			res = execute_action(&alert, &mediatype, error, sizeof(error));

			if (res == SUCCEED)
			{
				zabbix_log( LOG_LEVEL_DEBUG, "Alert ID [" ZBX_FS_UI64 "] was sent successfully",
					alert.alertid);
				DBexecute("update alerts set status=%d,error='' where alertid=" ZBX_FS_UI64,
					ALERT_STATUS_SENT,
					alert.alertid);
			}
			else
			{
				zabbix_log( LOG_LEVEL_DEBUG, "Error sending alert ID [" ZBX_FS_UI64 "]",
					alert.alertid);
				zabbix_syslog("Error sending alert ID [" ZBX_FS_UI64 "]",
					alert.alertid);
				error_esc = DBdyn_escape_string_len(error, ALERT_ERROR_LEN);

				alert.retries++;
				if(alert.retries < ALERT_MAX_RETRIES)
				{
					DBexecute("update alerts set retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
						alert.retries,
						error_esc,
						alert.alertid);
				}
				else
				{
					DBexecute("update alerts set status=%d,retries=%d,error='%s' where alertid=" ZBX_FS_UI64,
						ALERT_STATUS_FAILED,
						alert.retries,
						error_esc,
						alert.alertid);
				}

				zbx_free(error_esc);
			}

		}
		DBfree_result(result);

		zbx_setproctitle("sender [sleeping for %d seconds]",
				CONFIG_SENDER_FREQUENCY);

		sleep(CONFIG_SENDER_FREQUENCY);
	}

	/* Never reached */
	DBclose();
}
示例#18
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_cleanup                                             *
 *                                                                            *
 * Purpose: remove deleted items data                                         *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all  *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_cleanup()
{
	const char		*__function_name = "housekeeping_cleanup";
	DB_HOUSEKEEPER		housekeeper;
	DB_RESULT		result;
	DB_ROW			row;
	int			d, deleted = 0;
	zbx_vector_uint64_t	housekeeperids;

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

	zbx_vector_uint64_create(&housekeeperids);

	/* order by tablename to effectively use DB cache */
	result = DBselect(
			"select housekeeperid,tablename,field,value"
			" from housekeeper"
			" order by tablename");

	while (NULL != (row = DBfetch(result)))
	{
		ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]);
		housekeeper.tablename = row[1];
		housekeeper.field = row[2];
		ZBX_STR2UINT64(housekeeper.value, row[3]);

		if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE)
		{
			d = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64,
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value);
		}
		else
		{
#if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE)
			d = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64
						" and rownum<=%d",
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_MYSQL)
			d = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64 " limit %d",
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_POSTGRESQL)
			d = DBexecute(
					"delete from %s"
					" where ctid = any(array(select ctid from %s"
						" where %s=" ZBX_FS_UI64 " limit %d))",
					housekeeper.tablename,
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_SQLITE3)
			d = 0;
#endif
		}

		if (0 == d || 0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d)
			zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid);

		deleted += d;
	}
	DBfree_result(result);

	if (0 != housekeeperids.values_num)
	{
		char	*sql = NULL;
		size_t	sql_alloc = 512, sql_offset = 0;

		sql = zbx_malloc(sql, sql_alloc);

		zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from housekeeper where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid",
				housekeeperids.values, housekeeperids.values_num);

		DBexecute("%s", sql);

		zbx_free(sql);
	}

	zbx_vector_uint64_destroy(&housekeeperids);

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

	return deleted;
}
示例#19
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;
}
示例#20
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);
}
示例#21
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_cleanup                                             *
 *                                                                            *
 * Purpose: remove deleted items data                                         *
 *                                                                            *
 * Return value: number of rows deleted                                       *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all  *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_cleanup()
{
    const char		*__function_name = "housekeeping_cleanup";

    DB_HOUSEKEEPER		housekeeper;
    DB_RESULT		result;
    DB_ROW			row;
    int			d, deleted = 0;
    zbx_vector_uint64_t	housekeeperids;
    char			*sql = NULL, *table_name_esc;
    size_t			sql_alloc = 0, sql_offset = 0;
    zbx_hk_cleanup_table_t *table;

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

    /* first handle the trivial case when history and trend housekeeping is disabled */
    if (ZBX_HK_OPTION_DISABLED == hk_config.history_mode && ZBX_HK_OPTION_DISABLED == hk_config.trends_mode)
        goto out;

    zbx_vector_uint64_create(&housekeeperids);

    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
                     "select housekeeperid,tablename,field,value"
                     " from housekeeper"
                     " where tablename in (");

    /* assemble list of tables excluded from housekeeping procedure */
    for (table = hk_cleanup_tables; NULL != table->name; table++)
    {
        if (ZBX_HK_OPTION_ENABLED != *table->poption_mode)
            continue;

        table_name_esc = DBdyn_escape_string(table->name);

        zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, '\'');
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, table_name_esc);
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "',");

        zbx_free(table_name_esc);
    }
    sql_offset--;

    /* order by tablename to effectively use DB cache */
    zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ") order by tablename");

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

    while (NULL != (row = DBfetch(result)))
    {
        ZBX_STR2UINT64(housekeeper.housekeeperid, row[0]);
        housekeeper.tablename = row[1];
        housekeeper.field = row[2];
        ZBX_STR2UINT64(housekeeper.value, row[3]);

        if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE)
        {
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64,
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value);
        }
        else
        {
#if defined(HAVE_IBM_DB2) || defined(HAVE_ORACLE)
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64
                    " and rownum<=%d",
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_MYSQL)
            d = DBexecute(
                    "delete from %s"
                    " where %s=" ZBX_FS_UI64 " limit %d",
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_POSTGRESQL)
            d = DBexecute(
                    "delete from %s"
                    " where ctid = any(array(select ctid from %s"
                    " where %s=" ZBX_FS_UI64 " limit %d))",
                    housekeeper.tablename,
                    housekeeper.tablename,
                    housekeeper.field,
                    housekeeper.value,
                    CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_SQLITE3)
            d = 0;
#endif
        }

        if (ZBX_DB_OK <= d)
        {
            if (0 == CONFIG_MAX_HOUSEKEEPER_DELETE || CONFIG_MAX_HOUSEKEEPER_DELETE > d)
                zbx_vector_uint64_append(&housekeeperids, housekeeper.housekeeperid);

            deleted += d;
        }
    }
    DBfree_result(result);

    if (0 != housekeeperids.values_num)
    {
        zbx_vector_uint64_sort(&housekeeperids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

        sql_offset = 0;
        zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from housekeeper where");
        DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "housekeeperid",
                              housekeeperids.values, housekeeperids.values_num);

        DBexecute("%s", sql);
    }

    zbx_free(sql);

    zbx_vector_uint64_destroy(&housekeeperids);
out:
    zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d", __function_name, deleted);

    return deleted;
}
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);
}
示例#23
0
/******************************************************************************
 *                                                                            *
 * 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);
}
示例#24
0
/******************************************************************************
 *                                                                            *
 * Function: save_template_item_applications                                  *
 *                                                                            *
 * Purpose: saves new item applications links in database                     *
 *                                                                            *
 * Parameters:  items   - [IN] the template items                             *
 *                                                                            *
 ******************************************************************************/
void	save_template_item_applications(zbx_vector_ptr_t *items)
{
	typedef struct
	{
		zbx_uint64_t	itemid;
		zbx_uint64_t	applicationid;
	}
	zbx_itemapp_t;

	DB_RESULT		result;
	DB_ROW			row;
	char			*sql = NULL;
	size_t			sql_alloc = 0, sql_offset = 0;
	zbx_vector_uint64_t	itemids;
	zbx_vector_ptr_t	itemapps;
	zbx_itemapp_t		*itemapp;
	int 			i;
	zbx_db_insert_t		db_insert;

	zbx_vector_ptr_create(&itemapps);
	zbx_vector_uint64_create(&itemids);

	for (i = 0; i < items->values_num; i++)
	{
		zbx_template_item_t	*item = items->values[i];

		zbx_vector_uint64_append(&itemids, item->itemid);
	}

	zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
			"select hi.itemid,ha.applicationid"
			" from items_applications tia"
				" join items hi on hi.templateid=tia.itemid"
					" and");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hi.itemid", itemids.values, itemids.values_num);
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				" join application_template hat on hat.templateid=tia.applicationid"
				" join applications ha on ha.applicationid=hat.applicationid"
					" and ha.hostid=hi.hostid"
					" left join items_applications hia on hia.applicationid=ha.applicationid"
						" and hia.itemid=hi.itemid"
			" where hia.itemappid is null");

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

	while (NULL != (row = DBfetch(result)))
	{
		itemapp = zbx_malloc(NULL, sizeof(zbx_itemapp_t));

		ZBX_STR2UINT64(itemapp->itemid, row[0]);
		ZBX_STR2UINT64(itemapp->applicationid, row[1]);

		zbx_vector_ptr_append(&itemapps, itemapp);
	}
	DBfree_result(result);

	if (0 == itemapps.values_num)
		goto out;

	zbx_db_insert_prepare(&db_insert, "items_applications", "itemappid", "itemid", "applicationid", NULL);

	for (i = 0; i < itemapps.values_num; i++)
	{
		itemapp = itemapps.values[i];

		zbx_db_insert_add_values(&db_insert, __UINT64_C(0), itemapp->itemid, itemapp->applicationid);
	}

	zbx_db_insert_autoincrement(&db_insert, "itemappid");
	zbx_db_insert_execute(&db_insert);
	zbx_db_insert_clean(&db_insert);
out:
	zbx_free(sql);

	zbx_vector_uint64_destroy(&itemids);

	zbx_vector_ptr_clear_ext(&itemapps, zbx_ptr_free);
	zbx_vector_ptr_destroy(&itemapps);
}
示例#25
0
/******************************************************************************
 *                                                                            *
 * Function: get_template_lld_rule_map                                        *
 *                                                                            *
 * Purpose: reads template lld rule conditions and host lld_rule identifiers  *
 *          from database                                                     *
 *                                                                            *
 * Parameters: items - [IN] the host items including lld rules                *
 *             rules - [OUT] the ldd rule mapping                             *
 *                                                                            *
 ******************************************************************************/
static void	get_template_lld_rule_map(const zbx_vector_ptr_t *items, zbx_vector_ptr_t *rules)
{
	zbx_template_item_t		*item;
	zbx_lld_rule_map_t		*rule;
	zbx_lld_rule_condition_t	*condition;
	int				i, index;
	zbx_vector_uint64_t		itemids;
	DB_RESULT			result;
	DB_ROW				row;
	char				*sql = NULL;
	size_t				sql_alloc = 0, sql_offset = 0;
	zbx_uint64_t			itemid, item_conditionid;

	zbx_vector_uint64_create(&itemids);

	/* prepare discovery rules */
	for (i = 0; i < items->values_num; i++)
	{
		item = items->values[i];

		if (0 == (ZBX_FLAG_DISCOVERY_RULE & item->flags))
			continue;

		rule = zbx_malloc(NULL, sizeof(zbx_lld_rule_map_t));

		rule->itemid = item->itemid;
		rule->templateid = item->templateid;
		rule->conditionid = 0;
		zbx_vector_uint64_create(&rule->conditionids);
		zbx_vector_ptr_create(&rule->conditions);

		zbx_vector_ptr_append(rules, rule);

		if (0 != rule->itemid)
			zbx_vector_uint64_append(&itemids, rule->itemid);
		zbx_vector_uint64_append(&itemids, rule->templateid);
	}

	if (0 != itemids.values_num)
	{
		zbx_vector_ptr_sort(rules, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
		zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				"select item_conditionid,itemid,operator,macro,value from item_condition where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);

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

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(itemid, row[1]);

			index = zbx_vector_ptr_bsearch(rules, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

			if (FAIL != index)
			{
				/* read template lld conditions */

				rule = (zbx_lld_rule_map_t *)rules->values[index];

				condition = zbx_malloc(NULL, sizeof(zbx_lld_rule_condition_t));

				ZBX_STR2UINT64(condition->item_conditionid, row[0]);
				ZBX_STR2UCHAR(condition->operator, row[2]);
				condition->macro = zbx_strdup(NULL, row[3]);
				condition->value = zbx_strdup(NULL, row[4]);

				zbx_vector_ptr_append(&rule->conditions, condition);
			}
			else
			{
				/* read host lld conditions identifiers */

				for (i = 0; i < rules->values_num; i++)
				{
					rule = (zbx_lld_rule_map_t *)rules->values[i];

					if (itemid != rule->itemid)
						continue;

					ZBX_STR2UINT64(item_conditionid, row[0]);
					zbx_vector_uint64_append(&rule->conditionids, item_conditionid);

					break;
				}

				if (i == rules->values_num)
					THIS_SHOULD_NEVER_HAPPEN;
			}
		}
		DBfree_result(result);

		zbx_free(sql);
	}

	zbx_vector_uint64_destroy(&itemids);
}
static void	execute_commands(DB_EVENT *event, zbx_uint64_t actionid, zbx_uint64_t operationid, int esc_step)
{
	const char	*__function_name = "execute_commands";
	DB_RESULT	result;
	DB_ROW		row;

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

	result = DBselect(
			"select distinct h.hostid,h.host,o.type,o.scriptid,o.execute_on,o.port"
				",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command"
#ifdef HAVE_OPENIPMI
				",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password"
#endif
			" from opcommand o,opcommand_grp og,hosts_groups hg,hosts h"
			" where o.operationid=og.operationid"
				" and og.groupid=hg.groupid"
				" and hg.hostid=h.hostid"
				" and o.operationid=" ZBX_FS_UI64
				" and h.status=%d"
			" union "
			"select distinct h.hostid,h.host,o.type,o.scriptid,o.execute_on,o.port"
				",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command"
#ifdef HAVE_OPENIPMI
				",h.ipmi_authtype,h.ipmi_privilege,h.ipmi_username,h.ipmi_password"
#endif
			" from opcommand o,opcommand_hst oh,hosts h"
			" where o.operationid=oh.operationid"
				" and oh.hostid=h.hostid"
				" and o.operationid=" ZBX_FS_UI64
				" and h.status=%d"
			" union "
			"select distinct 0,null,o.type,o.scriptid,o.execute_on,o.port"
				",o.authtype,o.username,o.password,o.publickey,o.privatekey,o.command"
#ifdef HAVE_OPENIPMI
				",0,2,null,null"
#endif
			" from opcommand o,opcommand_hst oh"
			" where o.operationid=oh.operationid"
				" and o.operationid=" ZBX_FS_UI64
				" and oh.hostid is null",
			operationid, HOST_STATUS_MONITORED,
			operationid, HOST_STATUS_MONITORED,
			operationid);

	while (NULL != (row = DBfetch(result)))
	{
		int			rc = SUCCEED;
		char			error[ALERT_ERROR_LEN_MAX];
		DC_HOST			host;
		zbx_script_t		script;
		zbx_alert_status_t	status;

		*error = '\0';
		memset(&host, 0, sizeof(host));
		zbx_script_init(&script);

		ZBX_STR2UINT64(host.hostid, row[0]);

		if (0 != host.hostid)
		{
			strscpy(host.host, row[1]);
#ifdef HAVE_OPENIPMI
			host.ipmi_authtype = (signed char)atoi(row[12]);
			host.ipmi_privilege = (unsigned char)atoi(row[13]);
			strscpy(host.ipmi_username, row[14]);
			strscpy(host.ipmi_password, row[15]);
#endif
		}
		else
			rc = get_dynamic_hostid(event, &host, error, sizeof(error));

		script.type = (unsigned char)atoi(row[2]);

		if (ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT != script.type)
		{
			script.command = zbx_strdup(script.command, row[11]);
			substitute_simple_macros(event, NULL, NULL, NULL, NULL, NULL,
					&script.command, MACRO_TYPE_MESSAGE, NULL, 0);
		}

		if (SUCCEED == rc)
		{
			switch (script.type)
			{
				case ZBX_SCRIPT_TYPE_CUSTOM_SCRIPT:
					script.execute_on = (unsigned char)atoi(row[4]);
					break;
				case ZBX_SCRIPT_TYPE_SSH:
					script.authtype = (unsigned char)atoi(row[6]);
					script.publickey = zbx_strdup(script.publickey, row[9]);
					script.privatekey = zbx_strdup(script.privatekey, row[10]);
					/* break; is not missing here */
				case ZBX_SCRIPT_TYPE_TELNET:
					script.port = zbx_strdup(script.port, row[5]);
					script.username = zbx_strdup(script.username, row[7]);
					script.password = zbx_strdup(script.password, row[8]);
					break;
				case ZBX_SCRIPT_TYPE_GLOBAL_SCRIPT:
					ZBX_DBROW2UINT64(script.scriptid, row[3]);
					break;
			}

			rc = zbx_execute_script(&host, &script, NULL, error, sizeof(error));
		}

		status = (SUCCEED != rc ? ALERT_STATUS_FAILED : ALERT_STATUS_SENT);

		add_command_alert(&host, event->eventid, actionid, esc_step, script.command, status, error);

		zbx_script_clean(&script);
	}
	DBfree_result(result);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
示例#27
0
/******************************************************************************
 *                                                                            *
 * Function: save_template_discovery_prototypes                               *
 *                                                                            *
 * Purpose: saves host item prototypes in database                            *
 *                                                                            *
 * Parameters:  hostid  - [IN] the target host                                *
 *              items   - [IN] the template items                             *
 *                                                                            *
 ******************************************************************************/
void	save_template_discovery_prototypes(zbx_uint64_t hostid, zbx_vector_ptr_t *items)
{
	typedef struct
	{
		zbx_uint64_t	itemid;
		zbx_uint64_t	parent_itemid;
	}
	zbx_proto_t;

	DB_RESULT		result;
	DB_ROW			row;
	char			*sql = NULL;
	size_t			sql_alloc = 0, sql_offset = 0;
	zbx_vector_uint64_t	itemids;
	zbx_vector_ptr_t	prototypes;
	zbx_proto_t		*proto;
	int 			i;
	zbx_db_insert_t		db_insert;

	zbx_vector_ptr_create(&prototypes);
	zbx_vector_uint64_create(&itemids);

	for (i = 0; i < items->values_num; i++)
	{
		zbx_template_item_t	*item = items->values[i];

		/* process only new prototype items */
		if (NULL == item->key || 0 == (ZBX_FLAG_DISCOVERY_PROTOTYPE & item->flags))
			continue;

		zbx_vector_uint64_append(&itemids, item->itemid);
	}

	if (0 == itemids.values_num)
		goto out;

	zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select i.itemid,r.itemid"
			" from items i,item_discovery id,items r"
			" where i.templateid=id.itemid"
				" and id.parent_itemid=r.templateid"
				" and r.hostid=" ZBX_FS_UI64
				" and",
			hostid);
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "i.itemid", itemids.values, itemids.values_num);

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

	while (NULL != (row = DBfetch(result)))
	{
		proto = zbx_malloc(NULL, sizeof(zbx_proto_t));

		ZBX_STR2UINT64(proto->itemid, row[0]);
		ZBX_STR2UINT64(proto->parent_itemid, row[1]);

		zbx_vector_ptr_append(&prototypes, proto);
	}
	DBfree_result(result);

	if (0 == prototypes.values_num)
		goto out;

	zbx_db_insert_prepare(&db_insert, "item_discovery", "itemdiscoveryid", "itemid",
					"parent_itemid", NULL);

	for (i = 0; i < prototypes.values_num; i++)
	{
		proto = prototypes.values[i];

		zbx_db_insert_add_values(&db_insert, __UINT64_C(0), proto->itemid, proto->parent_itemid);
	}

	zbx_db_insert_autoincrement(&db_insert, "itemdiscoveryid");
	zbx_db_insert_execute(&db_insert);
	zbx_db_insert_clean(&db_insert);
out:
	zbx_free(sql);

	zbx_vector_uint64_destroy(&itemids);

	zbx_vector_ptr_clear_ext(&prototypes, zbx_ptr_free);
	zbx_vector_ptr_destroy(&prototypes);
}
static void	add_message_alert(DB_ESCALATION *escalation, DB_EVENT *event, DB_ACTION *action,
		zbx_uint64_t userid, zbx_uint64_t mediatypeid, const char *subject, const char *message)
{
	const char	*__function_name = "add_message_alert";

	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	alertid;
	int		now, severity, medias = 0;
	char		*subject_dyn, *message_dyn, *sendto_esc, *subject_esc, *message_esc, *error_esc;
	char		error[MAX_STRING_LEN];

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

	subject_dyn = zbx_strdup(NULL, subject);
	message_dyn = zbx_strdup(NULL, message);

	substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &subject_dyn, MACRO_TYPE_MESSAGE, NULL, 0);
	substitute_simple_macros(event, &userid, NULL, NULL, NULL, NULL, &message_dyn, MACRO_TYPE_MESSAGE, NULL, 0);

	now = time(NULL);
	subject_esc = DBdyn_escape_string_len(subject_dyn, ALERT_SUBJECT_LEN);
	message_esc = DBdyn_escape_string_len(message_dyn, ALERT_MESSAGE_LEN);

	zbx_free(subject_dyn);
	zbx_free(message_dyn);

	if (0 == mediatypeid)
	{
		result = DBselect(
				"select m.mediatypeid,m.sendto,m.severity,m.period,mt.status"
				" from media m,media_type mt"
				" where m.mediatypeid=mt.mediatypeid"
					" and m.active=%d"
					" and m.userid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE, userid);
	}
	else
	{
		result = DBselect(
				"select m.mediatypeid,m.sendto,m.severity,m.period,mt.status"
				" from media m,media_type mt"
				" where m.mediatypeid=mt.mediatypeid"
					" and m.active=%d"
					" and m.userid=" ZBX_FS_UI64
					" and m.mediatypeid=" ZBX_FS_UI64,
				MEDIA_STATUS_ACTIVE, userid, mediatypeid);
	}

	while (NULL != (row = DBfetch(result)))
	{
		medias		= 1;

		ZBX_STR2UINT64(mediatypeid, row[0]);
		severity	= atoi(row[2]);

		zabbix_log(LOG_LEVEL_DEBUG, "Trigger severity [%d] Media severity [%d] Period [%s]",
				(int)event->trigger.priority, severity, row[3]);

		if (((1 << event->trigger.priority) & severity) == 0)
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (severity)");
			continue;
		}

		if (FAIL == check_time_period(row[3], (time_t)NULL))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Won't send message (period)");
			continue;
		}

		alertid		= DBget_maxid("alerts");
		sendto_esc	= DBdyn_escape_string_len(row[1], ALERT_SENDTO_LEN);

		if (MEDIA_TYPE_STATUS_ACTIVE == atoi(row[4]))
		{
			DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
					",mediatypeid,sendto,subject,message,status,alerttype,esc_step)"
					" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
					"," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d)",
					alertid,
					action->actionid,
					event->eventid,
					userid,
					now,
					mediatypeid,
					sendto_esc,
					subject_esc,
					message_esc,
					ALERT_STATUS_NOT_SENT,
					ALERT_TYPE_MESSAGE,
					escalation->esc_step);
		}
		else
		{
			error_esc = DBdyn_escape_string("Media type disabled");

			DBexecute("insert into alerts (alertid,actionid,eventid,userid,clock"
					",mediatypeid,sendto,subject,message,status,alerttype,esc_step,error)"
					" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d"
					"," ZBX_FS_UI64 ",'%s','%s','%s',%d,%d,%d,'%s')",
					alertid,
					action->actionid,
					event->eventid,
					userid,
					now,
					mediatypeid,
					sendto_esc,
					subject_esc,
					message_esc,
					ALERT_STATUS_FAILED,
					ALERT_TYPE_MESSAGE,
					escalation->esc_step,
					error_esc);

			zbx_free(error_esc);
		}

		zbx_free(sendto_esc);
	}

	DBfree_result(result);

	if (0 == medias)
	{
		zbx_snprintf(error, sizeof(error), "No media defined for user \"%s\"",
				zbx_user_string(userid));

		alertid		= DBget_maxid("alerts");
		error_esc	= DBdyn_escape_string(error);

		DBexecute("insert into alerts (alertid,actionid,eventid,userid,retries,clock"
				",subject,message,status,alerttype,error,esc_step)"
				" values (" ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 "," ZBX_FS_UI64 ",%d,%d"
				",'%s','%s',%d,%d,'%s',%d)",
				alertid,
				action->actionid,
				event->eventid,
				userid,
				ALERT_MAX_RETRIES,
				now,
				subject_esc,
				message_esc,
				ALERT_STATUS_FAILED,
				ALERT_TYPE_MESSAGE,
				error_esc,
				escalation->esc_step);

		zbx_free(error_esc);
	}

	zbx_free(subject_esc);
	zbx_free(message_esc);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * Function: evaluate_aggregate                                               *
 *                                                                            *
 * Parameters: item      - [IN] aggregated item                               *
 *             grp_func  - [IN] one of ZBX_GRP_FUNC_*                         *
 *             groups    - [IN] list of comma-separated host groups           *
 *             itemkey   - [IN] item key to aggregate                         *
 *             item_func - [IN] one of ZBX_DB_GET_HIST_*                      *
 *             param     - [IN] item_func parameter (optional)                *
 *                                                                            *
 * Return value: SUCCEED - aggregate item evaluated successfully              *
 *               FAIL - otherwise                                             *
 *                                                                            *
 ******************************************************************************/
static int	evaluate_aggregate(DC_ITEM *item, AGENT_RESULT *res, int grp_func, const char *groups,
                               const char *itemkey, int item_func, const char *param)
{
    const char		*__function_name = "evaluate_aggregate";

    char			*sql = NULL;
    size_t			sql_alloc = 1024, sql_offset = 0;
    zbx_uint64_t		itemid;
    zbx_vector_uint64_t	itemids;
    DB_RESULT		result;
    DB_ROW			row;
    unsigned char		value_type;
    history_value_t		value;
    int			num = 0, ret = FAIL;

    zabbix_log(LOG_LEVEL_DEBUG, "In %s() grp_func:%d groups:'%s' itemkey:'%s' item_func:%d param:'%s'",
               __function_name, grp_func, groups, itemkey, item_func, param);

    memset(&value, 0, sizeof(value));

    zbx_vector_uint64_create(&itemids);
    aggregate_get_items(&itemids, groups, itemkey);

    if (0 == itemids.values_num)
    {
        SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No items for key [%s] in group(s) [%s]", itemkey, groups));
        goto clean;
    }

    sql = zbx_malloc(sql, sql_alloc);

    if (ZBX_DB_GET_HIST_VALUE == item_func)
    {
        zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
                           "select value_type,lastvalue"
                           " from items"
                           " where lastvalue is not null"
                           " and value_type in (%d,%d)"
                           " and",
                           ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64);
        DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);

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

        while (NULL != (row = DBfetch(result)))
        {
            value_type = (unsigned char)atoi(row[0]);

            evaluate_one(item, &value, &num, grp_func, row[1], value_type);
        }
        DBfree_result(result);
    }
    else
    {
        int		clock_from;
        unsigned int	period;
        char		**h_value;

        if (FAIL == is_uint_suffix(param, &period))
        {
            SET_MSG_RESULT(res, zbx_strdup(NULL, "Invalid fourth parameter"));
            goto clean;
        }

        clock_from = time(NULL) - period;

        zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
                           "select itemid,value_type"
                           " from items"
                           " where value_type in (%d,%d)"
                           " and",
                           ITEM_VALUE_TYPE_FLOAT, ITEM_VALUE_TYPE_UINT64);
        DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);

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

        while (NULL != (row = DBfetch(result)))
        {
            ZBX_STR2UINT64(itemid, row[0]);
            value_type = (unsigned char)atoi(row[1]);

            h_value = DBget_history(itemid, value_type, item_func, clock_from, 0, NULL, NULL, 0);

            if (NULL != h_value[0])
                evaluate_one(item, &value, &num, grp_func, h_value[0], value_type);
            DBfree_history(h_value);
        }
        DBfree_result(result);
    }

    if (0 == num)
    {
        SET_MSG_RESULT(res, zbx_dsprintf(NULL, "No values for key \"%s\" in group(s) \"%s\"", itemkey, groups));
        goto clean;
    }

    if (ZBX_GRP_FUNC_AVG == grp_func)
    {
        switch (item->value_type)
        {
        case ITEM_VALUE_TYPE_FLOAT:
            value.dbl = value.dbl / num;
            break;
        case ITEM_VALUE_TYPE_UINT64:
            value.ui64 = value.ui64 / num;
            break;
        default:
            assert(0);
        }
    }

    if (ITEM_VALUE_TYPE_FLOAT == item->value_type)
        SET_DBL_RESULT(res, value.dbl);
    else
        SET_UI64_RESULT(res, value.ui64);

    ret = SUCCEED;
clean:
    zbx_vector_uint64_destroy(&itemids);
    zbx_free(sql);

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

    return ret;
}
/******************************************************************************
 *                                                                            *
 * Function: check_operation_conditions                                       *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters: event - event to check                                         *
 *             actionid - action ID for matching                              *
 *                                                                            *
 * Return value: SUCCEED - matches, FAIL - otherwise                          *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	check_operation_conditions(DB_EVENT *event, zbx_uint64_t operationid, unsigned char evaltype)
{
	const char	*__function_name = "check_operation_conditions";

	DB_RESULT	result;
	DB_ROW		row;
	DB_CONDITION	condition;

	int	ret = SUCCEED; /* SUCCEED required for ACTION_EVAL_TYPE_AND_OR */
	int	cond, old_type = -1, exit = 0;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() operationid:" ZBX_FS_UI64, __function_name, operationid);

	result = DBselect("select conditiontype,operator,value"
				" from opconditions"
				" where operationid=" ZBX_FS_UI64
				" order by conditiontype",
			operationid);

	while (NULL != (row = DBfetch(result)) && 0 == exit)
	{
		memset(&condition, 0, sizeof(condition));
		condition.conditiontype	= atoi(row[0]);
		condition.operator	= atoi(row[1]);
		condition.value		= row[2];

		switch (evaltype)
		{
			case ACTION_EVAL_TYPE_AND_OR:
				if (old_type == condition.conditiontype)	/* OR conditions */
				{
					if (SUCCEED == check_action_condition(event, &condition))
						ret = SUCCEED;
				}
				else						/* AND conditions */
				{
					/* Break if PREVIOUS AND condition is FALSE */
					if (ret == FAIL)
						exit = 1;
					else if (FAIL == check_action_condition(event, &condition))
						ret = FAIL;
				}
				old_type = condition.conditiontype;
				break;
			case ACTION_EVAL_TYPE_AND:
				cond = check_action_condition(event, &condition);
				/* Break if any of AND conditions is FALSE */
				if (cond == FAIL)
				{
					ret = FAIL;
					exit = 1;
				}
				else
					ret = SUCCEED;
				break;
			case ACTION_EVAL_TYPE_OR:
				cond = check_action_condition(event, &condition);
				/* Break if any of OR conditions is TRUE */
				if (cond == SUCCEED)
				{
					ret = SUCCEED;
					exit = 1;
				}
				else
					ret = FAIL;
				break;
			default:
				ret = FAIL;
				exit = 1;
				break;
		}
	}
	DBfree_result(result);

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

	return ret;
}