Exemplo n.º 1
0
/******************************************************************************
 *                                                                            *
 * Function: calculate_checksums                                              *
 *                                                                            *
 * Purpose: calculate checksums of configuration data                         *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCESS - calculated successfully                            *
 *               FAIL - an error occurred                                     *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
int	calculate_checksums(int nodeid, const char *tablename, const zbx_uint64_t recordid)
{
	const char	*__function_name = "calculate_checksums";

	char		*sql = NULL;
	size_t		sql_alloc = 2 * ZBX_KIBIBYTE, sql_offset = 0;
	int		t, f, res = SUCCEED;

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

	sql = zbx_malloc(sql, sql_alloc);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"delete from node_cksum"
			" where nodeid=%d"
				" and cksumtype=%d",
			nodeid, NODE_CKSUM_TYPE_NEW);

	if (NULL != tablename)
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and tablename='%s'", tablename);

	if (0 != recordid)
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " and recordid=" ZBX_FS_UI64, recordid);

	if (ZBX_DB_OK > DBexecute("%s", sql))
		res = FAIL;

	for (t = 0; NULL != tables[t].table; t++)
	{
		if (0 == (tables[t].flags & ZBX_SYNC))
			continue;

		if (NULL != tablename && 0 != strcmp(tablename, tables[t].table))
			continue;

		sql_offset = 0;
		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"insert into node_cksum (nodeid,tablename,recordid,cksumtype,cksum)"
				" select %d,'%s',%s,%d,",
				nodeid, tables[t].table, tables[t].recid, NODE_CKSUM_TYPE_NEW);
#ifdef HAVE_MYSQL
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "concat_ws(',',");
#endif

		for (f = 0; NULL != tables[t].fields[f].name; f++)
		{
			const ZBX_FIELD	*field = &tables[t].fields[f];

			if (0 == (field->flags & ZBX_SYNC))
				continue;

			if (field->flags & ZBX_NOTNULL)
			{
				switch (field->type)
				{
					case ZBX_TYPE_ID:
					case ZBX_TYPE_INT:
					case ZBX_TYPE_UINT:
						zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, field->name);
						break;
					case ZBX_TYPE_FLOAT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								"md5(cast(%s as char))", field->name);
						break;
					default:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								"md5(%s)", field->name);
						break;
				}
			}
			else
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
						"case when %s is null then 'NULL'", field->name);

				switch (field->type)
				{
					case ZBX_TYPE_ID:
					case ZBX_TYPE_INT:
					case ZBX_TYPE_UINT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else cast(%s as char) end", field->name);
						break;
					case ZBX_TYPE_FLOAT:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else md5(cast(%s as char)) end", field->name);
						break;
					default:
						zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
								" else md5(%s) end", field->name);
						break;
				}
			}
#ifdef HAVE_MYSQL
			zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ',');
#else
			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "||','||");
#endif
		}

		/* remove last delimiter */
		if (f > 0)
		{
#ifdef HAVE_MYSQL
			sql_offset--;
			zbx_chrcpy_alloc(&sql, &sql_alloc, &sql_offset, ')');
#else
			sql_offset -= 7;
#endif
		}

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " from %s", tables[t].table);

		if (0 != recordid)
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where %s=" ZBX_FS_UI64,
					tables[t].recid, recordid);
		}
		else
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where 1=1" DB_NODE,
					DBnode(tables[t].recid, nodeid));
		}

		if (ZBX_DB_OK > DBexecute("%s", sql))
		{
			res = FAIL;
			break;
		}
	}
	zbx_free(sql);

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

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

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

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

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

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

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

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

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

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

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

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

	if (NULL == r)
		goto error;

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

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

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

	if (buffer_offset == 0)
		goto error;

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

	zbx_free(buffer);

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

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

	zbx_free(buffer);

	return FAIL;
}