Example #1
0
/******************************************************************************
 *                                                                            *
 * Function: process_deleted_records                                          *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_deleted_records(int nodeid, char *data, int sender_nodetype)
{
	const char	*__function_name = "process_deleted_records";
	char		*r, *lf;
	const ZBX_TABLE	*table = NULL;
	zbx_uint64_t	recid, *ids = NULL;
	int		ids_alloc = 0, ids_num = 0;
	char		*sql = NULL;
	size_t		sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;

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

	sql = zbx_malloc(sql, sql_alloc);

	DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);

	for (r = data; '\0' != *r;)
	{
		if (NULL != (lf = strchr(r, '\n')))
			*lf = '\0';

		zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);

		if (NULL == table || 0 != strcmp(table->table, buf))
		{
			make_delete_sql(&sql, &sql_alloc, &sql_offset, table, ids, &ids_num);

			if (NULL == (table = DBget_table(buf)))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot find table [%s]", __function_name, buf);
				goto next;
			}
		}

		zbx_get_next_field((const char **)&r, &buf, &buf_alloc, ZBX_DM_DELIMITER);
		ZBX_STR2UINT64(recid, buf);

		if ('2' == *r)	/* NODE_CONFIGLOG_OP_DELETE */
			uint64_array_add(&ids, &ids_alloc, &ids_num, recid, 64);
next:
		if (lf != NULL)
		{
			*lf++ = '\n';
			r = lf;
		}
		else
			break;
	}

	make_delete_sql(&sql, &sql_alloc, &sql_offset, table, ids, &ids_num);

	DBend_multiple_update(&sql, &sql_alloc, &sql_offset);

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

	zbx_free(sql);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #2
0
/******************************************************************************
 *                                                                            *
 * Function: get_values                                                       *
 *                                                                            *
 * Purpose: retrieve values of metrics from monitored hosts                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments: always SUCCEED                                                   *
 *                                                                            *
 ******************************************************************************/
static int	get_values(unsigned char poller_type)
{
	const char	*__function_name = "get_values";
	DC_ITEM		items[MAX_REACHABLE_ITEMS];
	AGENT_RESULT	agent;
	zbx_uint64_t	*ids = NULL, *snmpids = NULL, *ipmiids = NULL;
	int		ids_alloc = 0, snmpids_alloc = 0, ipmiids_alloc = 0,
			ids_num = 0, snmpids_num = 0, ipmiids_num = 0,
			i, now, num, res;
	static char	*key = NULL, *ipmi_ip = NULL, *params = NULL,
			*username = NULL, *publickey = NULL, *privatekey = NULL,
			*password = NULL, *snmp_community = NULL, *snmp_oid = NULL,
			*snmpv3_securityname = NULL, *snmpv3_authpassphrase = NULL,
			*snmpv3_privpassphrase = NULL;

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

	num = DCconfig_get_poller_items(poller_type, items, ZBX_POLLER_TYPE_UNREACHABLE != poller_type
								? MAX_REACHABLE_ITEMS : MAX_UNREACHABLE_ITEMS);

	for (i = 0; i < num; i++)
	{
		zbx_free(key);
		key = strdup(items[i].key_orig);
		substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
				&key, MACRO_TYPE_ITEM_KEY, NULL, 0);
		items[i].key = key;

		switch (items[i].type)
		{
			case ITEM_TYPE_SNMPv3:
				zbx_free(snmpv3_securityname);
				zbx_free(snmpv3_authpassphrase);
				zbx_free(snmpv3_privpassphrase);

				snmpv3_securityname = strdup(items[i].snmpv3_securityname_orig);
				snmpv3_authpassphrase = strdup(items[i].snmpv3_authpassphrase_orig);
				snmpv3_privpassphrase = strdup(items[i].snmpv3_privpassphrase_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_securityname, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_authpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmpv3_privpassphrase, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmpv3_securityname = snmpv3_securityname;
				items[i].snmpv3_authpassphrase = snmpv3_authpassphrase;
				items[i].snmpv3_privpassphrase = snmpv3_privpassphrase;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
				zbx_free(snmp_community);
				zbx_free(snmp_oid);

				snmp_community = strdup(items[i].snmp_community_orig);
				snmp_oid = strdup(items[i].snmp_oid_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_community, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&snmp_oid, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].snmp_community = snmp_community;
				items[i].snmp_oid = snmp_oid;
				break;
			case ITEM_TYPE_IPMI:
				zbx_free(ipmi_ip);
				ipmi_ip = strdup(items[i].host.ipmi_ip_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&ipmi_ip, MACRO_TYPE_HOST_IPMI_IP, NULL, 0);
				items[i].host.ipmi_ip = ipmi_ip;
				break;
			case ITEM_TYPE_DB_MONITOR:
				zbx_free(params);
				params = strdup(items[i].params_orig);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				items[i].params = params;
				break;
			case ITEM_TYPE_SSH:
				zbx_free(username);
				zbx_free(publickey);
				zbx_free(privatekey);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				publickey = strdup(items[i].publickey_orig);
				privatekey = strdup(items[i].privatekey_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&publickey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&privatekey, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].publickey = publickey;
				items[i].privatekey = privatekey;
				items[i].password = password;
				items[i].params = params;
				break;
			case ITEM_TYPE_TELNET:
				zbx_free(username);
				zbx_free(password);
				zbx_free(params);

				username = strdup(items[i].username_orig);
				password = strdup(items[i].password_orig);
				params = strdup(items[i].params_orig);

				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&username, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&password, MACRO_TYPE_ITEM_FIELD, NULL, 0);
				substitute_simple_macros(NULL, NULL, NULL, &items[i], NULL,
						&params, MACRO_TYPE_ITEM_FIELD, NULL, 0);

				items[i].username = username;
				items[i].password = password;
				items[i].params = params;
				break;
		}

		/* Skip unreachable hosts but do not break the loop. */
		switch (items[i].type)
		{
			case ITEM_TYPE_ZABBIX:
				if (SUCCEED == uint64_array_exists(ids, ids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "Zabbix Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_SNMPv1:
			case ITEM_TYPE_SNMPv2c:
			case ITEM_TYPE_SNMPv3:
				if (SUCCEED == uint64_array_exists(snmpids, snmpids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "SNMP Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			case ITEM_TYPE_IPMI:
				if (SUCCEED == uint64_array_exists(ipmiids, ipmiids_num, items[i].host.hostid))
				{
					DCrequeue_unreachable_item(items[i].itemid);
					zabbix_log(LOG_LEVEL_DEBUG, "IPMI Host " ZBX_FS_UI64 " is unreachable. Skipping [%s]",
							items[i].host.hostid, items[i].key_orig);
					continue;
				}
				break;
			default:
				/* nothing to do */;
		}

		init_result(&agent);

		res = get_value(&items[i], &agent);
		now = time(NULL);

		if (res == SUCCEED)
		{
			activate_host(&items[i], now);

			dc_add_history(items[i].itemid, items[i].value_type, &agent, now,
					ITEM_STATUS_ACTIVE, NULL, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_ACTIVE, now);
		}
		else if (res == NOTSUPPORTED || res == AGENT_ERROR)
		{
			activate_host(&items[i], now);

			dc_add_history(items[i].itemid, items[i].value_type, NULL, now,
					ITEM_STATUS_NOTSUPPORTED, agent.msg, 0, NULL, 0, 0, 0, 0);

			DCrequeue_reachable_item(items[i].itemid, ITEM_STATUS_NOTSUPPORTED, now);
		}
		else if (res == NETWORK_ERROR)
		{
			deactivate_host(&items[i], now, agent.msg);

			switch (items[i].type)
			{
				case ITEM_TYPE_ZABBIX:
					uint64_array_add(&ids, &ids_alloc, &ids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_SNMPv1:
				case ITEM_TYPE_SNMPv2c:
				case ITEM_TYPE_SNMPv3:
					uint64_array_add(&snmpids, &snmpids_alloc, &snmpids_num, items[i].host.hostid, 1);
					break;
				case ITEM_TYPE_IPMI:
					uint64_array_add(&ipmiids, &ipmiids_alloc, &ipmiids_num, items[i].host.hostid, 1);
					break;
				default:
					/* nothing to do */;
			}

			DCrequeue_unreachable_item(items[i].itemid);
		}
		else
		{
			zbx_error("unknown response code returned: %d", res);
			assert(0);
		}

		free_result(&agent);
	}

	zbx_free(key);
	zbx_free(ipmi_ip);
	zbx_free(params);
	zbx_free(username);
	zbx_free(publickey);
	zbx_free(privatekey);
	zbx_free(password);
	zbx_free(snmp_community);
	zbx_free(snmp_oid);
	zbx_free(snmpv3_securityname);
	zbx_free(snmpv3_authpassphrase);
	zbx_free(snmpv3_privpassphrase);

	zbx_free(ids);
	zbx_free(snmpids);
	zbx_free(ipmiids);

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

	return num;
}
Example #3
0
static void	update_maintenance_hosts(zbx_host_maintenance_t *hm, int hm_count, int now)
{
	typedef struct
	{
		zbx_uint64_t	hostid;
		int		maintenance_from;
		void		*next;
	}
	maintenance_t;

	const char	*__function_name = "update_maintenance_hosts";
	int		i;
	zbx_uint64_t	*ids = NULL, hostid;
	int		ids_alloc = 0, ids_num = 0;
	DB_RESULT	result;
	DB_ROW		row;
	char		*sql = NULL;
	size_t		sql_alloc = ZBX_KIBIBYTE, sql_offset;
	maintenance_t	*maintenances = NULL, *m;

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

	sql = zbx_malloc(sql, sql_alloc);

	DBbegin();

	for (i = 0; i < hm_count; i++)
	{
		if (SUCCEED == uint64_array_exists(ids, ids_num, hm[i].hostid))
			continue;

		if (hm[i].host_maintenanceid != hm[i].maintenanceid ||
				HOST_MAINTENANCE_STATUS_ON != hm[i].host_maintenance_status ||
				hm[i].host_maintenance_type != hm[i].maintenance_type ||
				0 == hm[i].host_maintenance_from)
		{
			zabbix_log(LOG_LEVEL_WARNING, "putting host [%s] into maintenance (with%s data collection)",
					hm[i].host, MAINTENANCE_TYPE_NORMAL == hm[i].maintenance_type ? "" : "out");

			sql_offset = 0;
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
					"update hosts"
					" set maintenanceid=" ZBX_FS_UI64 ","
						"maintenance_status=%d,"
						"maintenance_type=%d",
					hm[i].maintenanceid,
					HOST_MAINTENANCE_STATUS_ON,
					hm[i].maintenance_type);

			if (0 == hm[i].host_maintenance_from)
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",maintenance_from=%d",
						hm[i].maintenance_from);
			}

			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where hostid=" ZBX_FS_UI64,
					hm[i].hostid);

			DBexecute("%s", sql);

			DCconfig_set_maintenance(&hm[i].hostid, 1, HOST_MAINTENANCE_STATUS_ON,
					hm[i].maintenance_type, hm[i].maintenance_from);
		}

		uint64_array_add(&ids, &ids_alloc, &ids_num, hm[i].hostid, 4);
	}

	sql_offset = 0;
	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select hostid,host,maintenance_type,maintenance_from"
			" from hosts"
			" where status=%d"
				" and flags<>%d"
				" and maintenance_status=%d",
			HOST_STATUS_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_MAINTENANCE_STATUS_ON);

	if (NULL != ids && 0 != ids_num)
	{
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num);
	}

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

	ids_num = 0;

	while (NULL != (row = DBfetch(result)))
	{
		zabbix_log(LOG_LEVEL_WARNING, "taking host [%s] out of maintenance", row[1]);

		ZBX_STR2UINT64(hostid, row[0]);

		uint64_array_add(&ids, &ids_alloc, &ids_num, hostid, 4);

		if (MAINTENANCE_TYPE_NORMAL != atoi(row[2]))
			continue;

		m = zbx_malloc(NULL, sizeof(maintenance_t));
		m->hostid = hostid;
		m->maintenance_from = atoi(row[3]);
		m->next = maintenances;
		maintenances = m;
	}
	DBfree_result(result);

	sql_offset = 0;
	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"update hosts"
			" set maintenanceid=null,"
				"maintenance_status=%d,"
				"maintenance_type=0,"
				"maintenance_from=0"
			" where",
			HOST_MAINTENANCE_STATUS_OFF);

	if (NULL != ids && 0 != ids_num)
	{
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hostid", ids, ids_num);
		DBexecute("%s", sql);

		DCconfig_set_maintenance(ids, ids_num, HOST_MAINTENANCE_STATUS_OFF, 0, 0);
	}

	DBcommit();

	zbx_free(sql);
	zbx_free(ids);

	for (m = maintenances; NULL != m; m = m->next)
		generate_events(m->hostid, m->maintenance_from, now);

	for (m = maintenances; NULL != m; m = maintenances)
	{
		maintenances = m->next;
		zbx_free(m);
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #4
0
/******************************************************************************
 *                                                                            *
 * Function: DCflush_nextchecks                                               *
 *                                                                            *
 * Purpose: add item nextcheck to the array                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev, Dmitry Borovikov                              *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	DCflush_nextchecks()
{
	const char	*__function_name = "DCflush_nextchecks";

	int		i, sql_offset = 0, sql_allocated = 4096;
	char		*sql = NULL;

	DB_RESULT	result;
	DB_ROW		row;
	zbx_uint64_t	triggerid;
	zbx_uint64_t	itemid;
	zbx_uint64_t	events_maxid = 0;
	char		*error_msg_esc = NULL;

	char		*sql_select = NULL;
	int		sql_select_offset = 0, sql_select_allocated = 512;

	/* a crutch for the function `DBadd_condition_alloc' */
	zbx_uint64_t	*ids = NULL;
	int		ids_allocated = 0, ids_num = 0;

	zbx_uint64_t	*triggerids = NULL;
	int		triggerids_allocated = 0, triggerids_num = 0;

	struct event_objectid_clock 	*events = NULL;
	int		events_num = 0, events_allocated = 32;

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

	if (nextcheck_num == 0)
		return;

	sql = zbx_malloc(sql, sql_allocated);

	DBbegin();

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "begin\n");
#endif

	/* dealing with items */
	for (i = 0; i < nextcheck_num; i++)
	{
		if (NULL == nextchecks[i].error_msg)
			continue;

		uint64_array_add(&ids, &ids_allocated, &ids_num, nextchecks[i].itemid, 64);

		error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, ITEM_ERROR_LEN);
		zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc),
				"update items set status=%d,lastclock=%d,error='%s' where itemid=" ZBX_FS_UI64 ";\n",
				ITEM_STATUS_NOTSUPPORTED,
				(int)nextchecks[i].now,
				error_msg_esc,
				nextchecks[i].itemid);
		zbx_free(error_msg_esc);

		DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
	}

	/* dealing with notsupported items */
	if (ids_num > 0)
	{
		sql_select = zbx_malloc(sql_select, sql_select_allocated);
		events = zbx_malloc(events, events_allocated * sizeof(struct event_objectid_clock));

		/* preparing triggers */
		zbx_snprintf_alloc(&sql_select, &sql_select_allocated, &sql_select_offset, 256,
				"select t.triggerid,i.itemid"
				" from triggers t,functions f,items i"
				" where t.triggerid=f.triggerid"
					" and f.itemid=i.itemid"
					" and t.status in (%d)"
					" and t.value not in (%d)"
					" and",
				TRIGGER_STATUS_ENABLED,
				TRIGGER_VALUE_UNKNOWN);
		DBadd_condition_alloc(&sql_select, &sql_select_allocated, &sql_select_offset,
				"i.itemid", ids, ids_num);
		result = DBselect("%s", sql_select);

		zbx_free(sql_select);

		/* processing triggers */
		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(triggerid, row[0]);
			ZBX_STR2UINT64(itemid, row[1]);

			/* do not generate multiple unknown events for a trigger */
			if (SUCCEED == uint64_array_exists(triggerids, triggerids_num, triggerid))
				continue;

			uint64_array_add(&triggerids, &triggerids_allocated, &triggerids_num, triggerid, 64);

			/* index `i' will surely contain necessary itemid */
			i = get_nearestindex(nextchecks, sizeof(ZBX_DC_NEXTCHECK), nextcheck_num, itemid);

			if (i == nextcheck_num || nextchecks[i].itemid != itemid)
			{
				THIS_SHOULD_NEVER_HAPPEN;
				continue;
			}

			error_msg_esc = DBdyn_escape_string_len(nextchecks[i].error_msg, TRIGGER_ERROR_LEN);
			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 128 + strlen(error_msg_esc),
					"update triggers set value=%d,lastchange=%d,error='%s' where triggerid=" ZBX_FS_UI64";\n",
							TRIGGER_VALUE_UNKNOWN,
							nextchecks[i].now,
							error_msg_esc,
							triggerid);
			zbx_free(error_msg_esc);

			if (events_num == events_allocated)
			{
				events_allocated += 32;
				events = zbx_realloc(events, events_allocated * sizeof(struct event_objectid_clock));
			}
			events[events_num].objectid = triggerid;
			events[events_num].clock = nextchecks[i].now;
			events_num++;

			DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
		}
		DBfree_result(result);

		/* dealing with events */
		for (i = 0; i < events_num; i++)
		{
			events_maxid = DBget_maxid("events");

			zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 256,
					"insert into events (eventid,source,object,objectid,clock,value) "
					"values (" ZBX_FS_UI64 ",%d,%d," ZBX_FS_UI64 ",%d,%d);\n",
					events_maxid,
					EVENT_SOURCE_TRIGGERS,
					EVENT_OBJECT_TRIGGER,
					events[i].objectid,
					events[i].clock,
					TRIGGER_VALUE_UNKNOWN);

			DBexecute_overflowed_sql(&sql, &sql_allocated, &sql_offset);
		}

		zbx_free(events);
	}

#ifdef HAVE_ORACLE
	zbx_snprintf_alloc(&sql, &sql_allocated, &sql_offset, 8, "end;\n");
#endif

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

	zbx_free(sql);
	zbx_free(ids);
	zbx_free(triggerids);

	DCrelease_nextchecks();

	DBcommit();

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #5
0
/******************************************************************************
 *                                                                            *
 * Function: aggregate_get_items                                              *
 *                                                                            *
 * Purpose: get array of items specified by key for selected groups           *
 *                                                                            *
 * Parameters: ids - result, list of items                                    *
 *             groups - list of comma-separated host groups                   *
 *             itemkey - item key to aggregate                                *
 *                                                                            *
 ******************************************************************************/
static void	aggregate_get_items(zbx_uint64_t **ids, int *ids_alloc, int *ids_num, const char *groups,
		const char *itemkey)
{
	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;

	sql = zbx_malloc(sql, sql_alloc);

	esc = DBdyn_escape_string(itemkey);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
			"select i.itemid"
			" from items i,hosts_groups hg,hosts h,groups g"
			" where hg.groupid=g.groupid"
				" and i.hostid=h.hostid"
				" and hg.hostid=h.hostid"
				" 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]);
		uint64_array_add(ids, ids_alloc, ids_num, itemid, 64);
	}
	DBfree_result(result);
}
Example #6
0
/******************************************************************************
 *                                                                            *
 * Function: housekeeping_process_log                                         *
 *                                                                            *
 * Purpose: process table 'housekeeper' and remove data if required           *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value: SUCCEED - information removed successfully                   *
 *               FAIL - otherwise                                             *
 *                                                                            *
 * Author: Alexei Vladishev, Dmitry Borovikov                                 *
 *                                                                            *
 * Comments: sqlite3 does not use CONFIG_MAX_HOUSEKEEPER_DELETE, deletes all  *
 *                                                                            *
 ******************************************************************************/
static int	housekeeping_process_log()
{
	const char	*__function_name = "housekeeping_process_log";
	DB_HOUSEKEEPER	housekeeper;
	DB_RESULT	result;
	DB_ROW		row;
	long		deleted;
	char		*sql = NULL;
	int		sql_alloc = 512, sql_offset = 0;
	zbx_uint64_t	*ids = NULL;
	int		ids_alloc = 0, ids_num = 0;

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

	/* 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)
		{
			deleted = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64,
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value);
		}
		else
		{
#ifdef HAVE_ORACLE
			deleted = 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_POSTGRESQL)
			deleted = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64
						" and oid in (select oid from %s"
							" where %s=" ZBX_FS_UI64 " limit %d)",
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					CONFIG_MAX_HOUSEKEEPER_DELETE);
#elif defined(HAVE_MYSQL)
			deleted = DBexecute(
					"delete from %s"
					" where %s=" ZBX_FS_UI64 " limit %d",
					housekeeper.tablename,
					housekeeper.field,
					housekeeper.value,
					CONFIG_MAX_HOUSEKEEPER_DELETE);
#else	/* HAVE_SQLITE3 */
			deleted = 0;
#endif
		}

		if (0 == deleted || 0 == CONFIG_MAX_HOUSEKEEPER_DELETE ||
				CONFIG_MAX_HOUSEKEEPER_DELETE > deleted)
			uint64_array_add(&ids, &ids_alloc, &ids_num, housekeeper.housekeeperid, 64);

		if (deleted > 0)
		{
			zabbix_log( LOG_LEVEL_DEBUG, "Deleted [%ld] records from table [%s]",
					deleted, housekeeper.tablename);
		}
	}
	DBfree_result(result);

	if (NULL != ids)
	{
		sql = zbx_malloc(sql, sql_alloc * sizeof(char));

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 32,
				"delete from housekeeper where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset,
				"housekeeperid", ids, ids_num);

		DBexecute("%s", sql);

		zbx_free(sql);
		zbx_free(ids);
	}

	return SUCCEED;
}