Example #1
0
int	DBpatch_3020001(void)
{
	DB_RESULT		result;
	zbx_vector_uint64_t	eventids;
	DB_ROW			row;
	zbx_uint64_t		eventid;
	int			sources[] = {EVENT_SOURCE_TRIGGERS, EVENT_SOURCE_INTERNAL};
	int			objects[] = {EVENT_OBJECT_ITEM, EVENT_OBJECT_LLDRULE}, i;

	zbx_vector_uint64_create(&eventids);

	for (i = 0; i < (int)ARRSIZE(sources); i++)
	{
		result = DBselect(
				"select p.eventid"
				" from problem p"
				" where p.source=%d and p.object=%d and not exists ("
					"select null"
					" from triggers t"
					" where t.triggerid=p.objectid"
				")",
				sources[i], EVENT_OBJECT_TRIGGER);

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(eventid, row[0]);
			zbx_vector_uint64_append(&eventids, eventid);
		}
		DBfree_result(result);
	}

	for (i = 0; i < (int)ARRSIZE(objects); i++)
	{
		result = DBselect(
				"select p.eventid"
				" from problem p"
				" where p.source=%d and p.object=%d and not exists ("
					"select null"
					" from items i"
					" where i.itemid=p.objectid"
				")",
				EVENT_SOURCE_INTERNAL, objects[i]);

		while (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(eventid, row[0]);
			zbx_vector_uint64_append(&eventids, eventid);
		}
		DBfree_result(result);
	}

	zbx_vector_uint64_sort(&eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	if (0 != eventids.values_num)
		DBexecute_multiple_query("delete from problem where", "eventid", &eventids);

	zbx_vector_uint64_destroy(&eventids);

	return SUCCEED;
}
Example #2
0
/******************************************************************************
 *                                                                            *
 * Function: procstat_get_monitored_pids                                      *
 *                                                                            *
 * Purpose: creates a list of unique pids that are monitored by current data  *
 *          gathering cycle                                                   *
 *                                                                            *
 * Parameters: pids     - [OUT] a sorted vector of unique pids                *
 *             queries  - [IN] local, working copy of queries                 *
 *             pids_num - [IN] the total number of pids monitored by queries  *
 *                             (might contain duplicated pids)                *
 *                                                                            *
 ******************************************************************************/
static void	procstat_get_monitored_pids(zbx_vector_uint64_t *pids, const zbx_vector_ptr_t *queries, int pids_num)
{
	zbx_procstat_query_data_t	*qdata;
	int i;

	zbx_vector_uint64_reserve(pids, pids_num);

	for (i = 0; i < queries->values_num; i++)
	{
		qdata = (zbx_procstat_query_data_t *)queries->values[i];

		if (SUCCEED != qdata->error)
			continue;

		memcpy(pids->values + pids->values_num, qdata->pids.values,
				sizeof(zbx_uint64_t) * qdata->pids.values_num);
		pids->values_num += qdata->pids.values_num;
	}

	zbx_vector_uint64_sort(pids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
	zbx_vector_uint64_uniq(pids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
}
Example #3
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;
}
Example #4
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	process_escalations(int now)
{
	const char		*__function_name = "process_escalations";
	DB_RESULT		result;
	DB_ROW			row;
	DB_ESCALATION		escalation, last_escalation;
	zbx_vector_uint64_t	escalationids;
	char			*sql = NULL;
	size_t			sql_alloc = ZBX_KIBIBYTE, sql_offset;

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

	zbx_vector_uint64_create(&escalationids);
	sql = zbx_malloc(sql, sql_alloc);

	result = DBselect(
			"select escalationid,actionid,triggerid,eventid,r_eventid,esc_step,status,nextcheck"
			" from escalations"
			" where 1=1"
				DB_NODE
			" order by actionid,triggerid,escalationid",
			DBnode_local("escalationid"));

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

	do
	{
		memset(&last_escalation, 0, sizeof(last_escalation));

		if (NULL != (row = DBfetch(result)))
		{
			ZBX_STR2UINT64(last_escalation.escalationid, row[0]);
			ZBX_STR2UINT64(last_escalation.actionid, row[1]);
			ZBX_DBROW2UINT64(last_escalation.triggerid, row[2]);
			ZBX_DBROW2UINT64(last_escalation.eventid, row[3]);
			ZBX_DBROW2UINT64(last_escalation.r_eventid, row[4]);
			last_escalation.esc_step = atoi(row[5]);
			last_escalation.status = atoi(row[6]);
			last_escalation.nextcheck = atoi(row[7]);

			/* just delete on the next cycle */
			if (0 != last_escalation.r_eventid)
				last_escalation.status = ESCALATION_STATUS_COMPLETED;
		}

		if (0 != escalation.escalationid)
		{
			unsigned char	esc_superseded = 0;

			if (ESCALATION_STATUS_COMPLETED == escalation.status)
			{
				/* delete a recovery record and skip all processing */
				zbx_vector_uint64_append(&escalationids, escalation.escalationid);
				goto next;
			}

			if (0 != last_escalation.escalationid)
			{
				esc_superseded = (escalation.actionid == last_escalation.actionid &&
						escalation.triggerid == last_escalation.triggerid);

				if (1 == esc_superseded)
				{
					if (0 != last_escalation.r_eventid)
					{
						/* recover this escalation */
						escalation.r_eventid = last_escalation.r_eventid;
						escalation.status = ESCALATION_STATUS_ACTIVE;
					}
					else if (escalation.nextcheck > now ||
							ESCALATION_STATUS_SLEEP == escalation.status)
					{
						zbx_vector_uint64_append(&escalationids, escalation.escalationid);
						goto next;
					}
				}
			}

			if (ESCALATION_STATUS_ACTIVE != escalation.status ||
					(escalation.nextcheck > now && 0 == escalation.r_eventid))
			{
				goto next;
			}

			DBbegin();

			if (escalation.nextcheck <= now)
				execute_escalation(&escalation);

			/* execute recovery */
			if (ESCALATION_STATUS_COMPLETED != escalation.status && 0 != escalation.r_eventid)
			{
				escalation.status = ESCALATION_STATUS_RECOVERY;
				execute_escalation(&escalation);
			}
			else if (1 == esc_superseded)
				escalation.status = ESCALATION_STATUS_COMPLETED;

			sql_offset = 0;

			if (ESCALATION_STATUS_COMPLETED != escalation.status)
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
						"update escalations set status=%d", escalation.status);
				if (ESCALATION_STATUS_ACTIVE == escalation.status)
				{
					zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, ",esc_step=%d,nextcheck=%d",
							escalation.esc_step, escalation.nextcheck);
				}
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
						" where escalationid=" ZBX_FS_UI64, escalation.escalationid);

			}
			else
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
						"delete from escalations where escalationid=" ZBX_FS_UI64,
						escalation.escalationid);
			}

			DBexecute("%s", sql);

			DBcommit();
		}
next:
		if (NULL != row)
			memcpy(&escalation, &last_escalation, sizeof(escalation));
	}
	while (NULL != row);

	DBfree_result(result);

	zbx_free(sql);

	/* delete completed escalations */
	if (0 != escalationids.values_num)
	{
		zbx_vector_uint64_sort(&escalationids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		DBbegin();
		DBexecute_multiple_query("delete from escalations where", "escalationid", &escalationids);
		DBcommit();
	}

	zbx_vector_uint64_destroy(&escalationids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #6
0
static void	lld_graphs_save(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *graphs, int width, int height,
		double yaxismin, double yaxismax, unsigned char show_work_period, unsigned char show_triggers,
		unsigned char graphtype, unsigned char show_legend, unsigned char show_3d, double percent_left,
		double percent_right, unsigned char ymin_type, unsigned char ymax_type)
{
	const char		*__function_name = "lld_graphs_save";

	int			i, j, new_graphs = 0, upd_graphs = 0, new_gitems = 0;
	zbx_lld_graph_t		*graph;
	zbx_lld_gitem_t		*gitem;
	zbx_vector_ptr_t	upd_gitems; 	/* the ordered list of graphs_items which will be updated */
	zbx_vector_uint64_t	del_gitemids;

	zbx_uint64_t		graphid = 0, graphdiscoveryid = 0, gitemid = 0;
	char			*sql = NULL, *name_esc, *color_esc;
	size_t			sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0;
	zbx_db_insert_t		db_insert, db_insert_gdiscovery, db_insert_gitems;

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

	zbx_vector_ptr_create(&upd_gitems);
	zbx_vector_uint64_create(&del_gitemids);

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED))
			continue;

		if (0 == graph->graphid)
			new_graphs++;
		else if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE))
			upd_graphs++;

		for (j = 0; j < graph->gitems.values_num; j++)
		{
			gitem = (zbx_lld_gitem_t *)graph->gitems.values[j];

			if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_DELETE))
			{
				zbx_vector_uint64_append(&del_gitemids, gitem->gitemid);
				continue;
			}

			if (0 == (gitem->flags & ZBX_FLAG_LLD_GITEM_DISCOVERED))
				continue;

			if (0 == gitem->gitemid)
				new_gitems++;
			else if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE))
				zbx_vector_ptr_append(&upd_gitems, gitem);
		}
	}

	if (0 == new_graphs && 0 == new_gitems && 0 == upd_graphs && 0 == upd_gitems.values_num &&
			0 == del_gitemids.values_num)
	{
		goto out;
	}

	DBbegin();

	if (0 != new_graphs)
	{
		graphid = DBget_maxid_num("graphs", new_graphs);
		graphdiscoveryid = DBget_maxid_num("graph_discovery", new_graphs);

		zbx_db_insert_prepare(&db_insert, "graphs", "graphid", "name", "width", "height", "yaxismin",
				"yaxismax", "show_work_period", "show_triggers", "graphtype", "show_legend", "show_3d",
				"percent_left", "percent_right", "ymin_type", "ymin_itemid", "ymax_type",
				"ymax_itemid", "flags", NULL);

		zbx_db_insert_prepare(&db_insert_gdiscovery, "graph_discovery", "graphdiscoveryid", "graphid",
				"parent_graphid", NULL);
	}

	if (0 != new_gitems)
	{
		gitemid = DBget_maxid_num("graphs_items", new_gitems);

		zbx_db_insert_prepare(&db_insert_gitems, "graphs_items", "gitemid", "graphid", "itemid", "drawtype",
				"sortorder", "color", "yaxisside", "calc_fnc", "type", NULL);
	}

	if (0 != upd_graphs || 0 != upd_gitems.values_num || 0 != del_gitemids.values_num)
	{
		sql = zbx_malloc(sql, sql_alloc);
		DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
	}

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED))
			continue;

		if (0 == graph->graphid)
		{
			zbx_db_insert_add_values(&db_insert, graphid, graph->name, width, height, yaxismin, yaxismax,
					(int)show_work_period, (int)show_triggers, (int)graphtype, (int)show_legend,
					(int)show_3d, percent_left, percent_right, (int)ymin_type, graph->ymin_itemid,
					(int)ymax_type, graph->ymax_itemid, (int)ZBX_FLAG_DISCOVERY_CREATED);

			zbx_db_insert_add_values(&db_insert_gdiscovery, graphdiscoveryid, graphid, parent_graphid);

			graph->graphid = graphid++;
			graphdiscoveryid++;
		}
		else if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE))
		{
			const char	*d = "";

			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update graphs set ");

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME))
			{
				name_esc = DBdyn_escape_string(graph->name);
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "name='%s'", name_esc);
				zbx_free(name_esc);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_WIDTH))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%swidth=%d", d, width);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_HEIGHT))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sheight=%d", d, height);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMIN))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxismin=" ZBX_FS_DBL, d,
						yaxismin);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YAXISMAX))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxismax=" ZBX_FS_DBL, d,
						yaxismax);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_WORK_PERIOD))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_work_period=%d", d,
						(int)show_work_period);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_TRIGGERS))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_triggers=%d", d,
						(int)show_triggers);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_GRAPHTYPE))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sgraphtype=%d", d,
						(int)graphtype);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_LEGEND))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_legend=%d", d,
						(int)show_legend);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_SHOW_3D))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sshow_3d=%d", d, (int)show_3d);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_LEFT))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spercent_left=" ZBX_FS_DBL, d,
						percent_left);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_PERCENT_RIGHT))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spercent_right=" ZBX_FS_DBL, d,
						percent_right);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_TYPE))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symin_type=%d", d,
						(int)ymin_type);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMIN_ITEMID))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symin_itemid=%s", d,
						DBsql_id_ins(graph->ymin_itemid));
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_TYPE))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symax_type=%d", d,
						(int)ymax_type);
				d = ",";
			}

			if (0 != (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_YMAX_ITEMID))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%symax_itemid=%s", d,
						DBsql_id_ins(graph->ymax_itemid));
			}

			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where graphid=" ZBX_FS_UI64 ";\n",
					graph->graphid);
		}

		for (j = 0; j < graph->gitems.values_num; j++)
		{
			gitem = (zbx_lld_gitem_t *)graph->gitems.values[j];

			if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_DELETE))
				continue;

			if (0 == (gitem->flags & ZBX_FLAG_LLD_GITEM_DISCOVERED))
				continue;

			if (0 == gitem->gitemid)
			{
				zbx_db_insert_add_values(&db_insert_gitems, gitemid, graph->graphid, gitem->itemid,
						(int)gitem->drawtype, gitem->sortorder, gitem->color,
						(int)gitem->yaxisside, (int)gitem->calc_fnc, (int)gitem->type);

				gitem->gitemid = gitemid++;
			}
		}
	}

	for (i = 0; i < upd_gitems.values_num; i++)
	{
		const char	*d = "";

		gitem = (zbx_lld_gitem_t *)upd_gitems.values[i];

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update graphs_items set ");

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_ITEMID))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64, gitem->itemid);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_DRAWTYPE))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdrawtype=%d", d, (int)gitem->drawtype);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_SORTORDER))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%ssortorder=%d", d, gitem->sortorder);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_COLOR))
		{
			color_esc = DBdyn_escape_string(gitem->color);
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scolor='%s'", d, color_esc);
			zbx_free(color_esc);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_YAXISSIDE))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%syaxisside=%d", d,
					(int)gitem->yaxisside);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_CALC_FNC))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scalc_fnc=%d", d, (int)gitem->calc_fnc);
			d = ",";
		}

		if (0 != (gitem->flags & ZBX_FLAG_LLD_GITEM_UPDATE_TYPE))
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)gitem->type);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where gitemid=" ZBX_FS_UI64 ";\n",
				gitem->gitemid);
	}

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

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from graphs_items where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "gitemid",
				del_gitemids.values, del_gitemids.values_num);
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
	}

	if (0 != upd_graphs || 0 != upd_gitems.values_num || 0 != del_gitemids.values_num)
	{
		DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
		DBexecute("%s", sql);
		zbx_free(sql);
	}

	if (0 != new_graphs)
	{
		zbx_db_insert_execute(&db_insert);
		zbx_db_insert_clean(&db_insert);

		zbx_db_insert_execute(&db_insert_gdiscovery);
		zbx_db_insert_clean(&db_insert_gdiscovery);
	}

	if (0 != new_gitems)
	{
		zbx_db_insert_execute(&db_insert_gitems);
		zbx_db_insert_clean(&db_insert_gitems);
	}

	DBcommit();
out:
	zbx_vector_uint64_destroy(&del_gitemids);
	zbx_vector_ptr_destroy(&upd_gitems);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #7
0
/******************************************************************************
 *                                                                            *
 * Function: lld_graphs_validate                                              *
 *                                                                            *
 * Parameters: graphs - [IN] sorted list of graphs                            *
 *                                                                            *
 ******************************************************************************/
static void	lld_graphs_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *graphs, char **error)
{
	const char		*__function_name = "lld_graphs_validate";

	int			i, j;
	zbx_lld_graph_t		*graph, *graph_b;
	zbx_vector_uint64_t	graphids;
	zbx_vector_str_t	names;

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

	zbx_vector_uint64_create(&graphids);
	zbx_vector_str_create(&names);		/* list of graph names */

	/* checking a validity of the fields */

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		lld_validate_graph_field(graph, &graph->name, &graph->name_orig,
				ZBX_FLAG_LLD_GRAPH_UPDATE_NAME, GRAPH_NAME_LEN, error);
	}

	/* checking duplicated graph names */
	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED))
			continue;

		/* only new graphs or graphs with changed name will be validated */
		if (0 != graph->graphid && 0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME))
			continue;

		for (j = 0; j < graphs->values_num; j++)
		{
			graph_b = (zbx_lld_graph_t *)graphs->values[j];

			if (0 == (graph_b->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED) || i == j)
				continue;

			if (0 != strcmp(graph->name, graph_b->name))
				continue;

			*error = zbx_strdcatf(*error, "Cannot %s graph:"
						" graph with the same name \"%s\" already exists.\n",
						(0 != graph->graphid ? "update" : "create"), graph->name);

			if (0 != graph->graphid)
			{
				lld_field_str_rollback(&graph->name, &graph->name_orig, &graph->flags,
						ZBX_FLAG_LLD_GRAPH_UPDATE_NAME);
			}
			else
				graph->flags &= ~ZBX_FLAG_LLD_GRAPH_DISCOVERED;

			break;
		}
	}

	/* checking duplicated graphs in DB */

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED))
			continue;

		if (0 != graph->graphid)
		{
			zbx_vector_uint64_append(&graphids, graph->graphid);

			if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_UPDATE_NAME))
				continue;
		}

		zbx_vector_str_append(&names, graph->name);
	}

	if (0 != names.values_num)
	{
		DB_RESULT	result;
		DB_ROW		row;
		char		*sql = NULL;
		size_t		sql_alloc = 256, sql_offset = 0;

		sql = zbx_malloc(sql, sql_alloc);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"select g.name"
				" from graphs g,graphs_items gi,items i"
				" where g.graphid=gi.graphid"
					" and gi.itemid=i.itemid"
					" and i.hostid=" ZBX_FS_UI64
					" and",
				hostid);
		DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "g.name",
				(const char **)names.values, names.values_num);

		if (0 != graphids.values_num)
		{
			zbx_vector_uint64_sort(&graphids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not");
			DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "g.graphid",
					graphids.values, graphids.values_num);
		}

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

		while (NULL != (row = DBfetch(result)))
		{
			for (i = 0; i < graphs->values_num; i++)
			{
				graph = (zbx_lld_graph_t *)graphs->values[i];

				if (0 == (graph->flags & ZBX_FLAG_LLD_GRAPH_DISCOVERED))
					continue;

				if (0 == strcmp(graph->name, row[0]))
				{
					*error = zbx_strdcatf(*error, "Cannot %s graph:"
							" graph with the same name \"%s\" already exists.\n",
							(0 != graph->graphid ? "update" : "create"), graph->name);

					if (0 != graph->graphid)
					{
						lld_field_str_rollback(&graph->name, &graph->name_orig, &graph->flags,
								ZBX_FLAG_LLD_GRAPH_UPDATE_NAME);
					}
					else
						graph->flags &= ~ZBX_FLAG_LLD_GRAPH_DISCOVERED;

					continue;
				}
			}
		}
		DBfree_result(result);

		zbx_free(sql);
	}

	zbx_vector_str_destroy(&names);
	zbx_vector_uint64_destroy(&graphids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #8
0
/******************************************************************************
 *                                                                            *
 * Function: db_get_query_functions                                           *
 *                                                                            *
 * Purpose: get event query functionids from database                         *
 *                                                                            *
 ******************************************************************************/
static void	db_get_query_functions(zbx_vector_ptr_t *event_queries)
{
	DB_ROW				row;
	DB_RESULT			result;
	int				i;
	zbx_vector_uint64_t		triggerids;
	zbx_hashset_t			triggers;
	zbx_hashset_iter_t		iter;
	char				*sql = NULL;
	size_t				sql_alloc = 0, sql_offset = 0;
	zbx_trigger_functions_t		*trigger = NULL, trigger_local;
	zbx_uint64_t			triggerid, functionid;
	zbx_event_suppress_query_t	*query;

	/* cache functionids by triggerids */

	zbx_hashset_create(&triggers, 100, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	zbx_vector_uint64_create(&triggerids);

	for (i = 0; i < event_queries->values_num; i++)
	{
		query = (zbx_event_suppress_query_t *)event_queries->values[i];
		zbx_vector_uint64_append(&triggerids, query->triggerid);
	}

	zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
	zbx_vector_uint64_uniq(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "select functionid,triggerid from functions where");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", triggerids.values,
			triggerids.values_num);
	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by triggerid");

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

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

		if (NULL == trigger || trigger->triggerid != triggerid)
		{
			trigger_local.triggerid = triggerid;
			trigger = (zbx_trigger_functions_t *)zbx_hashset_insert(&triggers, &trigger_local,
					sizeof(trigger_local));
			zbx_vector_uint64_create(&trigger->functionids);
		}
		zbx_vector_uint64_append(&trigger->functionids, functionid);
	}
	DBfree_result(result);

	/*  copy functionids to event queries */

	for (i = 0; i < event_queries->values_num; i++)
	{
		query = (zbx_event_suppress_query_t *)event_queries->values[i];

		if (NULL == (trigger = (zbx_trigger_functions_t *)zbx_hashset_search(&triggers, &query->triggerid)))
			continue;

		zbx_vector_uint64_append_array(&query->functionids, trigger->functionids.values,
				trigger->functionids.values_num);
	}

	zbx_hashset_iter_reset(&triggers, &iter);
	while (NULL != (trigger = (zbx_trigger_functions_t *)zbx_hashset_iter_next(&iter)))
		zbx_vector_uint64_destroy(&trigger->functionids);
	zbx_hashset_destroy(&triggers);

	zbx_vector_uint64_destroy(&triggerids);
}
/******************************************************************************
 *                                                                            *
 * 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);
}
/******************************************************************************
 *                                                                            *
 * Function: process_record                                                   *
 *                                                                            *
 * Purpose: process record update                                             *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:  SUCCEED - processed successfully                            *
 *                FAIL - an error occurred                                    *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static int	process_record(char **sql, size_t *sql_alloc, size_t *sql_offset, int sender_nodeid, int nodeid,
		const ZBX_TABLE *table, const char *record, int lastrecord, int acknowledges,
		zbx_vector_uint64_t *ack_eventids)
{
	const char	*r;
	int		f, res = FAIL;
	char		*value_esc;

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

	if (0 == *sql_offset)
	{
		DBbegin_multiple_update(sql, sql_alloc, sql_offset);
#ifdef HAVE_MULTIROW_INSERT
		begin_history_sql(sql, sql_alloc, sql_offset, table);
#endif
	}

#if !defined(HAVE_MULTIROW_INSERT)
	begin_history_sql(sql, sql_alloc, sql_offset, table);
#endif

	zbx_chrcpy_alloc(sql, sql_alloc, sql_offset, '(');
	if (0 != (table->flags & ZBX_HISTORY_SYNC))
		zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%d,", nodeid);

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

		if (NULL == r)
			goto error;

		zbx_get_next_field(&r, &buffer, &buffer_alloc, ZBX_DM_DELIMITER);

		if (0 != acknowledges && 0 == strcmp(table->fields[f].name, "eventid"))
		{
			zbx_uint64_t	eventid;

			ZBX_STR2UINT64(eventid, buffer);
			zbx_vector_uint64_append(ack_eventids, eventid);
		}

		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(sql, sql_alloc, sql_offset, "%s,", buffer);
		}
		else if (table->fields[f].type == ZBX_TYPE_BLOB)
		{
			if ('\0' == *buffer)
				zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "'',");
			else
			{
#ifdef HAVE_POSTGRESQL
				size_t	len;

				len = zbx_hex2binary(buffer);
				zbx_pg_escape_bytea((u_char *)buffer, len, &tmp, &tmp_alloc);
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "'%s',", tmp);
#else
				zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "0x%s,", buffer);
#endif
			}
		}
		else	/* ZBX_TYPE_TEXT, ZBX_TYPE_CHAR */
		{
			zbx_hex2binary(buffer);
			value_esc = DBdyn_escape_string(buffer);

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

			zbx_free(value_esc);
		}
	}

	(*sql_offset)--;

#ifdef HAVE_MULTIROW_INSERT
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "),");
#else
	zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ");\n");
#endif

	if (0 != lastrecord || *sql_offset > ZBX_MAX_SQL_SIZE)
	{
#ifdef HAVE_MULTIROW_INSERT
		(*sql_offset)--;
		zbx_strcpy_alloc(sql, sql_alloc, sql_offset, ";\n");
#endif
		DBend_multiple_update(sql, sql_alloc, sql_offset);

		if (ZBX_DB_OK <= DBexecute("%s", *sql))
			res = SUCCEED;
		*sql_offset = 0;

		if (SUCCEED == res && 0 != lastrecord && 0 != acknowledges && 0 != ack_eventids->values_num)
		{
			zbx_vector_uint64_sort(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
			zbx_vector_uint64_uniq(ack_eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

			zbx_strcpy_alloc(sql, sql_alloc, sql_offset,
					"update events"
					" set acknowledged=1"
					" where");
			DBadd_condition_alloc(sql, sql_alloc, sql_offset,
					"eventid", ack_eventids->values, ack_eventids->values_num);

			if (ZBX_DB_OK > DBexecute("%s", *sql))
				res = FAIL;
			*sql_offset = 0;
		}
	}
	else
		res = SUCCEED;

	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, record);

	return FAIL;
}
Example #11
0
/******************************************************************************
 *                                                                            *
 * Function: lld_triggers_validate                                            *
 *                                                                            *
 * Parameters: triggers - [IN] sorted list of triggers                        *
 *                                                                            *
 ******************************************************************************/
static void	lld_triggers_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *triggers, char **error)
{
	const char		*__function_name = "lld_triggers_validate";

	int			i, j, k;
	zbx_lld_trigger_t	*trigger;
	zbx_lld_function_t	*function;
	zbx_vector_uint64_t	triggerids;
	zbx_vector_str_t	descriptions;

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

	zbx_vector_uint64_create(&triggerids);
	zbx_vector_str_create(&descriptions);

	/* checking a validity of the fields */

	for (i = 0; i < triggers->values_num; i++)
	{
		trigger = (zbx_lld_trigger_t *)triggers->values[i];

		lld_validate_trigger_field(trigger, &trigger->description, &trigger->description_orig,
				ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION, TRIGGER_DESCRIPTION_LEN, error);
		lld_validate_trigger_field(trigger, &trigger->comments, &trigger->comments_orig,
				ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS, TRIGGER_COMMENTS_LEN, error);
	}

	/* checking duplicated triggers in DB */

	for (i = 0; i < triggers->values_num; i++)
	{
		trigger = (zbx_lld_trigger_t *)triggers->values[i];

		if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED))
			continue;

		if (0 != trigger->triggerid)
		{
			zbx_vector_uint64_append(&triggerids, trigger->triggerid);

			if (SUCCEED != lld_trigger_changed(trigger))
				continue;
		}

		zbx_vector_str_append(&descriptions, trigger->description);
	}

	if (0 != descriptions.values_num)
	{
		char			*sql = NULL;
		size_t			sql_alloc = 256, sql_offset = 0;
		DB_RESULT		result;
		DB_ROW			row;
		zbx_vector_ptr_t	db_triggers;
		zbx_lld_trigger_t	*db_trigger;

		zbx_vector_ptr_create(&db_triggers);

		zbx_vector_str_sort(&descriptions, ZBX_DEFAULT_STR_COMPARE_FUNC);
		zbx_vector_str_uniq(&descriptions, ZBX_DEFAULT_STR_COMPARE_FUNC);

		sql = zbx_malloc(sql, sql_alloc);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				"select distinct t.triggerid,t.description,t.expression"
				" from triggers t,functions f,items i"
				" where t.triggerid=f.triggerid"
					" and f.itemid=i.itemid"
					" and i.hostid=" ZBX_FS_UI64
					" and",
				hostid);
		DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.description",
				(const char **)descriptions.values, descriptions.values_num);

		if (0 != triggerids.values_num)
		{
			zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not");
			DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.triggerid",
					triggerids.values, triggerids.values_num);
		}

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

		while (NULL != (row = DBfetch(result)))
		{
			db_trigger = zbx_malloc(NULL, sizeof(zbx_lld_trigger_t));

			ZBX_STR2UINT64(db_trigger->triggerid, row[0]);
			db_trigger->description = zbx_strdup(NULL, row[1]);
			db_trigger->description_orig = NULL;
			db_trigger->expression = zbx_strdup(NULL, row[2]);
			db_trigger->expression_orig = NULL;
			db_trigger->comments = NULL;
			db_trigger->comments_orig = NULL;
			db_trigger->flags = ZBX_FLAG_LLD_TRIGGER_UNSET;

			zbx_vector_ptr_create(&db_trigger->functions);

			zbx_vector_ptr_append(&db_triggers, db_trigger);
		}
		DBfree_result(result);

		zbx_vector_ptr_sort(&db_triggers, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

		lld_functions_get(0, NULL, &db_triggers);

		for (i = 0; i < db_triggers.values_num; i++)
		{
			db_trigger = (zbx_lld_trigger_t *)db_triggers.values[i];

			lld_expression_simplify(&db_trigger->expression, &db_trigger->functions);

			for (j = 0; j < triggers->values_num; j++)
			{
				trigger = (zbx_lld_trigger_t *)triggers->values[j];

				if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED))
					continue;

				if (SUCCEED != lld_triggers_equal(trigger, db_trigger))
					continue;

				*error = zbx_strdcatf(*error, "Cannot %s trigger: trigger \"%s\" already exists.\n",
						(0 != trigger->triggerid ? "update" : "create"), trigger->description);

				if (0 != trigger->triggerid)
				{
					lld_field_str_rollback(&trigger->description, &trigger->description_orig,
							&trigger->flags, ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION);

					lld_field_str_rollback(&trigger->expression, &trigger->expression_orig,
							&trigger->flags, ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION);

					for (k = 0; k < trigger->functions.values_num; k++)
					{
						function = (zbx_lld_function_t *)trigger->functions.values[k];

						if (0 != function->functionid)
						{
							lld_field_uint64_rollback(&function->itemid,
									&function->itemid_orig,
									&function->flags,
									ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID);

							lld_field_str_rollback(&function->function,
									&function->function_orig,
									&function->flags,
									ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION);

							lld_field_str_rollback(&function->parameter,
									&function->parameter_orig,
									&function->flags,
									ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER);

							function->flags &= ~ZBX_FLAG_LLD_FUNCTION_DELETE;
						}
						else
							function->flags &= ~ZBX_FLAG_LLD_FUNCTION_DISCOVERED;
					}
				}
				else
					trigger->flags &= ~ZBX_FLAG_LLD_TRIGGER_DISCOVERED;

				break;	/* only one same trigger can be here */
			}
		}

		zbx_vector_ptr_clean(&db_triggers, (zbx_mem_free_func_t)lld_trigger_free);
		zbx_vector_ptr_destroy(&db_triggers);

		zbx_free(sql);
	}

	zbx_vector_str_destroy(&descriptions);
	zbx_vector_uint64_destroy(&triggerids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #12
0
/******************************************************************************
 *                                                                            *
 * Function: lld_functions_get                                                *
 *                                                                            *
 * Purpose: retrieve functions which are used by all triggers in the host of  *
 *          the trigger prototype                                             *
 *                                                                            *
 ******************************************************************************/
static void	lld_functions_get(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *functions_proto,
		zbx_vector_ptr_t *triggers)
{
	const char		*__function_name = "lld_functions_get";

	int			i;
	zbx_lld_trigger_t	*trigger;
	zbx_vector_uint64_t	triggerids;

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

	zbx_vector_uint64_create(&triggerids);
	if (0 != parent_triggerid)
		zbx_vector_uint64_append(&triggerids, parent_triggerid);

	for (i = 0; i < triggers->values_num; i++)
	{
		trigger = (zbx_lld_trigger_t *)triggers->values[i];

		zbx_vector_uint64_append(&triggerids, trigger->triggerid);
	}

	if (0 != triggerids.values_num)
	{
		DB_RESULT		result;
		DB_ROW			row;
		zbx_lld_function_t	*function;
		zbx_uint64_t		triggerid;
		char			*sql = NULL;
		size_t			sql_alloc = 256, sql_offset = 0;
		int			index;

		zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		sql = zbx_malloc(sql, sql_alloc);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				"select functionid,triggerid,itemid,function,parameter"
				" from functions"
				" where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid",
				triggerids.values, triggerids.values_num);

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

		zbx_free(sql);

		while (NULL != (row = DBfetch(result)))
		{
			function = zbx_malloc(NULL, sizeof(zbx_lld_function_t));

			function->index = 0;
			ZBX_STR2UINT64(function->functionid, row[0]);
			ZBX_STR2UINT64(triggerid, row[1]);
			ZBX_STR2UINT64(function->itemid, row[2]);
			function->itemid_orig = 0;
			function->function = zbx_strdup(NULL, row[3]);
			function->function_orig = NULL;
			function->parameter = zbx_strdup(NULL, row[4]);
			function->parameter_orig = NULL;
			function->flags = ZBX_FLAG_LLD_FUNCTION_UNSET;

			if (0 != parent_triggerid && triggerid == parent_triggerid)
			{
				zbx_vector_ptr_append(functions_proto, function);
			}
			else if (FAIL != (index = zbx_vector_ptr_bsearch(triggers, &triggerid,
					ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
			{
				trigger = (zbx_lld_trigger_t *)triggers->values[index];

				zbx_vector_ptr_append(&trigger->functions, function);
			}
			else
			{
				THIS_SHOULD_NEVER_HAPPEN;
				lld_function_free(function);
			}
		}
		DBfree_result(result);

		if (NULL != functions_proto)
			zbx_vector_ptr_sort(functions_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

		for (i = 0; i < triggers->values_num; i++)
		{
			trigger = (zbx_lld_trigger_t *)triggers->values[i];

			zbx_vector_ptr_sort(&trigger->functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
		}
	}

	zbx_vector_uint64_destroy(&triggerids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
Example #13
0
/******************************************************************************
 *                                                                            *
 * Function: lld_triggers_save                                                *
 *                                                                            *
 * Purpose: add or update triggers in database based on discovery rule        *
 *                                                                            *
 ******************************************************************************/
static void	lld_triggers_save(zbx_uint64_t parent_triggerid, zbx_vector_ptr_t *triggers, unsigned char status,
		unsigned char type, unsigned char priority, const char *url)
{
	const char		*__function_name = "lld_triggers_save";

	int			i, j, new_triggers = 0, upd_triggers = 0, new_functions = 0;
	zbx_lld_trigger_t	*trigger;
	zbx_lld_function_t	*function;
	zbx_vector_ptr_t	upd_functions;	/* the ordered list of functions which will be updated */
	zbx_vector_uint64_t	del_functionids;
	zbx_uint64_t		triggerid = 0, functionid = 0;
	unsigned char		flags = ZBX_FLAG_LLD_TRIGGER_UNSET;
	char			*sql = NULL, *url_esc = NULL, *function_esc, *parameter_esc;
	size_t			sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0;
	zbx_db_insert_t		db_insert, db_insert_tdiscovery, db_insert_tfunctions;

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

	zbx_vector_ptr_create(&upd_functions);
	zbx_vector_uint64_create(&del_functionids);

	for (i = 0; i < triggers->values_num; i++)
	{
		trigger = (zbx_lld_trigger_t *)triggers->values[i];

		if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED))
			continue;

		if (0 == trigger->triggerid)
		{
			new_triggers++;
		}
		else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE))
		{
			upd_triggers++;
			flags |= trigger->flags;
		}

		for (j = 0; j < trigger->functions.values_num; j++)
		{
			function = (zbx_lld_function_t *)trigger->functions.values[j];

			if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE))
			{
				zbx_vector_uint64_append(&del_functionids, function->functionid);
				continue;
			}

			if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED))
				continue;

			if (0 == function->functionid)
				new_functions++;
			else if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE))
				zbx_vector_ptr_append(&upd_functions, function);
		}
	}

	if (0 == new_triggers && 0 == new_functions && 0 == upd_triggers && 0 == upd_functions.values_num &&
			0 == del_functionids.values_num)
	{
		goto out;
	}

	DBbegin();

	if (0 != new_triggers)
	{
		triggerid = DBget_maxid_num("triggers", new_triggers);

		zbx_db_insert_prepare(&db_insert, "triggers", "triggerid", "description", "expression", "priority",
				"status", "comments", "url", "type", "value", "state", "flags", NULL);

		zbx_db_insert_prepare(&db_insert_tdiscovery, "trigger_discovery", "triggerid", "parent_triggerid",
				NULL);
	}

	if (0 != new_functions)
	{
		functionid = DBget_maxid_num("functions", new_functions);

		zbx_db_insert_prepare(&db_insert_tfunctions, "functions", "functionid", "itemid", "triggerid",
				"function", "parameter", NULL);
	}

	if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num)
	{
		sql = zbx_malloc(sql, sql_alloc);
		DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
	}

	if (0 != (flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL))
		url_esc = DBdyn_escape_string(url);

	for (i = 0; i < triggers->values_num; i++)
	{
		char	*description_esc, *expression_esc, *comments_esc;

		trigger = (zbx_lld_trigger_t *)triggers->values[i];

		if (0 == (trigger->flags & ZBX_FLAG_LLD_TRIGGER_DISCOVERED))
			continue;

		for (j = 0; j < trigger->functions.values_num; j++)
		{
			function = (zbx_lld_function_t *)trigger->functions.values[j];

			if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_DELETE))
				continue;

			if (0 == (function->flags & ZBX_FLAG_LLD_FUNCTION_DISCOVERED))
				continue;

			if (0 == function->functionid)
			{
				zbx_db_insert_add_values(&db_insert_tfunctions, functionid, function->itemid,
						(0 == trigger->triggerid ? triggerid : trigger->triggerid),
						function->function, function->parameter);

				function->functionid = functionid++;
			}
		}

		if (0 == trigger->triggerid || 0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION))
			lld_expression_create(&trigger->expression, &trigger->functions);

		if (0 == trigger->triggerid)
		{
			zbx_db_insert_add_values(&db_insert, triggerid, trigger->description, trigger->expression,
					(int)priority, (int)status, trigger->comments, url, (int)type,
					(int)TRIGGER_VALUE_OK, (int)TRIGGER_STATE_NORMAL,
					(int)ZBX_FLAG_DISCOVERY_CREATED);

			zbx_db_insert_add_values(&db_insert_tdiscovery, triggerid, parent_triggerid);

			trigger->triggerid = triggerid++;
		}
		else if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE))
		{
			const char	*d = "";

			zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update triggers set ");

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_DESCRIPTION))
			{
				description_esc = DBdyn_escape_string(trigger->description);
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "description='%s'",
						description_esc);
				zbx_free(description_esc);
				d = ",";
			}

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_EXPRESSION))
			{
				expression_esc = DBdyn_escape_string(trigger->expression);
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sexpression='%s'", d,
						expression_esc);
				zbx_free(expression_esc);
				d = ",";
			}

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_TYPE))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d, (int)type);
				d = ",";
			}

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_PRIORITY))
			{
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spriority=%d", d, (int)priority);
				d = ",";
			}

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_COMMENTS))
			{
				comments_esc = DBdyn_escape_string(trigger->comments);
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%scomments='%s'", d,
						comments_esc);
				zbx_free(comments_esc);
				d = ",";
			}

			if (0 != (trigger->flags & ZBX_FLAG_LLD_TRIGGER_UPDATE_URL))
				zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%surl='%s'", d, url_esc);

			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
					" where triggerid=" ZBX_FS_UI64 ";\n", trigger->triggerid);
		}
	}

	zbx_free(url_esc);

	zbx_vector_ptr_sort(&upd_functions, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

	for (i = 0; i < upd_functions.values_num; i++)
	{
		const char	*d = "";

		function = (zbx_lld_function_t *)upd_functions.values[i];

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update functions set ");

		if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_ITEMID))
		{
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "itemid=" ZBX_FS_UI64,
					function->itemid);
			d = ",";
		}

		if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_FUNCTION))
		{
			function_esc = DBdyn_escape_string(function->function);
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sfunction='%s'", d,
					function_esc);
			zbx_free(function_esc);
			d = ",";
		}

		if (0 != (function->flags & ZBX_FLAG_LLD_FUNCTION_UPDATE_PARAMETER))
		{
			parameter_esc = DBdyn_escape_string(function->parameter);
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sparameter='%s'", d,
					parameter_esc);
			zbx_free(parameter_esc);
		}

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				" where functionid=" ZBX_FS_UI64 ";\n", function->functionid);
	}

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

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from functions where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "functionid",
				del_functionids.values, del_functionids.values_num);
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
	}

	if (0 != upd_triggers || 0 != upd_functions.values_num || 0 != del_functionids.values_num)
	{
		DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
		DBexecute("%s", sql);
		zbx_free(sql);
	}

	if (0 != new_triggers)
	{
		zbx_db_insert_execute(&db_insert);
		zbx_db_insert_clean(&db_insert);

		zbx_db_insert_execute(&db_insert_tdiscovery);
		zbx_db_insert_clean(&db_insert_tdiscovery);
	}

	if (0 != new_functions)
	{
		zbx_db_insert_execute(&db_insert_tfunctions);
		zbx_db_insert_clean(&db_insert_tfunctions);
	}

	DBcommit();
out:
	zbx_vector_uint64_destroy(&del_functionids);
	zbx_vector_ptr_destroy(&upd_functions);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * Function: process_deleted_records                                          *
 *                                                                            *
 * Purpose:                                                                   *
 *                                                                            *
 * Parameters:                                                                *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexander Vladishev                                                *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
static void	process_deleted_records(int nodeid, char *data)
{
	const char	*__function_name = "process_deleted_records";

typedef struct
{
	const ZBX_TABLE		*table;
	zbx_vector_uint64_t	recids;
	void			*next;
}
zbx_records_t;

	char		*r, *lf;
	zbx_uint64_t	recid;
	char		*sql = NULL;
	size_t		sql_alloc = 4 * ZBX_KIBIBYTE, sql_offset = 0;
	zbx_records_t	*first = NULL, *rec;

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

	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);	/* table name */

		if (NULL == first || 0 != strcmp(first->table->table, buf))
		{
			rec = zbx_malloc(NULL, sizeof(zbx_records_t));

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

			zbx_vector_uint64_create(&rec->recids);
			rec->next = first;
			first = rec;
		}

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

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

		if ('2' == *buf)	/* deleted record */
			zbx_vector_uint64_append(&rec->recids, recid);
next:
		if (lf != NULL)
		{
			*lf++ = '\n';
			r = lf;
		}
		else
			break;
	}

	sql = zbx_malloc(sql, sql_alloc);

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

	for (rec = first; NULL != rec; rec = rec->next)
	{
		if (0 == rec->recids.values_num)
			continue;

		zbx_vector_uint64_sort(&rec->recids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from %s where", rec->table->table);
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, rec->table->recid,
				rec->recids.values, rec->recids.values_num);
		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");

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

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

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

	zbx_free(sql);

	while (NULL != first)
	{
		rec = first;
		first = rec->next;

		zbx_vector_uint64_destroy(&rec->recids);
		zbx_free(rec);
	}

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * 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);
}
Example #16
0
/******************************************************************************
 *                                                                            *
 * Function: lld_gitems_get                                                   *
 *                                                                            *
 * Purpose: retrieve graphs_items which are used by the graph prototype and   *
 *          by selected graphs                                                *
 *                                                                            *
 ******************************************************************************/
static void	lld_gitems_get(zbx_uint64_t parent_graphid, zbx_vector_ptr_t *gitems_proto,
		zbx_vector_ptr_t *graphs)
{
	const char		*__function_name = "lld_gitems_get";

	int			i, index;
	zbx_lld_graph_t		*graph;
	zbx_lld_gitem_t		*gitem;
	zbx_uint64_t		graphid;
	zbx_vector_uint64_t	graphids;
	DB_RESULT		result;
	DB_ROW			row;
	char			*sql = NULL;
	size_t			sql_alloc = 256, sql_offset = 0;

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

	zbx_vector_uint64_create(&graphids);
	zbx_vector_uint64_append(&graphids, parent_graphid);

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		zbx_vector_uint64_append(&graphids, graph->graphid);
	}

	zbx_vector_uint64_sort(&graphids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

	sql = zbx_malloc(sql, sql_alloc);

	zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
			"select gitemid,graphid,itemid,drawtype,sortorder,color,yaxisside,calc_fnc,type"
			" from graphs_items"
			" where");
	DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "graphid",
			graphids.values, graphids.values_num);

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

	zbx_free(sql);

	while (NULL != (row = DBfetch(result)))
	{
		gitem = zbx_malloc(NULL, sizeof(zbx_lld_gitem_t));

		ZBX_STR2UINT64(gitem->gitemid, row[0]);
		ZBX_STR2UINT64(graphid, row[1]);
		ZBX_STR2UINT64(gitem->itemid, row[2]);
		ZBX_STR2UCHAR(gitem->drawtype, row[3]);
		gitem->sortorder = atoi(row[4]);
		gitem->color = zbx_strdup(NULL, row[5]);
		ZBX_STR2UCHAR(gitem->yaxisside, row[6]);
		ZBX_STR2UCHAR(gitem->calc_fnc, row[7]);
		ZBX_STR2UCHAR(gitem->type, row[8]);

		gitem->flags = ZBX_FLAG_LLD_GITEM_UNSET;

		if (graphid == parent_graphid)
		{
			zbx_vector_ptr_append(gitems_proto, gitem);
		}
		else if (FAIL != (index = zbx_vector_ptr_bsearch(graphs, &graphid,
				ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
		{
			graph = (zbx_lld_graph_t *)graphs->values[index];

			zbx_vector_ptr_append(&graph->gitems, gitem);
		}
		else
		{
			THIS_SHOULD_NEVER_HAPPEN;
			lld_gitem_free(gitem);
		}
	}
	DBfree_result(result);

	zbx_vector_ptr_sort(gitems_proto, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);

	for (i = 0; i < graphs->values_num; i++)
	{
		graph = (zbx_lld_graph_t *)graphs->values[i];

		zbx_vector_ptr_sort(&graph->gitems, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
	}

	zbx_vector_uint64_destroy(&graphids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * 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);
}
Example #18
0
/******************************************************************************
 *                                                                            *
 * Function: lld_items_get                                                    *
 *                                                                            *
 * Purpose: returns the list of items which are related to the graph          *
 *          prototype                                                         *
 *                                                                            *
 * Parameters: gitems_proto      - [IN] graph prototype's graphs_items        *
 *             ymin_itemid_proto - [IN] graph prototype's ymin_itemid         *
 *             ymax_itemid_proto - [IN] graph prototype's ymax_itemid         *
 *             items             - [OUT] sorted list of items                 *
 *                                                                            *
 ******************************************************************************/
static void	lld_items_get(zbx_vector_ptr_t *gitems_proto, zbx_uint64_t ymin_itemid_proto,
		zbx_uint64_t ymax_itemid_proto, zbx_vector_ptr_t *items)
{
	const char		*__function_name = "lld_items_get";

	DB_RESULT		result;
	DB_ROW			row;
	zbx_lld_gitem_t		*gitem;
	zbx_lld_item_t		*item;
	zbx_vector_uint64_t	itemids;
	int			i;

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

	zbx_vector_uint64_create(&itemids);

	for (i = 0; i < gitems_proto->values_num; i++)
	{
		gitem = (zbx_lld_gitem_t *)gitems_proto->values[i];

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

	if (0 != ymin_itemid_proto)
		zbx_vector_uint64_append(&itemids, ymin_itemid_proto);

	if (0 != ymax_itemid_proto)
		zbx_vector_uint64_append(&itemids, ymax_itemid_proto);

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

		zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);

		sql = zbx_malloc(sql, sql_alloc);

		zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
				"select itemid,flags"
				" from items"
				" where");
		DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid", itemids.values, itemids.values_num);

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

		zbx_free(sql);

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

			ZBX_STR2UINT64(item->itemid, row[0]);
			ZBX_STR2UCHAR(item->flags, row[1]);

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

		zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
	}

	zbx_vector_uint64_destroy(&itemids);

	zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
}
/******************************************************************************
 *                                                                            *
 * 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);
}
Example #20
0
/******************************************************************************
 *                                                                            *
 * Function: execute_operations                                               *
 *                                                                            *
 * Purpose: execute all operations linked to the action                       *
 *                                                                            *
 * Parameters: action - action to execute operations for                      *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 ******************************************************************************/
static void	execute_operations(DB_EVENT *event, zbx_uint64_t actionid)
{
	const char		*__function_name = "execute_operations";

	DB_RESULT		result;
	DB_ROW			row;
	unsigned char		operationtype;
	zbx_uint64_t		groupid, templateid;
	zbx_vector_uint64_t	lnk_templateids, del_templateids,
				new_groupids, del_groupids;

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

	zbx_vector_uint64_create(&lnk_templateids);
	zbx_vector_uint64_create(&del_templateids);
	zbx_vector_uint64_create(&new_groupids);
	zbx_vector_uint64_create(&del_groupids);

	result = DBselect(
			"select o.operationtype,g.groupid,t.templateid"
			" from operations o"
				" left join opgroup g on g.operationid=o.operationid"
				" left join optemplate t on t.operationid=o.operationid"
			" where o.actionid=" ZBX_FS_UI64,
			actionid);

	while (NULL != (row = DBfetch(result)))
	{
		operationtype = (unsigned char)atoi(row[0]);
		ZBX_DBROW2UINT64(groupid, row[1]);
		ZBX_DBROW2UINT64(templateid, row[2]);

		switch (operationtype)
		{
			case OPERATION_TYPE_HOST_ADD:
				op_host_add(event);
				break;
			case OPERATION_TYPE_HOST_REMOVE:
				op_host_del(event);
				break;
			case OPERATION_TYPE_HOST_ENABLE:
				op_host_enable(event);
				break;
			case OPERATION_TYPE_HOST_DISABLE:
				op_host_disable(event);
				break;
			case OPERATION_TYPE_GROUP_ADD:
				if (0 != groupid)
					zbx_vector_uint64_append(&new_groupids, groupid);
				break;
			case OPERATION_TYPE_GROUP_REMOVE:
				if (0 != groupid)
					zbx_vector_uint64_append(&del_groupids, groupid);
				break;
			case OPERATION_TYPE_TEMPLATE_ADD:
				if (0 != templateid)
					zbx_vector_uint64_append(&lnk_templateids, templateid);
				break;
			case OPERATION_TYPE_TEMPLATE_REMOVE:
				if (0 != templateid)
					zbx_vector_uint64_append(&del_templateids, templateid);
				break;
			default:
				;
		}
	}
	DBfree_result(result);

	if (0 != lnk_templateids.values_num)
	{
		zbx_vector_uint64_sort(&lnk_templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
		op_template_add(event, &lnk_templateids);
	}

	if (0 != del_templateids.values_num)
	{
		zbx_vector_uint64_sort(&del_templateids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
		op_template_del(event, &del_templateids);
	}

	if (0 != new_groupids.values_num)
	{
		zbx_vector_uint64_sort(&new_groupids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
		op_groups_add(event, &new_groupids);
	}

	if (0 != del_groupids.values_num)
	{
		zbx_vector_uint64_sort(&del_groupids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
		op_groups_del(event, &del_groupids);
	}

	zbx_vector_uint64_destroy(&del_groupids);
	zbx_vector_uint64_destroy(&new_groupids);
	zbx_vector_uint64_destroy(&del_templateids);
	zbx_vector_uint64_destroy(&lnk_templateids);

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