Exemplo n.º 1
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);
}
Exemplo n.º 2
0
/******************************************************************************
 *                                                                            *
 * Function : process_hstory_table_data:                                      *
 *                                                                            *
 * Purpose: process new history data                                          *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              * 
 *                                                                            *
 * Author: Aleksander Vladishev                                               *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	process_history_table_data(ZBX_TABLE *table, int master_nodeid, int nodeid)
{
	DB_RESULT	result;
	DB_ROW		row;
	char		*data = NULL, *tmp = NULL;
	int		data_allocated = 1024*1024, tmp_allocated = 4096, tmp_offset, data_offset, f, fld, len;
	int		data_found = 0;
	zbx_uint64_t	lastid;
	int		lastclock = 0, clock;

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

	DBbegin();

	if ((table->flags & ZBX_HISTORY) && FAIL == get_history_lastid(master_nodeid, nodeid, table, &lastid))
		return;
	if ((table->flags & ZBX_HISTORY_TRENDS) && FAIL == get_trends_lastid(master_nodeid, nodeid, table, &lastid, &lastclock))
		return;

	data = zbx_malloc(data, data_allocated);
	tmp = zbx_malloc(tmp, tmp_allocated);

	data_offset = 0;
	zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "History%c%d%c%d%c%s",
		ZBX_DM_DELIMITER, CONFIG_NODEID,
		ZBX_DM_DELIMITER, nodeid,
		ZBX_DM_DELIMITER, table->table);

	/* Do not send history for current node if CONFIG_NODE_NOHISTORY is set */
/*	if ((CONFIG_NODE_NOHISTORY != 0) && (CONFIG_NODEID == nodeid))
		goto exit;*/

	tmp_offset = 0;
	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "select %s,",
			table->recid);
	} else { /* ZBX_HISTORY, ZBX_HISTORY_TRENDS */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 16, "select ");
	}

	for (f = 0; table->fields[f].name != 0; f++) {
		if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
			continue;

		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 128, "%s,",
			table->fields[f].name);
	}
	tmp_offset--;

	if (table->flags & ZBX_HISTORY_SYNC) {
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where nodeid=%d order by %s",
			table->table,
			nodeid,
			table->recid);
	} else if (table->flags & ZBX_HISTORY_TRENDS) {
		clock = time(NULL) - 600; /* -10min */
		clock -= clock % 3600;

		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where"
			" (itemid>"ZBX_FS_UI64" or (itemid="ZBX_FS_UI64" and clock>%d)) and clock<%d"
			DB_NODE " order by itemid,clock",
			table->table,
			lastid, lastid, lastclock, clock,
			DBnode("itemid", nodeid));
	} else { /* ZBX_HISTORY */
		zbx_snprintf_alloc(&tmp, &tmp_allocated, &tmp_offset, 1024, " from %s where %s>"ZBX_FS_UI64
			DB_NODE " order by %s",
			table->table,
			table->recid,
			lastid,
			DBnode(table->recid, nodeid),
			table->recid);
	}

	result = DBselectN(tmp, 10000);
	while (NULL != (row = DBfetch(result))) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			ZBX_STR2UINT64(lastid, row[0]);
			fld = 1;
		} else
			fld = 0;

		zbx_snprintf_alloc(&data, &data_allocated, &data_offset, 128, "\n");

		for (f = 0; table->fields[f].name != 0; f++) {
			if ((table->flags & ZBX_HISTORY_SYNC) && 0 == (table->fields[f].flags & ZBX_HISTORY_SYNC))
				continue;

			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%c",
					row[fld], ZBX_DM_DELIMITER);
			} else { /* ZBX_TYPE_CHAR ZBX_TYPE_BLOB ZBX_TYPE_TEXT */
				len = (int)strlen(row[fld]);
				len = zbx_binary2hex((u_char *)row[fld], len, &tmp, &tmp_allocated);
				zbx_snprintf_alloc(&data, &data_allocated, &data_offset, len + 8, "%s%c",
					tmp, ZBX_DM_DELIMITER);
			}
			fld++;
		}
		data_offset--;
		data_found = 1;
	}
	DBfree_result(result);

	data[data_offset] = '\0';

	if (1 == data_found && SUCCEED == send_to_node(table->table, master_nodeid, nodeid, data)) {
		if (table->flags & ZBX_HISTORY_SYNC) {
			DBexecute("delete from %s where nodeid=%d and %s<="ZBX_FS_UI64,
				table->table,
				nodeid,
				table->recid,
				lastid);
		}
	}

	DBcommit();

	zbx_free(tmp);
	zbx_free(data);
}
Exemplo n.º 3
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;
}