Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndris Zeila <andris.zeila@zabbix.com>2022-06-21 16:26:35 +0300
committerAndris Zeila <andris.zeila@zabbix.com>2022-06-21 16:26:35 +0300
commit52fadc279aa4abf360b0bf1f39499b53296c3db4 (patch)
treec48a316e6e2b121c8e3be7e5d02c06bdd31e9ce2
parentd1faf66c02fa53702e7a51dfc58faf65b67c0cc6 (diff)
parentf3fb36f424064c1251a467e5f6b577c8f7508715 (diff)
........S. [ZBX-21145] changed host, item and trigger tag merging logic during template linking and LLD to reduce database updates
Merge in ZBX/zabbix from feature/ZBX-21145-6.0 to release/6.0 * commit 'f3fb36f424064c1251a467e5f6b577c8f7508715': (21 commits) ........S. [ZBX-21145] fixed sql query when copying trigger tags during trigger linking ........S. [ZBX-21145] fixed trigger tak copying when linking templates ........S. [ZBX-21145] style fix ........S. [ZBX-21145] fixed item tag creation in LLD ........S. [ZBX-21145] fixed host prototype lookup result checking ........S. [ZBX-21145] fixed resetting of duplicate tag validation result ........S. [ZBX-21145] backported tag merging/validation .D........ [ZBX-21145] added changelog entry ........S. [ZBX-21145] fixed warnings ........S. [ZBX-21145] added LLD error messages when host/item/trigger creation failed because of invalid tags ........S. [ZBX-21145] replaced trigger tag validation in lld with common tag validator ........S. [ZBX-21145] replaced item tag validation in lld with common tag validator ........S. [ZBX-21145] added common tag validator, replaced host tag validation in LLD ........S. [ZBX-21145] allow partial lld trigger update in the case of invalid tags ........S. [ZBX-21145] changed item tag LLD to allow item update with invalid tags ........S. [ZBX-21145] reworked lld trigger tag copying ........S. [ZBX-21145] reworked item LLD linking to use common tag merging logic ........S. [ZBX-21145] added auditlog support when copying template trigger tags ........S. [ZBX-21145] reworked trigger/trigger prototype template linking to use common tag merging logic (without auditlog updates) ........S. [ZBX-21145] reworked item/item prototype template linking to use common tag merging logic ...
-rw-r--r--ChangeLog.d/bugfix/ZBX-211451
-rw-r--r--include/db.h10
-rw-r--r--src/libs/zbxaudit/audit_trigger.c45
-rw-r--r--src/libs/zbxaudit/audit_trigger.h6
-rw-r--r--src/libs/zbxdbhigh/host.c96
-rw-r--r--src/libs/zbxdbhigh/tag.c323
-rw-r--r--src/libs/zbxdbhigh/template.h6
-rw-r--r--src/libs/zbxdbhigh/template_item.c88
-rw-r--r--src/libs/zbxdbhigh/trigger_linking.c304
-rw-r--r--src/zabbix_server/lld/lld.h4
-rw-r--r--src/zabbix_server/lld/lld_host.c136
-rw-r--r--src/zabbix_server/lld/lld_item.c312
-rw-r--r--src/zabbix_server/lld/lld_trigger.c343
13 files changed, 798 insertions, 876 deletions
diff --git a/ChangeLog.d/bugfix/ZBX-21145 b/ChangeLog.d/bugfix/ZBX-21145
new file mode 100644
index 00000000000..f7fe5e8c5fd
--- /dev/null
+++ b/ChangeLog.d/bugfix/ZBX-21145
@@ -0,0 +1 @@
+........S. [ZBX-21145] changed host, item and trigger tag merging logic during template linking and LLD to reduce database updates (wiper)
diff --git a/include/db.h b/include/db.h
index e2a192fd56c..82af4018dcd 100644
--- a/include/db.h
+++ b/include/db.h
@@ -83,8 +83,6 @@ zbx_graph_item_type;
# define TRIGGER_COMMENTS_LEN 65535
#endif
#define TRIGGER_EVENT_NAME_LEN 2048
-#define TAG_NAME_LEN 255
-#define TAG_VALUE_LEN 255
#define GROUP_NAME_LEN 255
@@ -176,7 +174,9 @@ zbx_graph_item_type;
#define ITEM_PARAMETER_NAME_LEN 255
#define ITEM_PARAMETER_VALUE_LEN 2048
-#define ITEM_TAG_FIELD_LEN 255
+/* common tag/value field lengths for all tags */
+#define TAG_NAME_LEN 255
+#define TAG_VALUE_LEN 255
#define HISTORY_STR_VALUE_LEN 255
#define HISTORY_TEXT_VALUE_LEN 65535
@@ -894,12 +894,14 @@ typedef struct
}
zbx_db_tag_t;
+ZBX_PTR_VECTOR_DECL(db_tag_ptr, zbx_db_tag_t *)
+
zbx_db_tag_t *zbx_db_tag_create(const char *tag_tag, const char *tag_value);
void zbx_db_tag_free(zbx_db_tag_t *tag);
int zbx_db_tag_compare_func(const void *d1, const void *d2);
int zbx_db_tag_compare_func_template(const void *d1, const void *d2);
-ZBX_PTR_VECTOR_DECL(db_tag_ptr, zbx_db_tag_t *)
+int zbx_merge_tags(zbx_vector_db_tag_ptr_t *dst, zbx_vector_db_tag_ptr_t *src, const char *owner, char **error);
typedef enum
{
diff --git a/src/libs/zbxaudit/audit_trigger.c b/src/libs/zbxaudit/audit_trigger.c
index 4085a48c772..292d9e58035 100644
--- a/src/libs/zbxaudit/audit_trigger.c
+++ b/src/libs/zbxaudit/audit_trigger.c
@@ -351,20 +351,55 @@ void zbx_audit_trigger_update_json_delete_tags(zbx_uint64_t triggerid, int flags
zbx_audit_update_json_append_no_value(triggerid, AUDIT_TRIGGER_ID, AUDIT_DETAILS_ACTION_DELETE, audit_key);
}
+#define TRIGGER_RESOURCE_KEY_RESOLVE_TAG(resource, nested) \
+ if (AUDIT_RESOURCE_TRIGGER == resource_type) \
+ { \
+ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "trigger.tag[" ZBX_FS_UI64 \
+ "]"#nested#resource, triggertagid); \
+ } \
+ else if (AUDIT_RESOURCE_TRIGGER_PROTOTYPE == resource_type) \
+ { \
+ zbx_snprintf(audit_key_##resource, sizeof(audit_key_##resource), "triggerprototype.tag[" \
+ ZBX_FS_UI64 "]"#nested#resource, triggertagid); \
+ } \
+ else \
+ { \
+ THIS_SHOULD_NEVER_HAPPEN; \
+ return; \
+ }
+
#define PREPARE_AUDIT_TRIGGER_UPDATE_TAG(resource, type1, type2) \
-void zbx_audit_trigger_update_json_update_tag_##resource(zbx_uint64_t triggerid, zbx_uint64_t triggertagid, \
- type1 resource##_old, type1 resource##_new) \
+void zbx_audit_trigger_update_json_update_tag_##resource(zbx_uint64_t triggerid, int trigger_flags, \
+ zbx_uint64_t triggertagid, type1 resource##_old, type1 resource##_new) \
{ \
- char buf[AUDIT_DETAILS_KEY_LEN]; \
+ int resource_type; \
+ char audit_key_##resource[AUDIT_DETAILS_KEY_LEN]; \
\
RETURN_IF_AUDIT_OFF(); \
+ resource_type = trigger_flag_to_resource_type(trigger_flags); \
\
- zbx_snprintf(buf, sizeof(buf), "trigger.tags[" ZBX_FS_UI64 "]", triggertagid); \
+ TRIGGER_RESOURCE_KEY_RESOLVE_TAG(resource,.) \
\
- zbx_audit_update_json_update_##type2(triggerid, AUDIT_TRIGGER_ID, buf, resource##_old, resource##_new); \
+ zbx_audit_update_json_update_##type2(triggerid, AUDIT_TRIGGER_ID, audit_key_##resource, resource##_old, \
+ resource##_new); \
}
PREPARE_AUDIT_TRIGGER_UPDATE_TAG(tag, const char*, string)
PREPARE_AUDIT_TRIGGER_UPDATE_TAG(value, const char*, string)
#undef PREPARE_AUDIT_TRIGGER_UPDATE_TAG
+
+void zbx_audit_trigger_update_json_update_trigger_tag_create_entry(zbx_uint64_t triggerid, int trigger_flags,
+ zbx_uint64_t triggertagid)
+{
+ int resource_type;
+ char audit_key_[AUDIT_DETAILS_KEY_LEN];
+
+ RETURN_IF_AUDIT_OFF();
+
+ resource_type = trigger_flag_to_resource_type(trigger_flags);
+
+ TRIGGER_RESOURCE_KEY_RESOLVE_TAG(,)
+
+ zbx_audit_update_json_append_no_value(triggerid, AUDIT_TRIGGER_ID, AUDIT_DETAILS_ACTION_UPDATE, audit_key_);
+}
diff --git a/src/libs/zbxaudit/audit_trigger.h b/src/libs/zbxaudit/audit_trigger.h
index 11f30420b3e..aadb3ceee84 100644
--- a/src/libs/zbxaudit/audit_trigger.h
+++ b/src/libs/zbxaudit/audit_trigger.h
@@ -62,10 +62,12 @@ void zbx_audit_trigger_update_json_remove_dependency(int flags, zbx_uint64_t tri
void zbx_audit_trigger_update_json_add_tags_and_values(zbx_uint64_t triggerid, int flags, zbx_uint64_t triggertagid,
const char *tag, const char *value);
void zbx_audit_trigger_update_json_delete_tags(zbx_uint64_t triggerid, int flags, zbx_uint64_t triggertagid);
+void zbx_audit_trigger_update_json_update_trigger_tag_create_entry(zbx_uint64_t trigger, int trigger_flags,
+ zbx_uint64_t tagid);
#define PREPARE_AUDIT_TRIGGER_UPDATE_TAG_H(resource, type1) \
-void zbx_audit_trigger_update_json_update_tag_##resource(zbx_uint64_t triggerid, zbx_uint64_t triggertagid, \
- type1 resource##_old, type1 resource##_new);
+void zbx_audit_trigger_update_json_update_tag_##resource(zbx_uint64_t triggerid, int trigger_flags, \
+ zbx_uint64_t triggertagid, type1 resource##_old, type1 resource##_new);
PREPARE_AUDIT_TRIGGER_UPDATE_TAG_H(tag, const char*)
PREPARE_AUDIT_TRIGGER_UPDATE_TAG_H(value, const char*)
diff --git a/src/libs/zbxdbhigh/host.c b/src/libs/zbxdbhigh/host.c
index 71eefab809d..311db4ccc05 100644
--- a/src/libs/zbxdbhigh/host.c
+++ b/src/libs/zbxdbhigh/host.c
@@ -2014,6 +2014,7 @@ typedef struct
zbx_vector_ptr_t group_prototypes; /* list of group prototypes */
zbx_vector_macros_t hostmacros; /* list of user macros */
zbx_vector_db_tag_ptr_t tags; /* list of host prototype tags */
+ zbx_vector_db_tag_ptr_t new_tags; /* list of host prototype template tags */
zbx_vector_interfaces_t interfaces; /* list of interfaces */
char *host;
char *name_orig;
@@ -2105,6 +2106,8 @@ static void DBhost_prototype_clean(zbx_host_prototype_t *host_prototype)
zbx_vector_macros_destroy(&host_prototype->hostmacros);
zbx_vector_db_tag_ptr_clear_ext(&host_prototype->tags, zbx_db_tag_free);
zbx_vector_db_tag_ptr_destroy(&host_prototype->tags);
+ zbx_vector_db_tag_ptr_clear_ext(&host_prototype->new_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&host_prototype->new_tags);
zbx_vector_interfaces_clear_ext(&host_prototype->interfaces, DBhost_interface_free);
zbx_vector_interfaces_destroy(&host_prototype->interfaces);
DBgroup_prototypes_clean(&host_prototype->group_prototypes);
@@ -2191,6 +2194,7 @@ static void DBhost_prototypes_make(zbx_uint64_t hostid, zbx_vector_uint64_t *tem
zbx_vector_ptr_create(&host_prototype->group_prototypes);
zbx_vector_macros_create(&host_prototype->hostmacros);
zbx_vector_db_tag_ptr_create(&host_prototype->tags);
+ zbx_vector_db_tag_ptr_create(&host_prototype->new_tags);
zbx_vector_interfaces_create(&host_prototype->interfaces);
host_prototype->host = zbx_strdup(NULL, row[2]);
host_prototype->name = zbx_strdup(NULL, row[3]);
@@ -2956,20 +2960,18 @@ static void DBhost_prototypes_macros_make(zbx_vector_ptr_t *host_prototypes, zbx
* *
* Parameters: host_prototypes - [IN/OUT] list of host prototypes *
* should be sorted by templateid *
- * del_tagids - [OUT] list of host tagids which *
- * should be deleted *
* *
* Comments: auxiliary function for DBcopy_template_host_prototypes() *
* *
******************************************************************************/
-static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes, zbx_vector_uint64_t *del_tagids)
+static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes)
{
DB_RESULT result;
DB_ROW row;
char *sql = NULL;
size_t sql_alloc = 0, sql_offset = 0;
zbx_vector_uint64_t hostids;
- zbx_uint64_t hostid, tagid;
+ zbx_uint64_t hostid;
zbx_host_prototype_t *host_prototype = NULL;
zbx_db_tag_t *tag;
int i;
@@ -3010,7 +3012,7 @@ static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes, zbx_v
tag = zbx_db_tag_create(row[1], row[2]);
tag->tagid = 0;
- zbx_vector_db_tag_ptr_append(&host_prototype->tags, tag);
+ zbx_vector_db_tag_ptr_append(&host_prototype->new_tags, tag);
}
DBfree_result(result);
@@ -3028,11 +3030,9 @@ static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes, zbx_v
zbx_vector_uint64_append(&hostids, host_prototype->hostid);
}
- /* replace existing tags with the new tags */
if (0 != hostids.values_num)
{
- int tag_index = 0;
- zbx_host_prototype_t *host_prototype_local = NULL;
+ host_prototype = NULL;
zbx_vector_uint64_sort(&hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
@@ -3045,55 +3045,37 @@ static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes, zbx_v
while (NULL != (row = DBfetch(result)))
{
- ZBX_STR2UINT64(tagid, row[0]);
- ZBX_STR2UINT64(hostid, row[1]);
+ ZBX_DBROW2UINT64(hostid, row[1]);
- if (NULL == host_prototype_local || host_prototype_local->hostid != hostid)
+ if (NULL == host_prototype || host_prototype->hostid != hostid)
{
- tag_index = 0;
-
for (i = 0; i < host_prototypes->values_num; i++)
{
- host_prototype_local = (zbx_host_prototype_t *)host_prototypes->values[i];
+ host_prototype = (zbx_host_prototype_t *)host_prototypes->values[i];
- if (host_prototype_local->hostid == hostid)
+ if (host_prototype->hostid == hostid)
break;
}
- if (NULL != host_prototype_local && host_prototype_local->hostid != hostid)
+ if (NULL == host_prototype || host_prototype->hostid != hostid)
{
THIS_SHOULD_NEVER_HAPPEN;
continue;
}
}
- if (NULL == host_prototype_local)
- continue;
-
- if (tag_index < host_prototype_local->tags.values_num)
- {
- host_prototype_local->tags.values[tag_index]->tagid = tagid;
- host_prototype_local->tags.values[tag_index]->flags |= ZBX_FLAG_DB_TAG_UPDATE_TAG |
- ZBX_FLAG_DB_TAG_UPDATE_VALUE;
-
- host_prototype_local->tags.values[tag_index]->tag_orig = zbx_strdup(NULL, row[2]);
- host_prototype_local->tags.values[tag_index]->value_orig = zbx_strdup(NULL, row[3]);
- }
- else
- {
- zbx_vector_uint64_append(del_tagids, tagid);
-
- zbx_audit_host_prototype_create_entry(AUDIT_ACTION_UPDATE, host_prototype_local->hostid,
- host_prototype_local->host);
- zbx_audit_host_prototype_update_json_delete_tag(host_prototype_local->hostid, tagid);
- }
-
- tag_index++;
+ tag = zbx_db_tag_create(row[2], row[3]);
+ ZBX_DBROW2UINT64(tag->tagid, row[0]);
+ zbx_vector_db_tag_ptr_append(&host_prototype->tags, tag);
}
DBfree_result(result);
}
- zbx_vector_uint64_sort(del_tagids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+ for (i = 0; i < host_prototypes->values_num; i++)
+ {
+ host_prototype = (zbx_host_prototype_t *)host_prototypes->values[i];
+ (void)zbx_merge_tags(&host_prototype->tags, &host_prototype->new_tags, NULL, NULL);
+ }
zbx_vector_uint64_destroy(&hostids);
zbx_free(sql);
@@ -3477,7 +3459,6 @@ static void DBhost_prototypes_interface_snmp_prepare_sql(zbx_uint64_t hostid, co
* Parameters: host_prototypes - [IN] vector of host prototypes *
* del_hosttemplateids - [IN] host template ids for delete *
* del_hostmacroids - [IN] host macro ids for delete *
- * del_tagids - [IN] tag ids for delete *
* del_interfaceids - [IN] interface ids for delete *
* del_snmpids - [IN] SNMP interface ids for delete *
* db_insert_htemplates - [IN/OUT] templates insert structure *
@@ -3485,8 +3466,8 @@ static void DBhost_prototypes_interface_snmp_prepare_sql(zbx_uint64_t hostid, co
******************************************************************************/
static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
const zbx_vector_uint64_t *del_hosttemplateids, const zbx_vector_uint64_t *del_hostmacroids,
- const zbx_vector_uint64_t *del_tagids, const zbx_vector_uint64_t *del_interfaceids,
- const zbx_vector_uint64_t *del_snmpids, zbx_db_insert_t *db_insert_htemplates)
+ const zbx_vector_uint64_t *del_interfaceids, const zbx_vector_uint64_t *del_snmpids,
+ zbx_db_insert_t *db_insert_htemplates)
{
char *sql1 = NULL, *sql2 = NULL, *name_esc, *value_esc;
size_t sql1_alloc = ZBX_KIBIBYTE, sql1_offset = 0,
@@ -3505,12 +3486,13 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
db_insert_hmacro, db_insert_tag, db_insert_iface, db_insert_snmp,
db_insert_inventory_mode;
zbx_vector_db_tag_ptr_t upd_tags;
- zbx_vector_uint64_t del_inventory_modes_hostids;
+ zbx_vector_uint64_t del_inventory_modes_hostids, del_tagids;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
zbx_vector_db_tag_ptr_create(&upd_tags);
zbx_vector_uint64_create(&del_inventory_modes_hostids);
+ zbx_vector_uint64_create(&del_tagids);
for (i = 0; i < host_prototypes->values_num; i++)
{
@@ -3590,6 +3572,13 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
tag->tagid, tag->value_orig, tag->value);
}
}
+ else if (ZBX_FLAG_DB_TAG_REMOVE == tag->flags)
+ {
+ zbx_audit_host_prototype_create_entry(AUDIT_ACTION_UPDATE, host_prototype->hostid,
+ host_prototype->host);
+ zbx_audit_host_prototype_update_json_delete_tag(host_prototype->hostid, tag->tagid);
+ zbx_vector_uint64_append(&del_tagids, tag->tagid);
+ }
}
for (j = 0; j < host_prototype->interfaces.values_num; j++)
@@ -3634,7 +3623,7 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
if (0 != new_hosts_templates)
hosttemplateid = DBget_maxid_num("hosts_templates", new_hosts_templates);
- if (0 != del_hosttemplateids->values_num || 0 != del_hostmacroids->values_num || 0 != del_tagids->values_num ||
+ if (0 != del_hosttemplateids->values_num || 0 != del_hostmacroids->values_num || 0 != del_tagids.values_num ||
0 != del_snmpids->values_num || 0 != del_interfaceids->values_num ||
0 != del_inventory_modes_hostids.values_num)
{
@@ -3658,11 +3647,11 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, ";\n");
}
- if (0 != del_tagids->values_num)
+ if (0 != del_tagids.values_num)
{
zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, "delete from host_tag where");
- DBadd_condition_alloc(&sql2, &sql2_alloc, &sql2_offset, "hosttagid", del_tagids->values,
- del_tagids->values_num);
+ DBadd_condition_alloc(&sql2, &sql2_alloc, &sql2_offset, "hosttagid", del_tagids.values,
+ del_tagids.values_num);
zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, ";\n");
}
@@ -4197,7 +4186,7 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
}
if (SUCCEED == res && (NULL != sql2 || 0 != del_hosttemplateids->values_num ||
- 0 != del_hostmacroids->values_num || 0 != del_tagids->values_num ||
+ 0 != del_hostmacroids->values_num || 0 != del_tagids.values_num ||
0 != del_interfaceids->values_num || 0 != del_snmpids->values_num ||
0 != del_inventory_modes_hostids.values_num))
{
@@ -4213,6 +4202,7 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
zbx_vector_db_tag_ptr_destroy(&upd_tags);
zbx_vector_uint64_destroy(&del_inventory_modes_hostids);
+ zbx_vector_uint64_destroy(&del_tagids);
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
@@ -4245,26 +4235,24 @@ static void DBcopy_template_host_prototypes(zbx_uint64_t hostid, zbx_vector_uint
if (0 != host_prototypes.values_num)
{
- zbx_vector_uint64_t del_hosttemplateids, del_group_prototypeids, del_macroids, del_tagids,
- del_interfaceids, del_snmp_interfaceids;
+ zbx_vector_uint64_t del_hosttemplateids, del_group_prototypeids, del_macroids, del_interfaceids,
+ del_snmp_interfaceids;
zbx_vector_uint64_create(&del_hosttemplateids);
zbx_vector_uint64_create(&del_group_prototypeids);
zbx_vector_uint64_create(&del_macroids);
- zbx_vector_uint64_create(&del_tagids);
zbx_vector_uint64_create(&del_interfaceids);
zbx_vector_uint64_create(&del_snmp_interfaceids);
DBhost_prototypes_templates_make(&host_prototypes, &del_hosttemplateids);
DBhost_prototypes_groups_make(&host_prototypes, &del_group_prototypeids);
DBhost_prototypes_macros_make(&host_prototypes, &del_macroids);
- DBhost_prototypes_tags_make(&host_prototypes, &del_tagids);
+ DBhost_prototypes_tags_make(&host_prototypes);
DBhost_prototypes_interfaces_make(&host_prototypes, &del_interfaceids, &del_snmp_interfaceids);
- DBhost_prototypes_save(&host_prototypes, &del_hosttemplateids, &del_macroids, &del_tagids,
+ DBhost_prototypes_save(&host_prototypes, &del_hosttemplateids, &del_macroids,
&del_interfaceids, &del_snmp_interfaceids, db_insert_htemplates);
DBgroup_prototypes_delete(&del_group_prototypeids);
- zbx_vector_uint64_destroy(&del_tagids);
zbx_vector_uint64_destroy(&del_macroids);
zbx_vector_uint64_destroy(&del_group_prototypeids);
zbx_vector_uint64_destroy(&del_snmp_interfaceids);
diff --git a/src/libs/zbxdbhigh/tag.c b/src/libs/zbxdbhigh/tag.c
index 02e9506a461..9fbd4c38403 100644
--- a/src/libs/zbxdbhigh/tag.c
+++ b/src/libs/zbxdbhigh/tag.c
@@ -18,15 +18,18 @@
**/
#include "common.h"
-#include "../zbxalgo/vectorimpl.h"
+#include "../zbxalgo/vectorimpl.h"
#include "db.h"
+ZBX_PTR_VECTOR_IMPL(db_tag_ptr, zbx_db_tag_t *)
+
zbx_db_tag_t *zbx_db_tag_create(const char *tag_tag, const char *tag_value)
{
zbx_db_tag_t *tag;
tag = (zbx_db_tag_t *)zbx_malloc(NULL, sizeof(zbx_db_tag_t));
+ tag->tagid = 0;
tag->flags = ZBX_FLAG_DB_TAG_UNSET;
tag->tag = zbx_strdup(NULL, tag_tag);
tag->value = zbx_strdup(NULL, tag_value);
@@ -71,4 +74,320 @@ int zbx_db_tag_compare_func_template(const void *d1, const void *d2)
return 0;
}
-ZBX_PTR_VECTOR_IMPL(db_tag_ptr, zbx_db_tag_t *)
+/******************************************************************************
+ * *
+ * Purpose: roll back tag updates done during merge process *
+ * *
+ * Return value: SUCCEED - updates were rolled back *
+ * FAIL - new tag, rollback impossible *
+ * *
+ ******************************************************************************/
+static int db_tag_rollback(zbx_db_tag_t *tag)
+{
+ if (0 == tag->tagid)
+ return FAIL;
+
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE_TAG))
+ {
+ zbx_free(tag->tag);
+ tag->tag = tag->tag_orig;
+ tag->tag_orig = NULL;
+ tag->flags &= (~ZBX_FLAG_DB_TAG_UPDATE_TAG);
+ }
+
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE_VALUE))
+ {
+ zbx_free(tag->value);
+ tag->value = tag->value_orig;
+ tag->value_orig = NULL;
+ tag->flags &= (~ZBX_FLAG_DB_TAG_UPDATE_VALUE);
+ }
+
+ return SUCCEED;
+}
+
+#define ZBX_TAG_OP(tag) (0 == tag->tagid ? "create" : "update")
+
+typedef enum
+{
+ ZBX_DB_TAG_TAG,
+ ZBX_DB_TAG_VALUE
+}
+zbx_db_tag_field_t;
+
+/******************************************************************************
+ * *
+ * Purpose: check validness of a single tag field (tag or value) *
+ * *
+ * Return value: SUCCEED - tag field is valid *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int db_tag_check_field(const zbx_db_tag_t *tag, zbx_db_tag_field_t type, const char *owner, char **error)
+{
+ const char *field, *str;
+ size_t field_len, str_len;
+
+ switch (type)
+ {
+ case ZBX_DB_TAG_TAG:
+ field = "tag";
+ str = tag->tag;
+ field_len = TAG_NAME_LEN;
+ break;
+ case ZBX_DB_TAG_VALUE:
+ field = "value";
+ str = tag->value;
+ field_len = TAG_VALUE_LEN;
+ break;
+ default:
+ THIS_SHOULD_NEVER_HAPPEN;
+
+ if (NULL != *error)
+ {
+ *error = zbx_strdcatf(*error, "Cannot %s %s tag: invalid field type.\n", ZBX_TAG_OP(tag),
+ owner);
+ }
+ return FAIL;
+ }
+
+ if (SUCCEED != zbx_is_utf8(str))
+ {
+ if (NULL != error)
+ {
+ char *ptr_utf8;
+
+ ptr_utf8 = zbx_strdup(NULL, str);
+ zbx_replace_invalid_utf8(ptr_utf8);
+ *error = zbx_strdcatf(*error, "Cannot %s %s tag: %s \"%s\" has invalid UTF-8 sequence.\n",
+ ZBX_TAG_OP(tag), owner, field, ptr_utf8);
+ zbx_free(ptr_utf8);
+ }
+
+ return FAIL;
+ }
+
+ str_len = zbx_strlen_utf8(str);
+
+ if (field_len < str_len)
+ {
+ if (NULL != *error)
+ {
+ *error = zbx_strdcatf(*error, "Cannot %s %s tag: %s \"%128s...\" is too long.\n",
+ ZBX_TAG_OP(tag), owner, field, str);
+ }
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: check validness of all fields for a list of tags *
+ * *
+ * Return value: SUCCEED - tags have valid fields *
+ * FAIL - otherwise *
+ * *
+ ******************************************************************************/
+static int check_tag_fields(zbx_vector_db_tag_ptr_t *tags, const char *owner, char **error)
+{
+ int i, ret = SUCCEED;
+
+ for (i = 0; i < tags->values_num; i++)
+ {
+ zbx_db_tag_t *tag = tags->values[i];
+ int errors = 0;
+
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
+ continue;
+
+ if ('\0' == *tag->tag)
+ {
+ if (NULL != error)
+ {
+ *error = zbx_strdcatf(*error, "Cannot %s %s tag: empty tag name.\n", ZBX_TAG_OP(tag),
+ owner);
+ }
+ errors += FAIL;
+ }
+
+ errors += db_tag_check_field(tag, ZBX_DB_TAG_TAG, owner, error);
+ errors += db_tag_check_field(tag, ZBX_DB_TAG_VALUE, owner, error);
+
+ if (0 > errors)
+ {
+ if (SUCCEED != db_tag_rollback(tag))
+ {
+ zbx_db_tag_free(tag);
+ zbx_vector_db_tag_ptr_remove_noorder(tags, i--);
+ }
+
+ ret = FAIL;
+ }
+ }
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: check new tags for duplicate tag+value combinations *
+ * *
+ * Parameters: tags - [IN/OUT] the tags to check *
+ * owner - [IN] the owned object (host, item, trigger) *
+ * error - [OUT] the error message *
+ * *
+ * Return value: SUCCEED - tags have no duplicates *
+ * FAIL - otherwise *
+ * *
+ * Comments: Existing tags are rolled back to their original values, while *
+ * new tags are removed. *
+ * *
+ ******************************************************************************/
+static int check_duplicate_tags(zbx_vector_db_tag_ptr_t *tags, const char *owner, char **error)
+{
+ int i, j, ret = SUCCEED;
+
+ for (i = 0; i < tags->values_num; i++)
+ {
+ zbx_db_tag_t *left = tags->values[i];
+
+ for (j = 0; j < i; j++)
+ {
+ zbx_db_tag_t *right = tags->values[j];
+
+ if (0 == strcmp(left->tag, right->tag) && 0 == strcmp(left->value, right->value))
+ {
+ if (NULL != error)
+ {
+ *error = zbx_strdcatf(*error, "Cannot %s %s tag: \"%s: %s\" already exists.\n",
+ ZBX_TAG_OP(left), owner, left->tag, right->value);
+ }
+
+ zbx_db_tag_free(left);
+ zbx_vector_db_tag_ptr_remove_noorder(tags, i--);
+
+ ret = FAIL;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/******************************************************************************
+ * *
+ * Purpose: merge new tags into existing *
+ * *
+ * Parameters: dst - [IN/OUT] vector of existing tags *
+ * src - [IN/OUT] vector or new tags *
+ * owner - [IN] the tag owner (host, item, trigger), *
+ * optional - must be specified if error parameter *
+ * is not null *
+ * error - [IN,OUT] the error message (appended to existing), *
+ * optional *
+ * *
+ * Comments: The tags are merged using the following logic: *
+ * 1) tags with matching name+value are left as it is *
+ * 2) tags with matching names will have their values updated *
+ * 3) tags without matches will have: *
+ * a) their name and value updated if there are new tags left *
+ * b) flagged to be removed otherwise *
+ * 4) all leftover new tags will be created *
+ * *
+ * Return value: SUCCEED - tags were merged without issues *
+ * FAIL - tags were merged with errors *
+ * *
+ ******************************************************************************/
+int zbx_merge_tags(zbx_vector_db_tag_ptr_t *dst, zbx_vector_db_tag_ptr_t *src, const char *owner, char **error)
+{
+ int i, j, ret;
+
+ zabbix_log(LOG_LEVEL_DEBUG, "In %s() old_tags:%d new_tags:%d", __func__, dst->values_num, src->values_num);
+
+ ret = check_duplicate_tags(src, owner, error);
+
+ /* perform exact tag + value match */
+ for (i = 0; i < dst->values_num; i++)
+ {
+ for (j = 0; j < src->values_num; j++)
+ {
+ if (0 == strcmp(dst->values[i]->tag, src->values[j]->tag) &&
+ 0 == strcmp(dst->values[i]->value, src->values[j]->value))
+ {
+ break;
+ }
+ }
+
+ if (j != src->values_num)
+ {
+ zbx_db_tag_free(src->values[j]);
+ zbx_vector_db_tag_ptr_remove_noorder(src, j);
+ continue;
+ }
+
+ dst->values[i]->flags = ZBX_FLAG_DB_TAG_REMOVE;
+ }
+
+ if (0 == src->values_num)
+ goto out;
+
+ /* perform tag match */
+ for (i = 0; i < dst->values_num; i++)
+ {
+ if (ZBX_FLAG_DB_TAG_REMOVE != dst->values[i]->flags)
+ continue;
+
+ for (j = 0; j < src->values_num; j++)
+ {
+ if (0 == strcmp(dst->values[i]->tag, src->values[j]->tag))
+ break;
+ }
+
+ if (j != src->values_num)
+ {
+ dst->values[i]->value_orig = dst->values[i]->value;
+ dst->values[i]->value = src->values[j]->value;
+ dst->values[i]->flags = ZBX_FLAG_DB_TAG_UPDATE_VALUE;
+ src->values[j]->value = NULL;
+ zbx_db_tag_free(src->values[j]);
+ zbx_vector_db_tag_ptr_remove_noorder(src, j);
+ continue;
+ }
+ }
+
+ if (0 == src->values_num)
+ goto out;
+
+ /* update rest of the tags */
+ for (i = 0; i < dst->values_num && 0 < src->values_num; i++)
+ {
+ if (ZBX_FLAG_DB_TAG_REMOVE != dst->values[i]->flags)
+ continue;
+
+ dst->values[i]->tag_orig = dst->values[i]->tag;
+ dst->values[i]->value_orig = dst->values[i]->value;
+ dst->values[i]->tag = src->values[0]->tag;
+ dst->values[i]->value = src->values[0]->value;
+ dst->values[i]->flags = ZBX_FLAG_DB_TAG_UPDATE_TAG | ZBX_FLAG_DB_TAG_UPDATE_VALUE;
+ src->values[0]->tag = NULL;
+ src->values[0]->value = NULL;
+ zbx_db_tag_free(src->values[0]);
+ zbx_vector_db_tag_ptr_remove_noorder(src, 0);
+ }
+
+ /* add leftover new tags */
+ zbx_vector_db_tag_ptr_append_array(dst, src->values, src->values_num);
+ zbx_vector_db_tag_ptr_clear(src);
+out:
+ if (SUCCEED != check_tag_fields(dst, owner, error))
+ ret = FAIL;
+
+ zbx_vector_db_tag_ptr_sort(dst, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
+
+ zabbix_log(LOG_LEVEL_DEBUG, "End of %s() tags:%d", __func__, dst->values_num);
+
+ return ret;
+}
diff --git a/src/libs/zbxdbhigh/template.h b/src/libs/zbxdbhigh/template.h
index 737e203fd59..aeae77e1309 100644
--- a/src/libs/zbxdbhigh/template.h
+++ b/src/libs/zbxdbhigh/template.h
@@ -28,8 +28,6 @@
typedef struct _zbx_template_item_preproc_t zbx_template_item_preproc_t;
ZBX_PTR_VECTOR_DECL(item_preproc_ptr, zbx_template_item_preproc_t *)
-ZBX_PTR_VECTOR_DECL(item_tag_ptr, zbx_db_tag_t *)
-
typedef struct _zbx_template_item_param_t zbx_template_item_param_t;
ZBX_PTR_VECTOR_DECL(item_param_ptr, zbx_template_item_param_t *)
@@ -190,8 +188,8 @@ typedef struct
zbx_vector_ptr_t dependent_items;
zbx_vector_item_preproc_ptr_t item_preprocs;
zbx_vector_item_preproc_ptr_t template_preprocs;
- zbx_vector_item_tag_ptr_t item_tags;
- zbx_vector_item_tag_ptr_t template_tags;
+ zbx_vector_db_tag_ptr_t item_tags;
+ zbx_vector_db_tag_ptr_t template_tags;
zbx_vector_item_param_ptr_t item_params;
zbx_vector_item_param_ptr_t template_params;
zbx_vector_lld_macro_ptr_t item_lld_macros;
diff --git a/src/libs/zbxdbhigh/template_item.c b/src/libs/zbxdbhigh/template_item.c
index 863dd105dc1..cd095ef3834 100644
--- a/src/libs/zbxdbhigh/template_item.c
+++ b/src/libs/zbxdbhigh/template_item.c
@@ -57,8 +57,6 @@ struct _zbx_template_item_preproc_t
ZBX_PTR_VECTOR_IMPL(item_preproc_ptr, zbx_template_item_preproc_t *)
-ZBX_PTR_VECTOR_IMPL(item_tag_ptr, zbx_db_tag_t *)
-
struct _zbx_template_item_param_t
{
zbx_uint64_t item_parameterid;
@@ -505,8 +503,8 @@ static void get_template_items(zbx_uint64_t hostid, const zbx_vector_uint64_t *t
zbx_vector_ptr_create(&item->dependent_items);
zbx_vector_item_preproc_ptr_create(&item->item_preprocs);
zbx_vector_item_preproc_ptr_create(&item->template_preprocs);
- zbx_vector_item_tag_ptr_create(&item->item_tags);
- zbx_vector_item_tag_ptr_create(&item->template_tags);
+ zbx_vector_db_tag_ptr_create(&item->item_tags);
+ zbx_vector_db_tag_ptr_create(&item->template_tags);
zbx_vector_item_param_ptr_create(&item->item_params);
zbx_vector_item_param_ptr_create(&item->template_params);
zbx_vector_lld_macro_ptr_create(&item->item_lld_macros);
@@ -1399,16 +1397,16 @@ static void free_template_item(zbx_template_item_t *item)
zbx_vector_ptr_destroy(&item->dependent_items);
zbx_vector_item_preproc_ptr_clear_ext(&item->item_preprocs, zbx_item_preproc_free);
zbx_vector_item_preproc_ptr_clear_ext(&item->template_preprocs, zbx_item_preproc_free);
- zbx_vector_item_tag_ptr_clear_ext(&item->item_tags, zbx_db_tag_free);
- zbx_vector_item_tag_ptr_clear_ext(&item->template_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_clear_ext(&item->item_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_clear_ext(&item->template_tags, zbx_db_tag_free);
zbx_vector_item_param_ptr_clear_ext(&item->item_params, zbx_item_params_free);
zbx_vector_item_param_ptr_clear_ext(&item->template_params, zbx_item_params_free);
zbx_vector_lld_macro_ptr_clear_ext(&item->item_lld_macros, zbx_lld_macros_free);
zbx_vector_lld_macro_ptr_clear_ext(&item->template_lld_macros, zbx_lld_macros_free);
zbx_vector_item_preproc_ptr_destroy(&item->item_preprocs);
zbx_vector_item_preproc_ptr_destroy(&item->template_preprocs);
- zbx_vector_item_tag_ptr_destroy(&item->item_tags);
- zbx_vector_item_tag_ptr_destroy(&item->template_tags);
+ zbx_vector_db_tag_ptr_destroy(&item->item_tags);
+ zbx_vector_db_tag_ptr_destroy(&item->template_tags);
zbx_vector_item_param_ptr_destroy(&item->item_params);
zbx_vector_item_param_ptr_destroy(&item->template_params);
zbx_vector_lld_macro_ptr_destroy(&item->item_lld_macros);
@@ -1821,6 +1819,8 @@ static void copy_template_item_tags(const zbx_vector_ptr_t *items)
if (0 != deleteids.values_num)
{
+ zbx_vector_uint64_sort(&deleteids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
sql_offset = 0;
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from item_tag where");
DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemtagid", deleteids.values,
@@ -2882,7 +2882,7 @@ static void link_template_items_tag(const zbx_vector_uint64_t *templateids, zbx_
char *sql = NULL;
size_t sql_alloc = 0, sql_offset = 0;
zbx_uint64_t itemid;
- zbx_db_tag_t *ptsrc, *ptdst;
+ zbx_db_tag_t *db_tag;
zbx_template_item_t *item;
zbx_hashset_t items_t;
zbx_vector_uint64_t itemids;
@@ -2926,9 +2926,9 @@ static void link_template_items_tag(const zbx_vector_uint64_t *templateids, zbx_
}
item = (zbx_template_item_t *)items->values[index];
- ptdst = zbx_db_tag_create(row[2], row[3]);
- ZBX_STR2UINT64(ptdst->tagid, row[0]);
- zbx_vector_item_tag_ptr_append(&item->item_tags, ptdst);
+ db_tag = zbx_db_tag_create(row[2], row[3]);
+ ZBX_STR2UINT64(db_tag->tagid, row[0]);
+ zbx_vector_db_tag_ptr_append(&item->item_tags, db_tag);
}
DBfree_result(result);
@@ -2938,7 +2938,7 @@ static void link_template_items_tag(const zbx_vector_uint64_t *templateids, zbx_
}
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- "select it.itemtagid,it.itemid,it.tag,it.value"
+ "select it.itemid,it.tag,it.value"
" from item_tag it,items ti"
" where it.itemid=ti.itemid"
" and");
@@ -2950,7 +2950,7 @@ static void link_template_items_tag(const zbx_vector_uint64_t *templateids, zbx_
{
zbx_template_item_t item_local, *pitem_local = &item_local, **pitem;
- ZBX_STR2UINT64(item_local.templateid, row[1]);
+ ZBX_STR2UINT64(item_local.templateid, row[0]);
if (NULL == (pitem = (zbx_template_item_t **)zbx_hashset_search(&items_t, &pitem_local)))
{
@@ -2958,70 +2958,16 @@ static void link_template_items_tag(const zbx_vector_uint64_t *templateids, zbx_
continue;
}
- ptdst = zbx_db_tag_create(row[2], row[3]);
- ZBX_STR2UINT64(ptdst->tagid, row[0]);
- zbx_vector_item_tag_ptr_append(&(*pitem)->template_tags, ptdst);
+ db_tag = zbx_db_tag_create(row[1], row[2]);
+ zbx_vector_db_tag_ptr_append(&(*pitem)->template_tags, db_tag);
}
DBfree_result(result);
zbx_free(sql);
for (i = 0; i < items->values_num; i++)
{
- int j, tag_num;
- char *buffer = NULL;
-
item = (zbx_template_item_t *)items->values[i];
-
- zbx_vector_item_tag_ptr_sort(&item->item_tags, zbx_db_tag_compare_func_template);
- zbx_vector_item_tag_ptr_sort(&item->template_tags, zbx_db_tag_compare_func_template);
-
- tag_num = MAX(item->item_tags.values_num, item->template_tags.values_num);
-
- for (j = 0; j < tag_num; j++)
- {
- if (j >= item->item_tags.values_num)
- {
- ptsrc = (zbx_db_tag_t *)item->template_tags.values[j];
- ptdst = zbx_db_tag_create(ptsrc->tag, ptsrc->value);
- ptdst->tagid = 0;
- zbx_vector_item_tag_ptr_append(&item->item_tags, ptdst);
- continue;
- }
-
- ptdst = (zbx_db_tag_t *)item->item_tags.values[j];
-
- if (j >= item->template_tags.values_num)
- {
- ptdst->flags |= ZBX_FLAG_DB_TAG_REMOVE;
- continue;
- }
-
- ptsrc = (zbx_db_tag_t *)item->template_tags.values[j];
-
- buffer = zbx_strdup(buffer, ptsrc->tag);
-
- if (0 != strcmp(ptdst->tag, buffer))
- {
- ptdst->tag_orig = zbx_strdup(NULL, ptdst->tag);
- zbx_free(ptdst->tag);
- ptdst->tag = buffer;
- buffer = NULL;
- ptdst->flags |= ZBX_FLAG_DB_TAG_UPDATE_TAG;
- }
-
- buffer = zbx_strdup(buffer, ptsrc->value);
-
- if (0 != strcmp(ptdst->value, buffer))
- {
- ptdst->value_orig = zbx_strdup(NULL, ptdst->value);
- zbx_free(ptdst->value);
- ptdst->value = buffer;
- buffer = NULL;
- ptdst->flags |= ZBX_FLAG_DB_TAG_UPDATE_VALUE;
- }
- else
- zbx_free(buffer);
- }
+ (void)zbx_merge_tags(&item->item_tags, &item->template_tags, NULL, NULL);
}
zbx_hashset_destroy(&items_t);
zbx_vector_uint64_destroy(&itemids);
diff --git a/src/libs/zbxdbhigh/trigger_linking.c b/src/libs/zbxdbhigh/trigger_linking.c
index 09023346bc6..1b90d5a2fe8 100644
--- a/src/libs/zbxdbhigh/trigger_linking.c
+++ b/src/libs/zbxdbhigh/trigger_linking.c
@@ -280,21 +280,38 @@ static void zbx_triggers_descriptions_clean(zbx_hashset_t *x)
typedef struct
{
- zbx_uint64_t triggerid;
- char *tag;
- char *value;
- int flags;
+ zbx_uint64_t triggerid;
+ unsigned char flags;
+ zbx_vector_db_tag_ptr_t tags;
+ zbx_vector_db_tag_ptr_t new_tags;
}
-zbx_trigger_tag_insert_temp_t;
+zbx_trigger_tags_t;
-ZBX_PTR_VECTOR_DECL(trigger_tag_insert_temps, zbx_trigger_tag_insert_temp_t *)
-ZBX_PTR_VECTOR_IMPL(trigger_tag_insert_temps, zbx_trigger_tag_insert_temp_t *)
+ZBX_PTR_VECTOR_DECL(trigger_tags, zbx_trigger_tags_t *)
+ZBX_PTR_VECTOR_IMPL(trigger_tags, zbx_trigger_tags_t *)
-static void trigger_tag_insert_temp_free(zbx_trigger_tag_insert_temp_t *trigger_tag_insert_temp)
+static zbx_trigger_tags_t *trigger_tags_create(zbx_uint64_t triggerid, unsigned char flags)
{
- zbx_free(trigger_tag_insert_temp->tag);
- zbx_free(trigger_tag_insert_temp->value);
- zbx_free(trigger_tag_insert_temp);
+ zbx_trigger_tags_t *trigger_tags;
+
+ trigger_tags = (zbx_trigger_tags_t *)zbx_malloc(NULL, sizeof(zbx_trigger_tags_t));
+ trigger_tags->triggerid = triggerid;
+ trigger_tags->flags = flags;
+ zbx_vector_db_tag_ptr_create(&trigger_tags->tags);
+ zbx_vector_db_tag_ptr_create(&trigger_tags->new_tags);
+
+ return trigger_tags;
+}
+
+static void trigger_tags_free(zbx_trigger_tags_t *trigger_tags)
+{
+ zbx_vector_db_tag_ptr_clear_ext(&trigger_tags->tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&trigger_tags->tags);
+
+ zbx_vector_db_tag_ptr_clear_ext(&trigger_tags->new_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&trigger_tags->new_tags);
+
+ zbx_free(trigger_tags);
}
/********************************************************************************
@@ -310,14 +327,18 @@ static void trigger_tag_insert_temp_free(zbx_trigger_tag_insert_temp_t *trigger_
static int DBcopy_template_trigger_tags(const zbx_vector_uint64_t *new_triggerids,
const zbx_vector_uint64_t *cur_triggerids)
{
- DB_RESULT result;
- DB_ROW row;
- char *sql = NULL;
- size_t sql_alloc = 0, sql_offset = 0;
- int i, ret = SUCCEED;
- zbx_vector_uint64_t triggerids;
- zbx_db_insert_t db_insert;
- zbx_vector_trigger_tag_insert_temps_t trigger_tag_insert_temps;
+ DB_RESULT result;
+ DB_ROW row;
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ int i, j, ret = SUCCEED, insert_num = 0, update_num = 0, delete_num = 0;
+ zbx_db_insert_t db_insert;
+ zbx_vector_uint64_t triggerids, del_tagids;
+ zbx_vector_trigger_tags_t triggers_tags;
+ zbx_trigger_tags_t *trigger_tags = NULL;
+ zbx_uint64_t triggerid, tagid;
+ zbx_db_tag_t *db_tag;
+
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
@@ -326,61 +347,53 @@ static int DBcopy_template_trigger_tags(const zbx_vector_uint64_t *new_triggerid
zbx_vector_uint64_create(&triggerids);
zbx_vector_uint64_reserve(&triggerids, (size_t)(new_triggerids->values_num + cur_triggerids->values_num));
- zbx_vector_trigger_tag_insert_temps_create(&trigger_tag_insert_temps);
+ zbx_vector_uint64_append_array(&triggerids, new_triggerids->values, new_triggerids->values_num);
+ zbx_vector_uint64_append_array(&triggerids, cur_triggerids->values, cur_triggerids->values_num);
+ zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- if (0 != cur_triggerids->values_num)
- {
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- "select tt.triggertagid,tt.triggerid,t.flags"
- " from trigger_tag tt,triggers t"
- " where tt.triggerid=t.triggerid and ");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.triggerid", cur_triggerids->values,
- cur_triggerids->values_num);
-
- if (NULL == (result = DBselect("%s", sql)))
- {
- ret = FAIL;
- goto clean;
- }
+ zbx_vector_trigger_tags_create(&triggers_tags);
+ zbx_vector_trigger_tags_reserve(&triggers_tags, (size_t)triggerids.values_alloc);
- while (NULL != (row = DBfetch(result)))
- {
- zbx_uint64_t audit_del_triggerid, audit_del_triggertagid;
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
+ "select tt.triggertagid,t.triggerid,t.flags,tt.tag,tt.value"
+ " from triggers t"
+ " left join trigger_tag tt on tt.triggerid=t.triggerid"
+ " where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "t.triggerid", triggerids.values,
+ triggerids.values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by t.triggerid");
- ZBX_STR2UINT64(audit_del_triggerid, row[1]);
- ZBX_STR2UINT64(audit_del_triggertagid, row[0]);
+ if (NULL == (result = DBselect("%s", sql)))
+ {
+ ret = FAIL;
+ goto clean;
+ }
- zbx_audit_trigger_update_json_delete_tags(audit_del_triggerid, atoi(row[2]),
- audit_del_triggertagid);
- }
+ while (NULL != (row = DBfetch(result)))
+ {
+ ZBX_STR2UINT64(triggerid, row[1]);
- sql_offset = 0;
- DBfree_result(result);
+ if (NULL == trigger_tags || trigger_tags->triggerid != triggerid)
+ {
+ unsigned char flags;
- /* remove tags from host triggers that were linked to template triggers */
- zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from trigger_tag where");
- DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggerid", cur_triggerids->values,
- cur_triggerids->values_num);
+ ZBX_STR2UCHAR(flags, row[2]);
+ trigger_tags = trigger_tags_create(triggerid, flags);
+ zbx_vector_trigger_tags_append(&triggers_tags, trigger_tags);
+ }
- if (ZBX_DB_OK > DBexecute("%s", sql))
+ if (SUCCEED != DBis_null(row[3]))
{
- ret = FAIL;
- goto clean;
+ db_tag = zbx_db_tag_create(row[3], row[4]);
+ ZBX_DBROW2UINT64(db_tag->tagid, row[0]);
+ zbx_vector_db_tag_ptr_append(&trigger_tags->tags, db_tag);
}
-
- sql_offset = 0;
-
- for (i = 0; i < cur_triggerids->values_num; i++)
- zbx_vector_uint64_append(&triggerids, cur_triggerids->values[i]);
}
+ DBfree_result(result);
- for (i = 0; i < new_triggerids->values_num; i++)
- zbx_vector_uint64_append(&triggerids, new_triggerids->values[i]);
-
- zbx_vector_uint64_sort(&triggerids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
-
+ sql_offset = 0;
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
- "select t.triggerid,tt.tag,tt.value,t.flags"
+ "select t.triggerid,tt.tag,tt.value"
" from trigger_tag tt,triggers t"
" where tt.triggerid=t.templateid"
" and");
@@ -395,54 +408,165 @@ static int DBcopy_template_trigger_tags(const zbx_vector_uint64_t *new_triggerid
while (NULL != (row = DBfetch(result)))
{
- zbx_trigger_tag_insert_temp_t *zbx_trigger_tag_insert_temp;
-
- zbx_trigger_tag_insert_temp = (zbx_trigger_tag_insert_temp_t *)zbx_malloc(NULL,
- sizeof(zbx_trigger_tag_insert_temp_t));
- ZBX_STR2UINT64(zbx_trigger_tag_insert_temp->triggerid, row[0]);
- zbx_trigger_tag_insert_temp->tag = zbx_strdup(NULL, row[1]);
- zbx_trigger_tag_insert_temp->value = zbx_strdup(NULL, row[2]);
- zbx_trigger_tag_insert_temp->flags = atoi(row[3]);
- zbx_vector_trigger_tag_insert_temps_append(&trigger_tag_insert_temps, zbx_trigger_tag_insert_temp);
+ zbx_trigger_tags_t trigger_tags_local;
+
+ ZBX_STR2UINT64(trigger_tags_local.triggerid, row[0]);
+
+ if (FAIL == (i = zbx_vector_trigger_tags_bsearch(&triggers_tags, &trigger_tags_local,
+ ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ continue;
+ }
+
+ zbx_vector_db_tag_ptr_append(&triggers_tags.values[i]->new_tags, zbx_db_tag_create(row[1], row[2]));
+ }
+ DBfree_result(result);
+
+ for (i = 0; i < triggers_tags.values_num; i++)
+ {
+ trigger_tags = triggers_tags.values[i];
+ (void)zbx_merge_tags(&trigger_tags->tags, &trigger_tags->new_tags, NULL, NULL);
+
+ for (j = 0; j < trigger_tags->tags.values_num; j++)
+ {
+ db_tag = trigger_tags->tags.values[j];
+
+ if (0 == db_tag->tagid)
+ insert_num++;
+ else if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
+ update_num++;
+ else if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
+ delete_num++;
+ }
}
- if (0 < trigger_tag_insert_temps.values_num)
+ if (0 == insert_num && 0 == update_num && 0 == delete_num)
+ goto clean;
+
+ if (0 != update_num)
{
- zbx_uint64_t triggertagid;
+ sql_offset = 0;
+ DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
+ }
- triggertagid = DBget_maxid_num("trigger_tag", trigger_tag_insert_temps.values_num);
+ if (0 != insert_num)
+ {
zbx_db_insert_prepare(&db_insert, "trigger_tag", "triggertagid", "triggerid", "tag", "value", NULL);
+ tagid = DBget_maxid_num("trigger_tag", insert_num);
+ }
- for (i = 0; i < trigger_tag_insert_temps.values_num; i++)
+ if (0 != delete_num)
+ {
+ zbx_vector_uint64_create(&del_tagids);
+ zbx_vector_uint64_reserve(&del_tagids, (size_t)delete_num);
+ }
+
+ for (i = 0; i < triggers_tags.values_num; i++)
+ {
+ trigger_tags = triggers_tags.values[i];
+
+ for (j = 0; j < trigger_tags->tags.values_num; j++)
{
- zbx_db_insert_add_values(&db_insert, triggertagid,
- trigger_tag_insert_temps.values[i]->triggerid,
- trigger_tag_insert_temps.values[i]->tag,
- trigger_tag_insert_temps.values[i]->value);
+ const char *d = "";
+
+ db_tag = trigger_tags->tags.values[j];
- zbx_audit_trigger_update_json_add_tags_and_values(trigger_tag_insert_temps.values[i]->triggerid,
- trigger_tag_insert_temps.values[i]->flags,
- triggertagid, trigger_tag_insert_temps.values[i]->tag,
- trigger_tag_insert_temps.values[i]->value);
+ if (0 == db_tag->tagid)
+ {
+ zbx_db_insert_add_values(&db_insert, tagid, trigger_tags->triggerid,
+ db_tag->tag, db_tag->value);
+
+ zbx_audit_trigger_update_json_add_tags_and_values(trigger_tags->triggerid,
+ trigger_tags->flags, tagid, db_tag->tag, db_tag->value);
+
+ tagid++;
+ }
+ else if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
+ {
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update trigger_tag set ");
+
+ zbx_audit_trigger_update_json_update_trigger_tag_create_entry(trigger_tags->triggerid,
+ trigger_tags->flags, db_tag->tagid);
+
+ if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_UPDATE_TAG))
+ {
+ char *tag_esc;
+
+ tag_esc = DBdyn_escape_string(db_tag->tag);
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stag='%s'", d, tag_esc);
+
+ d = ",";
+ zbx_free(tag_esc);
+
+ zbx_audit_trigger_update_json_update_tag_tag(trigger_tags->triggerid,
+ trigger_tags->flags, db_tag->tagid, db_tag->tag_orig,
+ db_tag->tag);
+
+ }
- triggertagid++;
+ if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_UPDATE_VALUE))
+ {
+ char *value_esc;
+
+ value_esc = DBdyn_escape_string(db_tag->value);
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%svalue='%s'", d, value_esc);
+ zbx_free(value_esc);
+
+ zbx_audit_trigger_update_json_update_tag_value(trigger_tags->triggerid,
+ trigger_tags->flags, db_tag->tagid, db_tag->value_orig,
+ db_tag->value);
+ }
+
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where triggertagid=" ZBX_FS_UI64
+ ";\n", db_tag->tagid);
+
+ DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
+ }
+ else if (0 != (db_tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
+ {
+ zbx_vector_uint64_append(&del_tagids, db_tag->tagid);
+
+ zbx_audit_trigger_update_json_delete_tags(trigger_tags->triggerid, trigger_tags->flags,
+ db_tag->tagid);
+ }
}
}
- DBfree_result(result);
+ if (0 != update_num)
+ {
+ DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
- zbx_free(sql);
+ if (16 < sql_offset) /* in ORACLE always present begin..end; */
+ DBexecute("%s", sql);
+ }
- if (0 < trigger_tag_insert_temps.values_num)
+ if (0 != insert_num)
{
- zbx_db_insert_autoincrement(&db_insert, "triggertagid");
zbx_db_insert_execute(&db_insert);
zbx_db_insert_clean(&db_insert);
}
+
+ if (0 != delete_num)
+ {
+ zbx_vector_uint64_sort(&del_tagids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
+
+ sql_offset = 0;
+ zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "delete from trigger_tag where");
+ DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "triggertagid", del_tagids.values,
+ del_tagids.values_num);
+ DBexecute("%s", sql);
+
+ zbx_vector_uint64_destroy(&del_tagids);
+ }
+
clean:
- zbx_vector_trigger_tag_insert_temps_clear_ext(&trigger_tag_insert_temps, trigger_tag_insert_temp_free);
- zbx_vector_trigger_tag_insert_temps_destroy(&trigger_tag_insert_temps);
+ zbx_free(sql);
zbx_vector_uint64_destroy(&triggerids);
+
+ zbx_vector_trigger_tags_clear_ext(&triggers_tags, trigger_tags_free);
+ zbx_vector_trigger_tags_destroy(&triggers_tags);
+
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%s", __func__, zbx_result_string(ret));
diff --git a/src/zabbix_server/lld/lld.h b/src/zabbix_server/lld/lld.h
index c86f096c949..57abcb8c336 100644
--- a/src/zabbix_server/lld/lld.h
+++ b/src/zabbix_server/lld/lld.h
@@ -89,7 +89,7 @@ typedef struct
zbx_vector_ptr_t lld_rows;
zbx_vector_ptr_t preproc_ops;
zbx_vector_ptr_t item_params;
- zbx_vector_ptr_t item_tags;
+ zbx_vector_db_tag_ptr_t item_tags;
}
zbx_lld_item_prototype_t;
@@ -198,7 +198,7 @@ typedef struct
zbx_vector_ptr_t preproc_ops;
zbx_vector_ptr_t dependent_items;
zbx_vector_ptr_t item_params;
- zbx_vector_ptr_t item_tags;
+ zbx_vector_db_tag_ptr_t item_tags;
zbx_vector_db_tag_ptr_t override_tags;
unsigned char status;
unsigned char type_orig;
diff --git a/src/zabbix_server/lld/lld_host.c b/src/zabbix_server/lld/lld_host.c
index f87b9e92c93..fbec72bd1d3 100644
--- a/src/zabbix_server/lld/lld_host.c
+++ b/src/zabbix_server/lld/lld_host.c
@@ -302,7 +302,7 @@ typedef struct
zbx_lld_group_rights_t;
static void lld_host_update_tags(zbx_lld_host_t *host, const zbx_vector_db_tag_ptr_t *tags,
- const zbx_vector_ptr_t *lld_macros, char **info);
+ const zbx_vector_ptr_t *lld_macros, char **error);
typedef struct
{
@@ -820,7 +820,7 @@ static void lld_hosts_validate(zbx_vector_ptr_t *hosts, char **error)
static zbx_lld_host_t *lld_host_make(zbx_vector_ptr_t *hosts, const char *host_proto, const char *name_proto,
signed char inventory_mode_proto, unsigned char status_proto, unsigned char discover_proto,
zbx_vector_db_tag_ptr_t *tags, const zbx_lld_row_t *lld_row, const zbx_vector_ptr_t *lld_macros,
- char **info, unsigned char custom_iface)
+ unsigned char custom_iface, char **error)
{
char *buffer = NULL;
int i, host_found = 0;
@@ -968,7 +968,7 @@ static zbx_lld_host_t *lld_host_make(zbx_vector_ptr_t *hosts, const char *host_p
if (0 != (host->flags & ZBX_FLAG_LLD_HOST_DISCOVERED))
{
zbx_vector_db_tag_ptr_append_array(&tmp_tags, tags->values, tags->values_num);
- lld_host_update_tags(host, &tmp_tags, lld_macros, info);
+ lld_host_update_tags(host, &tmp_tags, lld_macros, error);
if (0 != lnk_templateids.values_num)
{
@@ -2210,80 +2210,6 @@ static void lld_proto_tags_get(zbx_uint64_t parent_hostid, zbx_vector_db_tag_ptr
/******************************************************************************
* *
- * Purpose: validate host tag field *
- * *
- * Parameters: name - [IN] the field name (tag, value) *
- * field - [IN] the field value *
- * field_len - [IN] the field length *
- * info - [OUT] error information *
- * *
- ******************************************************************************/
-static int lld_tag_validate_field(const char *name, const char *field, size_t field_len, char **info)
-{
- if (SUCCEED != zbx_is_utf8(field))
- {
- char *field_utf8;
-
- field_utf8 = zbx_strdup(NULL, field);
- zbx_replace_invalid_utf8(field_utf8);
- *info = zbx_strdcatf(*info, "Cannot create host tag: %s \"%s\" has invalid UTF-8 sequence.\n",
- name, field_utf8);
- zbx_free(field_utf8);
- return FAIL;
- }
-
- if (zbx_strlen_utf8(field) > field_len)
- {
- *info = zbx_strdcatf(*info, "Cannot create host tag: %s \"%128s...\" is too long.\n", name, field);
- return FAIL;
- }
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
- * Purpose: validate host tag *
- * *
- * Parameters: tags - [IN] the current host tags *
- * tags_num - [IN] the number of host tags *
- * name - [IN] the new tag name *
- * value - [IN] the new tag value *
- * info - [OUT] error information *
- * *
- ******************************************************************************/
-static int lld_tag_validate(zbx_db_tag_t **tags, int tags_num, const char *name, const char *value, char **info)
-{
- int i;
-
- if ('\0' == *name)
- {
- *info = zbx_strdcatf(*info, "Cannot create host tag: empty tag name.\n");
- return FAIL;
- }
-
- if (SUCCEED != lld_tag_validate_field("name", name, TAG_NAME_LEN, info))
- return FAIL;
-
- if (SUCCEED != lld_tag_validate_field("value", value, TAG_VALUE_LEN, info))
- return FAIL;
-
- for (i = 0; i < tags_num; i++)
- {
- if (0 == strcmp(tags[i]->tag, name) && 0 == strcmp(tags[i]->value, value))
- {
- *info = zbx_strdcatf(*info, "Cannot create host tag: tag \"%s\",\"%s\" already exists.\n",
- name, value);
-
- return FAIL;
- }
- }
-
- return SUCCEED;
-}
-
-/******************************************************************************
- * *
* Purpose: update host tags *
* *
* Parameters: host - [IN] a host with existing tags, sorted by tag + *
@@ -2301,10 +2227,10 @@ static int lld_tag_validate(zbx_db_tag_t **tags, int tags_num, const char *name,
* *
******************************************************************************/
static void lld_host_update_tags(zbx_lld_host_t *host, const zbx_vector_db_tag_ptr_t *tags,
- const zbx_vector_ptr_t *lld_macros, char **info)
+ const zbx_vector_ptr_t *lld_macros, char **error)
{
int i;
- zbx_db_tag_t *host_tag, *proto_tag;
+ zbx_db_tag_t *proto_tag;
zbx_vector_db_tag_ptr_t new_tags;
char *tag = NULL, *value = NULL;
@@ -2320,9 +2246,6 @@ static void lld_host_update_tags(zbx_lld_host_t *host, const zbx_vector_db_tag_p
substitute_lld_macros(&tag, host->jp_row, lld_macros, ZBX_MACRO_FUNC, NULL, 0);
substitute_lld_macros(&value, host->jp_row, lld_macros, ZBX_MACRO_FUNC, NULL, 0);
- if (SUCCEED != lld_tag_validate(new_tags.values, new_tags.values_num, tag, value, info))
- continue;
-
proto_tag = zbx_db_tag_create(tag, value);
zbx_vector_db_tag_ptr_append(&new_tags, proto_tag);
@@ -2330,51 +2253,13 @@ static void lld_host_update_tags(zbx_lld_host_t *host, const zbx_vector_db_tag_p
zbx_free(value);
}
- zbx_vector_db_tag_ptr_sort(&new_tags, zbx_db_tag_compare_func);
-
- zbx_vector_db_tag_ptr_reserve(&host->tags, (size_t)new_tags.values_num);
-
- /* update host tags or flag them for removal */
- for (i = 0; i < host->tags.values_num; i++)
- {
- host_tag = (zbx_db_tag_t *)host->tags.values[i];
- if (i < new_tags.values_num)
- {
- proto_tag = (zbx_db_tag_t *)new_tags.values[i];
-
- if (0 != strcmp(host_tag->tag, proto_tag->tag))
- {
- host_tag->tag_orig = zbx_strdup(NULL, host_tag->tag);
- host_tag->tag = zbx_strdup(host_tag->tag, proto_tag->tag);
- host_tag->flags |= ZBX_FLAG_DB_TAG_UPDATE_TAG;
- }
-
- if (0 != strcmp(host_tag->value, proto_tag->value))
- {
- host_tag->value_orig = zbx_strdup(NULL, host_tag->value);
- host_tag->value = zbx_strdup(host_tag->value, proto_tag->value);
- host_tag->flags |= ZBX_FLAG_DB_TAG_UPDATE_VALUE;
- }
- }
- else
- host_tag->flags = ZBX_FLAG_DB_TAG_REMOVE;
- }
-
- /* add missing tags */
- if (i < new_tags.values_num)
+ if (SUCCEED != zbx_merge_tags(&host->tags, &new_tags, "host", error))
{
- int j;
-
- /* set uninitialized properties of new tags that will be moved to host */
- for (j = i; j < new_tags.values_num; j++)
+ if (0 == host->hostid)
{
- proto_tag = (zbx_db_tag_t *)new_tags.values[j];
- proto_tag->tagid = 0;
- proto_tag->flags = 0;
+ host->flags &= ~ZBX_FLAG_LLD_HOST_DISCOVERED;
+ *error = zbx_strdcatf(*error, "Cannot create host: tag validation failed.\n");
}
-
- zbx_vector_db_tag_ptr_append_array(&host->tags, new_tags.values + i, new_tags.values_num - i);
- new_tags.values_num = i;
}
zbx_free(tag);
@@ -4541,7 +4426,8 @@ void lld_update_hosts(zbx_uint64_t lld_ruleid, const zbx_vector_ptr_t *lld_rows,
const zbx_lld_row_t *lld_row = (zbx_lld_row_t *)lld_rows->values[i];
if (NULL == (host = lld_host_make(&hosts, host_proto, name_proto, inventory_mode_proto,
- status, discover, &tags, lld_row, lld_macro_paths, error, use_custom_interfaces)))
+ status, discover, &tags, lld_row, lld_macro_paths, use_custom_interfaces,
+ error)))
{
continue;
}
diff --git a/src/zabbix_server/lld/lld_item.c b/src/zabbix_server/lld/lld_item.c
index 2ea606e3c73..8813fc12054 100644
--- a/src/zabbix_server/lld/lld_item.c
+++ b/src/zabbix_server/lld/lld_item.c
@@ -120,24 +120,6 @@ zbx_lld_item_param_t;
#define ZBX_ITEM_TAG_FIELD_TAG 1
#define ZBX_ITEM_TAG_FIELD_VALUE 2
-typedef struct
-{
- zbx_uint64_t item_tagid;
- char *tag;
- char *tag_orig;
- char *value;
- char *value_orig;
-
-#define ZBX_FLAG_LLD_ITEM_TAG_UNSET __UINT64_C(0x00)
-#define ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED __UINT64_C(0x01)
-#define ZBX_FLAG_LLD_ITEM_TAG_UPDATE_TAG __UINT64_C(0x02)
-#define ZBX_FLAG_LLD_ITEM_TAG_UPDATE_VALUE __UINT64_C(0x04)
-#define ZBX_FLAG_LLD_ITEM_TAG_UPDATE \
- (ZBX_FLAG_LLD_ITEM_TAG_UPDATE_TAG | ZBX_FLAG_LLD_ITEM_TAG_UPDATE_VALUE)
- zbx_uint64_t flags;
-}
-zbx_lld_item_tag_t;
-
/* item index by prototype (parent) id and lld row */
typedef struct
{
@@ -206,15 +188,6 @@ static int lld_item_param_sort_by_name(const void *d1, const void *d2)
return 0;
}
-static int lld_item_tag_sort_by_tag(const void *d1, const void *d2)
-{
- zbx_lld_item_tag_t *it1 = *(zbx_lld_item_tag_t **)d1;
- zbx_lld_item_tag_t *it2 = *(zbx_lld_item_tag_t **)d2;
-
- ZBX_RETURN_IF_NOT_EQUAL(it1->tag, it2->tag);
- return 0;
-}
-
static void lld_item_preproc_free(zbx_lld_item_preproc_t *op)
{
zbx_free(op->params);
@@ -237,17 +210,6 @@ static void lld_item_param_free(zbx_lld_item_param_t *param)
zbx_free(param);
}
-static void lld_item_tag_free(zbx_lld_item_tag_t *tag)
-{
- zbx_free(tag->tag);
- if (0 != (tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE_TAG))
- zbx_free(tag->tag_orig);
- zbx_free(tag->value);
- if (0 != (tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE_VALUE))
- zbx_free(tag->value_orig);
- zbx_free(tag);
-}
-
static void lld_item_prototype_free(zbx_lld_item_prototype_t *item_prototype)
{
zbx_free(item_prototype->name);
@@ -287,8 +249,8 @@ static void lld_item_prototype_free(zbx_lld_item_prototype_t *item_prototype)
zbx_vector_ptr_clear_ext(&item_prototype->item_params, (zbx_clean_func_t)lld_item_param_free);
zbx_vector_ptr_destroy(&item_prototype->item_params);
- zbx_vector_ptr_clear_ext(&item_prototype->item_tags, (zbx_clean_func_t)lld_item_tag_free);
- zbx_vector_ptr_destroy(&item_prototype->item_tags);
+ zbx_vector_db_tag_ptr_clear_ext(&item_prototype->item_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&item_prototype->item_tags);
zbx_free(item_prototype);
}
@@ -352,8 +314,8 @@ static void lld_item_free(zbx_lld_item_t *item)
zbx_vector_ptr_destroy(&item->preproc_ops);
zbx_vector_ptr_clear_ext(&item->item_params, (zbx_clean_func_t)lld_item_param_free);
zbx_vector_ptr_destroy(&item->item_params);
- zbx_vector_ptr_clear_ext(&item->item_tags, (zbx_clean_func_t)lld_item_tag_free);
- zbx_vector_ptr_destroy(&item->item_tags);
+ zbx_vector_db_tag_ptr_clear_ext(&item->item_tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&item->item_tags);
zbx_vector_ptr_destroy(&item->dependent_items);
zbx_vector_db_tag_ptr_destroy(&item->override_tags);
@@ -376,7 +338,6 @@ static void lld_items_get(const zbx_vector_ptr_t *item_prototypes, zbx_vector_pt
zbx_lld_item_t *item, *master;
zbx_lld_item_preproc_t *preproc_op;
zbx_lld_item_param_t *item_param;
- zbx_lld_item_tag_t *item_tag;
const zbx_lld_item_prototype_t *item_prototype;
zbx_uint64_t db_valuemapid, db_interfaceid, itemid, master_itemid;
zbx_vector_uint64_t parent_itemids;
@@ -628,7 +589,7 @@ static void lld_items_get(const zbx_vector_ptr_t *item_prototypes, zbx_vector_pt
zbx_vector_ptr_create(&item->preproc_ops);
zbx_vector_ptr_create(&item->dependent_items);
zbx_vector_ptr_create(&item->item_params);
- zbx_vector_ptr_create(&item->item_tags);
+ zbx_vector_db_tag_ptr_create(&item->item_tags);
zbx_vector_db_tag_ptr_create(&item->override_tags);
zbx_vector_ptr_append(items, item);
@@ -756,6 +717,8 @@ static void lld_items_get(const zbx_vector_ptr_t *item_prototypes, zbx_vector_pt
while (NULL != (row = DBfetch(result)))
{
+ zbx_db_tag_t *db_tag;
+
ZBX_STR2UINT64(itemid, row[1]);
if (FAIL == (index = zbx_vector_ptr_bsearch(items, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
@@ -766,14 +729,9 @@ static void lld_items_get(const zbx_vector_ptr_t *item_prototypes, zbx_vector_pt
item = (zbx_lld_item_t *)items->values[index];
- item_tag = (zbx_lld_item_tag_t *)zbx_malloc(NULL, sizeof(zbx_lld_item_tag_t));
- item_tag->flags = ZBX_FLAG_LLD_ITEM_TAG_UNSET;
- ZBX_STR2UINT64(item_tag->item_tagid, row[0]);
- item_tag->tag = zbx_strdup(NULL, row[2]);
- item_tag->tag_orig = NULL;
- item_tag->value = zbx_strdup(NULL, row[3]);
- item_tag->value_orig = NULL;
- zbx_vector_ptr_append(&item->item_tags, item_tag);
+ db_tag = zbx_db_tag_create(row[2], row[3]);
+ ZBX_STR2UINT64(db_tag->tagid, row[0]);
+ zbx_vector_db_tag_ptr_append(&item->item_tags, db_tag);
}
DBfree_result(result);
out:
@@ -834,40 +792,6 @@ static int lld_validate_item_param(zbx_uint64_t itemid, int type, size_t len, ch
return SUCCEED;
}
-static int lld_validate_item_tag(zbx_uint64_t itemid, int type, char *tag, char **error)
-{
- size_t len;
- if (SUCCEED != zbx_is_utf8(tag))
- {
- char *tag_utf8;
-
- tag_utf8 = zbx_strdup(NULL, tag);
- zbx_replace_invalid_utf8(tag_utf8);
- *error = zbx_strdcatf(*error, "Cannot %s item: tag's %s \"%s\" has invalid UTF-8 sequence.\n",
- (0 != itemid ? "update" : "create"),
- (ZBX_ITEM_TAG_FIELD_TAG != type ? "tag" : "value"), tag_utf8);
- zbx_free(tag_utf8);
- return FAIL;
- }
-
- len = zbx_strlen_utf8(tag);
-
- if (ITEM_TAG_FIELD_LEN < len)
- {
- *error = zbx_strdcatf(*error, "Cannot %s item: tag's %s \"%s\" is too long.\n",
- (0 != itemid ? "update" : "create"),
- (ZBX_ITEM_TAG_FIELD_TAG != type ? "tag" : "value"), tag);
- return FAIL;
- }
- else if (0 == len && ZBX_ITEM_TAG_FIELD_TAG == type)
- {
- *error = zbx_strdcatf(*error, "Cannot %s item: empty tag name.\n", (0 != itemid ? "update" : "create"));
- return FAIL;
- }
-
- return SUCCEED;
-}
-
static void lld_validate_item_field(zbx_lld_item_t *item, char **field, char **field_orig, zbx_uint64_t flag,
size_t field_len, char **error)
{
@@ -1640,50 +1564,6 @@ static void lld_items_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *items, zbx
}
}
- /* check item tags for new and updated discovered items */
- for (i = 0; i < items->values_num; i++)
- {
- item = (zbx_lld_item_t *)items->values[i];
-
- if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
- continue;
-
- for (j = 0; j < item->item_tags.values_num; j++)
- {
- zbx_lld_item_tag_t *item_tag = (zbx_lld_item_tag_t *)item->item_tags.values[j], *tag_dup;
- int k;
-
- if (SUCCEED != lld_validate_item_tag(item->itemid, ZBX_ITEM_TAG_FIELD_TAG, item_tag->tag,
- error) || SUCCEED != lld_validate_item_tag(item->itemid,
- ZBX_ITEM_TAG_FIELD_VALUE, item_tag->value, error))
- {
- item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
- break;
- }
-
- if (0 == (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED))
- continue;
-
- /* check for duplicated tag */
- for (k = 0; k < j; k++)
- {
- tag_dup = (zbx_lld_item_tag_t *)item->item_tags.values[k];
-
- if (0 == strcmp(item_tag->tag, tag_dup->tag) &&
- 0 == strcmp(item_tag->value, tag_dup->value))
- {
- item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
- *error = zbx_strdcatf(*error, "Cannot create item tag: tag \"%s\","
- "\"%s\" already exists.\n", item_tag->tag, item_tag->value);
- break;
- }
- }
-
- if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
- break;
- }
- }
-
/* check preprocessing steps for new and updated discovered items */
for (i = 0; i < items->values_num; i++)
{
@@ -2084,7 +1964,7 @@ static zbx_lld_item_t *lld_item_make(const zbx_lld_item_prototype_t *item_protot
zbx_vector_ptr_create(&item->preproc_ops);
zbx_vector_ptr_create(&item->dependent_items);
zbx_vector_ptr_create(&item->item_params);
- zbx_vector_ptr_create(&item->item_tags);
+ zbx_vector_db_tag_ptr_create(&item->item_tags);
if (SUCCEED == ret && ZBX_PROTOTYPE_NO_DISCOVER != discover)
item->flags = ZBX_FLAG_LLD_ITEM_DISCOVERED;
@@ -2867,18 +2747,19 @@ static void lld_items_param_make(const zbx_vector_ptr_t *item_prototypes,
* Parameters: item_prototypes - [IN] the item prototypes *
* lld_macro_paths - [IN] use json path to extract from jp_row *
* items - [IN/OUT] sorted list of items *
+ * error - [OUT] error message *
* *
******************************************************************************/
static void lld_items_tags_make(const zbx_vector_ptr_t *item_prototypes, const zbx_vector_ptr_t *lld_macro_paths,
- zbx_vector_ptr_t *items)
+ zbx_vector_ptr_t *items, char **error)
{
- int i, j, index, item_tag_num;
+ int i, j, index;
zbx_lld_item_t *item;
zbx_lld_item_prototype_t *item_proto;
- zbx_lld_item_tag_t *itsrc, *itdst;
- zbx_db_tag_t *override_tags;
- char *buffer = NULL;
- const char *name, *value;
+ zbx_vector_db_tag_ptr_t new_tags;
+ zbx_db_tag_t *db_tag;
+
+ zbx_vector_db_tag_ptr_create(&new_tags);
for (i = 0; i < items->values_num; i++)
{
@@ -2894,88 +2775,41 @@ static void lld_items_tags_make(const zbx_vector_ptr_t *item_prototypes, const z
continue;
}
- zbx_vector_ptr_sort(&item->item_tags, lld_item_tag_sort_by_tag);
- zbx_vector_db_tag_ptr_sort(&item->override_tags, zbx_db_tag_compare_func);
-
item_proto = (zbx_lld_item_prototype_t *)item_prototypes->values[index];
- item_tag_num = MAX(item->item_tags.values_num,
- item_proto->item_tags.values_num + item->override_tags.values_num);
-
- for (j = 0; j < item_tag_num; j++)
+ for (j = 0; j < item_proto->item_tags.values_num; j++)
{
- if (j < item->item_tags.values_num &&
- j >= item_proto->item_tags.values_num + item->override_tags.values_num)
- {
- itdst = (zbx_lld_item_tag_t *)item->item_tags.values[j];
- itdst->flags &= ~ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED;
- continue;
- }
-
- if (j >= item_proto->item_tags.values_num)
- {
- override_tags = item->override_tags.values[j - item_proto->item_tags.values_num];
- name = override_tags->tag;
- value = override_tags->value;
- }
- else
- {
- itsrc = (zbx_lld_item_tag_t *)item_proto->item_tags.values[j];
- name = itsrc->tag;
- value = itsrc->value;
- }
-
- if (j >= item->item_tags.values_num)
- {
- itdst = (zbx_lld_item_tag_t *)zbx_malloc(NULL, sizeof(zbx_lld_item_tag_t));
- itdst->item_tagid = 0;
- itdst->flags = ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED | ZBX_FLAG_LLD_ITEM_TAG_UPDATE;
- itdst->tag = zbx_strdup(NULL, name);
- itdst->tag_orig = NULL;
- itdst->value = zbx_strdup(NULL, value);
- itdst->value_orig = NULL;
-
- substitute_lld_macros(&itdst->tag, &item->lld_row->jp_row,
- lld_macro_paths, ZBX_MACRO_ANY, NULL, 0);
- substitute_lld_macros(&itdst->value, &item->lld_row->jp_row,
- lld_macro_paths, ZBX_MACRO_ANY, NULL, 0);
-
- zbx_vector_ptr_append(&item->item_tags, itdst);
- continue;
- }
-
- itdst = (zbx_lld_item_tag_t *)item->item_tags.values[j];
- itdst->flags |= ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED;
-
- buffer = zbx_strdup(buffer, name);
- substitute_lld_macros(&buffer, &item->lld_row->jp_row, lld_macro_paths, ZBX_MACRO_ANY, NULL, 0);
+ db_tag = zbx_db_tag_create(item_proto->item_tags.values[j]->tag,
+ item_proto->item_tags.values[j]->value);
+ zbx_vector_db_tag_ptr_append(&new_tags, db_tag);
+ }
- if (0 != strcmp(itdst->tag, buffer))
- {
- itdst->tag_orig = zbx_strdup(NULL, itdst->tag);
- zbx_free(itdst->tag);
- itdst->tag = buffer;
- buffer = NULL;
- itdst->flags |= ZBX_FLAG_LLD_ITEM_PARAM_UPDATE_NAME;
- }
- else
- zbx_free(buffer);
+ for (j = 0; j < item->override_tags.values_num; j++)
+ {
+ db_tag = zbx_db_tag_create(item->override_tags.values[j]->tag,
+ item->override_tags.values[j]->value);
+ zbx_vector_db_tag_ptr_append(&new_tags, db_tag);
+ }
- buffer = zbx_strdup(buffer, value);
- substitute_lld_macros(&buffer, &item->lld_row->jp_row, lld_macro_paths, ZBX_MACRO_ANY, NULL, 0);
+ for (j = 0; j < new_tags.values_num; j++)
+ {
+ substitute_lld_macros(&new_tags.values[j]->tag, &item->lld_row->jp_row, lld_macro_paths,
+ ZBX_MACRO_ANY, NULL, 0);
+ substitute_lld_macros(&new_tags.values[j]->value, &item->lld_row->jp_row, lld_macro_paths,
+ ZBX_MACRO_ANY, NULL, 0);
+ }
- if (0 != strcmp(itdst->value, buffer))
+ if (SUCCEED != zbx_merge_tags(&item->item_tags, &new_tags, "item", error))
+ {
+ if (0 == item->itemid)
{
- itdst->value_orig = zbx_strdup(NULL, itdst->value);
- zbx_free(itdst->value);
- itdst->value = buffer;
- buffer = NULL;
- itdst->flags |= ZBX_FLAG_LLD_ITEM_PARAM_UPDATE_VALUE;
+ item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
+ *error = zbx_strdcatf(*error, "Cannot create item: tag validation failed.\n");
}
- else
- zbx_free(buffer);
}
}
+
+ zbx_vector_db_tag_ptr_destroy(&new_tags);
}
/******************************************************************************
@@ -4101,7 +3935,7 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
{
int ret = SUCCEED, i, j, new_tag_num = 0, update_tag_num = 0, delete_tag_num = 0;
zbx_lld_item_t *item;
- zbx_lld_item_tag_t *item_tag;
+ zbx_db_tag_t *item_tag;
zbx_vector_uint64_t deleteids;
zbx_db_insert_t db_insert;
char *sql = NULL;
@@ -4121,30 +3955,33 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
for (j = 0; j < item->item_tags.values_num; j++)
{
- item_tag = (zbx_lld_item_tag_t *)item->item_tags.values[j];
+ item_tag = item->item_tags.values[j];
- if (0 == (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_DISCOVERED))
+ if (0 != (item_tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
{
- zbx_vector_uint64_append(&deleteids, item_tag->item_tagid);
+ zbx_vector_uint64_append(&deleteids, item_tag->tagid);
zbx_audit_item_delete_tag(item->itemid, (int)ZBX_FLAG_DISCOVERY_CREATED,
- item_tag->item_tagid);
+ item_tag->tagid);
continue;
}
- if (0 == item_tag->item_tagid)
+ if (0 == item_tag->tagid)
{
new_tag_num++;
continue;
}
- if (0 == (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE))
+ if (0 == (item_tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
continue;
update_tag_num++;
}
}
- if (0 == *host_locked && (0 != update_tag_num || 0 != new_tag_num || 0 != deleteids.values_num))
+ if (0 == update_tag_num && 0 == new_tag_num && 0 == deleteids.values_num)
+ goto out;
+
+ if (0 == *host_locked)
{
if (SUCCEED != DBlock_hostid(hostid))
{
@@ -4179,9 +4016,9 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
{
char delim = ' ';
- item_tag = (zbx_lld_item_tag_t *)item->item_tags.values[j];
+ item_tag = item->item_tags.values[j];
- if (0 == item_tag->item_tagid)
+ if (0 == item_tag->tagid)
{
zbx_db_insert_add_values(&db_insert, new_tagid, item->itemid, item_tag->tag,
item_tag->value);
@@ -4191,14 +4028,14 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
continue;
}
- if (0 == (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE))
+ if (0 == (item_tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
continue;
zbx_audit_item_update_json_update_item_tag_create_entry(item->itemid,
- (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->item_tagid);
+ (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->tagid);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update item_tag set");
- if (0 != (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE_TAG))
+ if (0 != (item_tag->flags & ZBX_FLAG_DB_TAG_UPDATE_TAG))
{
char *tag_esc;
@@ -4206,13 +4043,13 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%ctag='%s'", delim, tag_esc);
zbx_audit_item_update_json_update_item_tag_tag(item->itemid,
- (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->item_tagid,
+ (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->tagid,
item_tag->tag_orig, item_tag->tag);
zbx_free(tag_esc);
delim = ',';
}
- if (0 != (item_tag->flags & ZBX_FLAG_LLD_ITEM_TAG_UPDATE_VALUE))
+ if (0 != (item_tag->flags & ZBX_FLAG_DB_TAG_UPDATE_VALUE))
{
char *value_esc;
@@ -4220,14 +4057,14 @@ static int lld_items_tags_save(zbx_uint64_t hostid, zbx_vector_ptr_t *items, int
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cvalue='%s'", delim, value_esc);
zbx_audit_item_update_json_update_item_tag_value(item->itemid,
- (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->item_tagid,
+ (int)ZBX_FLAG_DISCOVERY_CREATED, item_tag->tagid,
item_tag->value_orig, item_tag->value);
zbx_free(value_esc);
}
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemtagid=" ZBX_FS_UI64 ";\n",
- item_tag->item_tagid);
+ item_tag->tagid);
DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
}
@@ -4344,7 +4181,6 @@ static void lld_item_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *i
zbx_lld_item_prototype_t *item_prototype;
zbx_lld_item_preproc_t *preproc_op;
zbx_lld_item_param_t *item_param;
- zbx_lld_item_tag_t *item_tag;
zbx_uint64_t itemid;
int index, i;
@@ -4418,7 +4254,7 @@ static void lld_item_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *i
zbx_vector_ptr_create(&item_prototype->lld_rows);
zbx_vector_ptr_create(&item_prototype->preproc_ops);
zbx_vector_ptr_create(&item_prototype->item_params);
- zbx_vector_ptr_create(&item_prototype->item_tags);
+ zbx_vector_db_tag_ptr_create(&item_prototype->item_tags);
zbx_vector_ptr_append(item_prototypes, item_prototype);
}
@@ -4510,6 +4346,8 @@ static void lld_item_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *i
while (NULL != (row = DBfetch(result)))
{
+ zbx_db_tag_t *db_tag;
+
ZBX_STR2UINT64(itemid, row[0]);
if (FAIL == (index = zbx_vector_ptr_bsearch(item_prototypes, &itemid,
@@ -4521,22 +4359,10 @@ static void lld_item_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *i
item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[index];
- item_tag = (zbx_lld_item_tag_t *)zbx_malloc(NULL, sizeof(zbx_lld_item_tag_t));
- item_tag->item_tagid = 0;
- item_tag->tag = zbx_strdup(NULL, row[1]);
- item_tag->tag_orig = NULL;
- item_tag->value = zbx_strdup(NULL, row[2]);
- item_tag->value_orig = NULL;
- item_tag->flags = ZBX_FLAG_LLD_ITEM_TAG_UNSET;
- zbx_vector_ptr_append(&item_prototype->item_tags, item_tag);
+ db_tag = zbx_db_tag_create(row[1], row[2]);
+ zbx_vector_db_tag_ptr_append(&item_prototype->item_tags, db_tag);
}
DBfree_result(result);
-
- for (i = 0; i < item_prototypes->values_num; i++)
- {
- item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[i];
- zbx_vector_ptr_sort(&item_prototype->item_tags, lld_item_tag_sort_by_tag);
- }
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d prototypes", __func__, item_prototypes->values_num);
}
@@ -4610,7 +4436,7 @@ int lld_update_items(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, zbx_vector_pt
lld_items_make(&item_prototypes, lld_rows, lld_macro_paths, &items, &items_index, error);
lld_items_preproc_make(&item_prototypes, lld_macro_paths, &items);
lld_items_param_make(&item_prototypes, lld_macro_paths, &items);
- lld_items_tags_make(&item_prototypes, lld_macro_paths, &items);
+ lld_items_tags_make(&item_prototypes, lld_macro_paths, &items, error);
lld_link_dependent_items(&items, &items_index);
diff --git a/src/zabbix_server/lld/lld_trigger.c b/src/zabbix_server/lld/lld_trigger.c
index 245b948d51a..63f351da5f0 100644
--- a/src/zabbix_server/lld/lld_trigger.c
+++ b/src/zabbix_server/lld/lld_trigger.c
@@ -45,7 +45,7 @@ typedef struct
unsigned char discover;
zbx_vector_ptr_t functions;
zbx_vector_ptr_t dependencies;
- zbx_vector_ptr_t tags;
+ zbx_vector_db_tag_ptr_t tags;
zbx_eval_context_t eval_ctx;
zbx_eval_context_t eval_ctx_r;
}
@@ -74,7 +74,7 @@ typedef struct
zbx_vector_ptr_t functions;
zbx_vector_ptr_t dependencies;
zbx_vector_ptr_t dependents;
- zbx_vector_ptr_t tags;
+ zbx_vector_db_tag_ptr_t tags;
zbx_vector_db_tag_ptr_t override_tags;
#define ZBX_FLAG_LLD_TRIGGER_UNSET __UINT64_C(0x0000)
#define ZBX_FLAG_LLD_TRIGGER_DISCOVERED __UINT64_C(0x0001)
@@ -143,24 +143,6 @@ zbx_lld_dependency_t;
typedef struct
{
- zbx_uint64_t triggertagid;
- char *tag_orig;
- char *tag;
- char *value_orig;
- char *value;
-#define ZBX_FLAG_LLD_TAG_UNSET __UINT64_C(0x00)
-#define ZBX_FLAG_LLD_TAG_DISCOVERED __UINT64_C(0x01)
-#define ZBX_FLAG_LLD_TAG_UPDATE_TAG __UINT64_C(0x02)
-#define ZBX_FLAG_LLD_TAG_UPDATE_VALUE __UINT64_C(0x04)
-#define ZBX_FLAG_LLD_TAG_UPDATE \
- (ZBX_FLAG_LLD_TAG_UPDATE_TAG | ZBX_FLAG_LLD_TAG_UPDATE_VALUE)
-#define ZBX_FLAG_LLD_TAG_DELETE __UINT64_C(0x08)
- zbx_uint64_t flags;
-}
-zbx_lld_tag_t;
-
-typedef struct
-{
zbx_uint64_t parent_triggerid;
zbx_uint64_t itemid;
zbx_lld_trigger_t *trigger;
@@ -223,15 +205,6 @@ typedef struct
}
zbx_lld_trigger_node_iter_t;
-static void lld_tag_free(zbx_lld_tag_t *tag)
-{
- zbx_free(tag->tag);
- zbx_free(tag->tag_orig);
- zbx_free(tag->value);
- zbx_free(tag->value_orig);
- zbx_free(tag);
-}
-
static void lld_item_free(zbx_lld_item_t *item)
{
zbx_free(item);
@@ -251,8 +224,8 @@ static void lld_trigger_prototype_free(zbx_lld_trigger_prototype_t *trigger_prot
zbx_eval_clear(&trigger_prototype->eval_ctx);
zbx_eval_clear(&trigger_prototype->eval_ctx_r);
- zbx_vector_ptr_clear_ext(&trigger_prototype->tags, (zbx_clean_func_t)lld_tag_free);
- zbx_vector_ptr_destroy(&trigger_prototype->tags);
+ zbx_vector_db_tag_ptr_clear_ext(&trigger_prototype->tags, zbx_db_tag_free);
+ zbx_vector_db_tag_ptr_destroy(&trigger_prototype->tags);
zbx_vector_ptr_clear_ext(&trigger_prototype->dependencies, zbx_ptr_free);
zbx_vector_ptr_destroy(&trigger_prototype->dependencies);
zbx_vector_ptr_clear_ext(&trigger_prototype->functions, (zbx_mem_free_func_t)lld_function_free);
@@ -270,9 +243,9 @@ static void lld_trigger_prototype_free(zbx_lld_trigger_prototype_t *trigger_prot
static void lld_trigger_free(zbx_lld_trigger_t *trigger)
{
- zbx_vector_ptr_clear_ext(&trigger->tags, (zbx_clean_func_t)lld_tag_free);
+ zbx_vector_db_tag_ptr_clear_ext(&trigger->tags, zbx_db_tag_free);
zbx_vector_db_tag_ptr_destroy(&trigger->override_tags);
- zbx_vector_ptr_destroy(&trigger->tags);
+ zbx_vector_db_tag_ptr_destroy(&trigger->tags);
zbx_vector_ptr_destroy(&trigger->dependents);
zbx_vector_ptr_clear_ext(&trigger->dependencies, zbx_ptr_free);
zbx_vector_ptr_destroy(&trigger->dependencies);
@@ -350,7 +323,7 @@ static void lld_trigger_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t
zbx_vector_ptr_create(&trigger_prototype->functions);
zbx_vector_ptr_create(&trigger_prototype->dependencies);
- zbx_vector_ptr_create(&trigger_prototype->tags);
+ zbx_vector_db_tag_ptr_create(&trigger_prototype->tags);
zbx_eval_init(&trigger_prototype->eval_ctx);
zbx_eval_init(&trigger_prototype->eval_ctx_r);
@@ -512,7 +485,7 @@ static void lld_triggers_get(const zbx_vector_ptr_t *trigger_prototypes, zbx_vec
zbx_vector_ptr_create(&trigger->functions);
zbx_vector_ptr_create(&trigger->dependencies);
zbx_vector_ptr_create(&trigger->dependents);
- zbx_vector_ptr_create(&trigger->tags);
+ zbx_vector_db_tag_ptr_create(&trigger->tags);
zbx_vector_db_tag_ptr_create(&trigger->override_tags);
zbx_vector_ptr_append(triggers, trigger);
@@ -796,55 +769,37 @@ static void lld_tags_get(const zbx_vector_ptr_t *trigger_prototypes, zbx_vector_
while (NULL != (row = DBfetch(result)))
{
+ zbx_db_tag_t *tag;
int index;
zbx_uint64_t triggerid;
- zbx_lld_tag_t *tag = (zbx_lld_tag_t *)zbx_malloc(NULL, sizeof(zbx_lld_tag_t));
- ZBX_STR2UINT64(tag->triggertagid, row[0]);
+ tag = zbx_db_tag_create(row[2], row[3]);
ZBX_STR2UINT64(triggerid, row[1]);
- tag->tag = zbx_strdup(NULL, row[2]);
- tag->tag_orig = NULL;
- tag->value = zbx_strdup(NULL, row[3]);
- tag->value_orig = NULL;
- tag->flags = ZBX_FLAG_LLD_DEPENDENCY_UNSET;
if (FAIL != (index = zbx_vector_ptr_bsearch(trigger_prototypes, &triggerid,
ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
{
trigger_prototype = (zbx_lld_trigger_prototype_t *)trigger_prototypes->values[index];
- zbx_vector_ptr_append(&trigger_prototype->tags, tag);
+ zbx_vector_db_tag_ptr_append(&trigger_prototype->tags, tag);
}
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->tags, tag);
+ ZBX_STR2UINT64(tag->tagid, row[0]);
+ zbx_vector_db_tag_ptr_append(&trigger->tags, tag);
}
else
{
THIS_SHOULD_NEVER_HAPPEN;
- lld_tag_free(tag);
+ zbx_db_tag_free(tag);
}
}
DBfree_result(result);
- for (i = 0; i < trigger_prototypes->values_num; i++)
- {
- trigger_prototype = (zbx_lld_trigger_prototype_t *)trigger_prototypes->values[i];
-
- zbx_vector_ptr_sort(&trigger_prototype->tags, 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->tags, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
- }
-
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
@@ -1562,7 +1517,7 @@ static void lld_trigger_make(const zbx_lld_trigger_prototype_t *trigger_prototy
zbx_vector_ptr_create(&trigger->functions);
zbx_vector_ptr_create(&trigger->dependencies);
zbx_vector_ptr_create(&trigger->dependents);
- zbx_vector_ptr_create(&trigger->tags);
+ zbx_vector_db_tag_ptr_create(&trigger->tags);
trigger->flags = ZBX_FLAG_LLD_TRIGGER_UNSET;
@@ -1891,95 +1846,50 @@ static void lld_trigger_dependencies_make(const zbx_vector_ptr_t *trigger_protot
* *
******************************************************************************/
static void lld_trigger_tag_make(const zbx_lld_trigger_prototype_t *trigger_prototype,
- zbx_hashset_t *items_triggers, const zbx_lld_row_t *lld_row, const zbx_vector_ptr_t *lld_macro_paths)
+ zbx_hashset_t *items_triggers, const zbx_lld_row_t *lld_row, const zbx_vector_ptr_t *lld_macro_paths,
+ char **error)
{
zbx_lld_trigger_t *trigger;
int i;
+ zbx_vector_db_tag_ptr_t new_tags;
+ zbx_db_tag_t *tag;
zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __func__);
if (NULL == (trigger = lld_trigger_get(trigger_prototype->triggerid, items_triggers, &lld_row->item_links)))
goto out;
- zbx_vector_db_tag_ptr_sort(&trigger->override_tags, zbx_db_tag_compare_func);
+ zbx_vector_db_tag_ptr_create(&new_tags);
- for (i = 0; i < trigger_prototype->tags.values_num + trigger->override_tags.values_num; i++)
+ for (i = 0; i < trigger_prototype->tags.values_num; i++)
{
- zbx_lld_tag_t *tag;
- const char *key, *value;
-
- if (i < trigger_prototype->tags.values_num)
- {
- zbx_lld_tag_t *tag_proto;
-
- tag_proto = (zbx_lld_tag_t *)trigger_prototype->tags.values[i];
- key = tag_proto->tag;
- value = tag_proto->value;
- }
- else
- {
- zbx_db_tag_t *dbtag;
-
- dbtag = trigger->override_tags.values[i - trigger_prototype->tags.values_num];
- key = dbtag->tag;
- value = dbtag->value;
- }
-
- if (i < trigger->tags.values_num)
- {
- char *buffer = NULL;
-
- tag = (zbx_lld_tag_t *)trigger->tags.values[i];
-
- buffer = zbx_strdup(buffer, key);
- substitute_lld_macros(&buffer, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC, NULL, 0);
- zbx_lrtrim(buffer, ZBX_WHITESPACE);
-
- if (0 != strcmp(buffer, tag->tag))
- {
- tag->tag_orig = tag->tag;
- tag->tag = buffer;
- buffer = NULL;
- tag->flags |= ZBX_FLAG_LLD_TAG_UPDATE_TAG;
- }
-
- buffer = zbx_strdup(buffer, value);
- substitute_lld_macros(&buffer, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC, NULL, 0);
- zbx_lrtrim(buffer, ZBX_WHITESPACE);
-
- if (0 != strcmp(buffer, tag->value))
- {
- tag->value_orig = tag->value;
- tag->value = buffer;
- buffer = NULL;
- tag->flags |= ZBX_FLAG_LLD_TAG_UPDATE_VALUE;
- }
-
- zbx_free(buffer);
- }
- else
- {
- tag = (zbx_lld_tag_t *)zbx_malloc(NULL, sizeof(zbx_lld_tag_t));
-
- tag->triggertagid = 0;
-
- tag->tag = zbx_strdup(NULL, key);
- tag->tag_orig = NULL;
- substitute_lld_macros(&tag->tag, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC, NULL, 0);
- zbx_lrtrim(tag->tag, ZBX_WHITESPACE);
-
- tag->value = zbx_strdup(NULL, value);
- tag->value_orig = NULL;
- substitute_lld_macros(&tag->value, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC, NULL, 0);
- zbx_lrtrim(tag->value, ZBX_WHITESPACE);
+ tag = zbx_db_tag_create(trigger_prototype->tags.values[i]->tag,
+ trigger_prototype->tags.values[i]->value);
+ zbx_vector_db_tag_ptr_append(&new_tags, tag);
+ }
- tag->flags = ZBX_FLAG_LLD_TAG_UNSET;
+ for (i = 0; i < trigger->override_tags.values_num; i++)
+ {
+ tag = zbx_db_tag_create(trigger->override_tags.values[i]->tag,
+ trigger->override_tags.values[i]->value);
+ zbx_vector_db_tag_ptr_append(&new_tags, tag);
+ }
- zbx_vector_ptr_append(&trigger->tags, tag);
- }
+ for (i = 0; i < new_tags.values_num; i++)
+ {
+ substitute_lld_macros(&new_tags.values[i]->tag, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC,
+ NULL, 0);
+ substitute_lld_macros(&new_tags.values[i]->value, &lld_row->jp_row, lld_macro_paths, ZBX_MACRO_FUNC,
+ NULL, 0);
+ }
- tag->flags |= ZBX_FLAG_LLD_TAG_DISCOVERED;
+ if (SUCCEED != zbx_merge_tags(&trigger->tags, &new_tags, "trigger", error) && 0 == trigger->triggerid)
+ {
+ trigger->flags &= ~ZBX_FLAG_LLD_TRIGGER_DISCOVERED;
+ *error = zbx_strdcatf(*error, "Cannot create trigger: tag validation failed.\n");
}
+
+ zbx_vector_db_tag_ptr_destroy(&new_tags);
out:
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
@@ -1990,7 +1900,7 @@ out:
* *
******************************************************************************/
static void lld_trigger_tags_make(const zbx_vector_ptr_t *trigger_prototypes, zbx_vector_ptr_t *triggers,
- const zbx_vector_ptr_t *lld_rows, const zbx_vector_ptr_t *lld_macro_paths)
+ const zbx_vector_ptr_t *lld_rows, const zbx_vector_ptr_t *lld_macro_paths, char **error)
{
zbx_lld_trigger_prototype_t *trigger_prototype;
int i, j;
@@ -1998,7 +1908,6 @@ static void lld_trigger_tags_make(const zbx_vector_ptr_t *trigger_prototypes, zb
zbx_lld_trigger_t *trigger;
zbx_lld_function_t *function;
zbx_lld_item_trigger_t item_trigger;
- zbx_lld_tag_t *tag;
/* used for fast search of trigger by item prototype */
zbx_hashset_create(&items_triggers, 512, items_triggers_hash_func, items_triggers_compare_func);
@@ -2029,24 +1938,7 @@ static void lld_trigger_tags_make(const zbx_vector_ptr_t *trigger_prototypes, zb
{
zbx_lld_row_t *lld_row = (zbx_lld_row_t *)lld_rows->values[j];
- lld_trigger_tag_make(trigger_prototype, &items_triggers, lld_row, lld_macro_paths);
- }
- }
-
- /* marking tags which will be deleted */
- 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;
-
- for (j = 0; j < trigger->tags.values_num; j++)
- {
- tag = (zbx_lld_tag_t *)trigger->tags.values[j];
-
- if (0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
- tag->flags = ZBX_FLAG_LLD_TAG_DELETE;
+ lld_trigger_tag_make(trigger_prototype, &items_triggers, lld_row, lld_macro_paths, error);
}
}
@@ -2280,7 +2172,7 @@ static void lld_triggers_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *trigger
zbx_vector_ptr_create(&db_trigger->functions);
zbx_vector_ptr_create(&db_trigger->dependencies);
zbx_vector_ptr_create(&db_trigger->dependents);
- zbx_vector_ptr_create(&db_trigger->tags);
+ zbx_vector_db_tag_ptr_create(&db_trigger->tags);
zbx_vector_db_tag_ptr_create(&db_trigger->override_tags);
zbx_vector_ptr_append(&db_triggers, db_trigger);
@@ -2354,98 +2246,6 @@ static void lld_triggers_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *trigger
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
-static void lld_validate_trigger_tag_field(zbx_lld_tag_t *tag, const char *field, zbx_uint64_t flag,
- size_t field_len, char **error)
-{
- size_t len;
-
- if (0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
- return;
-
- /* only new trigger tags or tags with changed data will be validated */
- if (0 != tag->triggertagid && 0 == (tag->flags & flag))
- return;
-
- if (SUCCEED != zbx_is_utf8(field))
- {
- char *field_utf8;
-
- field_utf8 = zbx_strdup(NULL, field);
- zbx_replace_invalid_utf8(field_utf8);
- *error = zbx_strdcatf(*error, "Cannot create trigger tag: value \"%s\" has invalid UTF-8 sequence.\n",
- field_utf8);
- zbx_free(field_utf8);
- }
- else if ((len = zbx_strlen_utf8(field)) > field_len)
- *error = zbx_strdcatf(*error, "Cannot create trigger tag: value \"%s\" is too long.\n", field);
- else if (0 != (flag & ZBX_FLAG_LLD_TAG_UPDATE_TAG) && 0 == len)
- *error = zbx_strdcatf(*error, "Cannot create trigger tag: empty tag name.\n");
- else
- return;
-
- if (0 != tag->triggertagid)
- tag->flags = ZBX_FLAG_LLD_TAG_DELETE;
- else
- tag->flags &= ~ZBX_FLAG_LLD_TAG_DISCOVERED;
-}
-
-/******************************************************************************
- * *
- * Purpose: validate created or updated trigger tags *
- * *
- ******************************************************************************/
-static void lld_trigger_tags_validate(zbx_vector_ptr_t *triggers, char **error)
-{
- int i, j, k;
- zbx_lld_trigger_t *trigger;
- zbx_lld_tag_t *tag, *tag_tmp;
-
- 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;
-
- for (j = 0; j < trigger->tags.values_num; j++)
- {
- tag = (zbx_lld_tag_t *)trigger->tags.values[j];
-
- lld_validate_trigger_tag_field(tag, tag->tag, ZBX_FLAG_LLD_TAG_UPDATE_TAG,
- TAG_NAME_LEN, error);
- lld_validate_trigger_tag_field(tag, tag->value, ZBX_FLAG_LLD_TAG_UPDATE_VALUE,
- TAG_VALUE_LEN, error);
-
- if (0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
- continue;
-
- /* check for duplicated tag,values pairs */
- for (k = 0; k < j; k++)
- {
- tag_tmp = (zbx_lld_tag_t *)trigger->tags.values[k];
-
- if (0 == strcmp(tag->tag, tag_tmp->tag) && 0 == strcmp(tag->value, tag_tmp->value))
- {
- *error = zbx_strdcatf(*error, "Cannot create trigger tag: tag \"%s\","
- "\"%s\" already exists.\n", tag->tag, tag->value);
-
- if (0 != tag->triggertagid)
- tag->flags = ZBX_FLAG_LLD_TAG_DELETE;
- else
- tag->flags &= ~ZBX_FLAG_LLD_TAG_DISCOVERED;
- }
- }
-
- /* reset trigger discovery flags for new trigger if tag discovery failed */
- if (0 == trigger->triggerid && 0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
- {
- trigger->flags &= ~ZBX_FLAG_LLD_TRIGGER_DISCOVERED;
- break;
- }
- }
- }
-}
-
/******************************************************************************
* *
* Purpose: transforms the simple trigger expression to the DB format *
@@ -2552,7 +2352,7 @@ static int lld_triggers_save(zbx_uint64_t hostid, const zbx_vector_ptr_t *trigge
zbx_lld_trigger_t *trigger;
zbx_lld_function_t *function;
zbx_lld_dependency_t *dependency;
- zbx_lld_tag_t *tag;
+ zbx_db_tag_t *tag;
zbx_vector_uint64_t del_functionids, del_triggerdepids, del_triggertagids, trigger_protoids;
zbx_uint64_t triggerid = 0, functionid = 0, triggerdepid = 0, triggerid_up, triggertagid;
char *sql = NULL;
@@ -2625,23 +2425,20 @@ static int lld_triggers_save(zbx_uint64_t hostid, const zbx_vector_ptr_t *trigge
for (j = 0; j < trigger->tags.values_num; j++)
{
- tag = (zbx_lld_tag_t *)trigger->tags.values[j];
+ tag = trigger->tags.values[j];
- if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_DELETE))
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
{
- zbx_vector_uint64_append(&del_triggertagids, tag->triggertagid);
+ zbx_vector_uint64_append(&del_triggertagids, tag->tagid);
zbx_audit_trigger_update_json_delete_tags(trigger->triggerid,
- (int)ZBX_FLAG_DISCOVERY_CREATED, tag->triggertagid);
+ (int)ZBX_FLAG_DISCOVERY_CREATED, tag->tagid);
continue;
}
- if (0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
- continue;
-
- if (0 == tag->triggertagid)
+ if (0 == tag->tagid)
new_tags++;
- else if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_UPDATE))
+ else if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
upd_tags++;
}
}
@@ -3012,31 +2809,28 @@ static int lld_triggers_save(zbx_uint64_t hostid, const zbx_vector_ptr_t *trigge
{
char *value_esc;
- tag = (zbx_lld_tag_t *)trigger->tags.values[j];
-
- if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_DELETE))
- continue;
+ tag = trigger->tags.values[j];
- if (0 == (tag->flags & ZBX_FLAG_LLD_TAG_DISCOVERED))
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_REMOVE))
continue;
- if (0 == tag->triggertagid)
+ if (0 == tag->tagid)
{
- tag->triggertagid = triggertagid++;
- zbx_db_insert_add_values(&db_insert_ttags, tag->triggertagid, trigger->triggerid,
+ tag->tagid = triggertagid++;
+ zbx_db_insert_add_values(&db_insert_ttags, tag->tagid, trigger->triggerid,
tag->tag, tag->value);
zbx_audit_trigger_update_json_add_tags_and_values(trigger->triggerid,
- (int)ZBX_FLAG_DISCOVERY_CREATED, tag->triggertagid, tag->tag,
+ (int)ZBX_FLAG_DISCOVERY_CREATED, tag->tagid, tag->tag,
tag->value);
}
- else if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_UPDATE))
+ else if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE))
{
const char *d = "";
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update trigger_tag set ");
- if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_UPDATE_TAG))
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE_TAG))
{
value_esc = DBdyn_escape_string(tag->tag);
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "tag='%s'", value_esc);
@@ -3044,21 +2838,23 @@ static int lld_triggers_save(zbx_uint64_t hostid, const zbx_vector_ptr_t *trigge
d = ",";
zbx_audit_trigger_update_json_update_tag_tag(trigger->triggerid,
- tag->triggertagid, tag->tag_orig, tag->tag);
+ ZBX_FLAG_DISCOVERY_CREATED, tag->tagid, tag->tag_orig,
+ tag->tag);
}
- if (0 != (tag->flags & ZBX_FLAG_LLD_TAG_UPDATE_VALUE))
+ if (0 != (tag->flags & ZBX_FLAG_DB_TAG_UPDATE_VALUE))
{
value_esc = DBdyn_escape_string(tag->value);
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%svalue='%s'", d, value_esc);
zbx_free(value_esc);
zbx_audit_trigger_update_json_update_tag_value(trigger->triggerid,
- tag->triggertagid, tag->value_orig, tag->value);
+ ZBX_FLAG_DISCOVERY_CREATED, tag->tagid, tag->value_orig,
+ tag->value);
}
zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
- " where triggertagid=" ZBX_FS_UI64 ";\n", tag->triggertagid);
+ " where triggertagid=" ZBX_FS_UI64 ";\n", tag->tagid);
}
}
}
@@ -3807,8 +3603,7 @@ int lld_update_triggers(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, const zbx_
lld_triggers_validate(hostid, &triggers, error);
lld_trigger_dependencies_make(&trigger_prototypes, &triggers, lld_rows, error);
lld_trigger_dependencies_validate(&triggers, error);
- lld_trigger_tags_make(&trigger_prototypes, &triggers, lld_rows, lld_macro_paths);
- lld_trigger_tags_validate(&triggers, error);
+ lld_trigger_tags_make(&trigger_prototypes, &triggers, lld_rows, lld_macro_paths, error);
ret = lld_triggers_save(hostid, &trigger_prototypes, &triggers);
lld_remove_lost_objects("trigger_discovery", "triggerid", &triggers, lifetime, lastcheck, DBdelete_triggers,
get_trigger_info);