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-11-11 11:28:02 +0300
committerAndris Zeila <andris.zeila@zabbix.com>2022-11-11 11:32:11 +0300
commitce2a5cacabb71328a9a66bba10e2257ea5cde15c (patch)
tree79e12f39565c52b7ecd2230ddcbe8be333ca323a
parent8f8c59ee64649f779e535deb8f713d1cf394acd2 (diff)
........S. [ZBX-19813] improved interface update during LLD linking and changed interface copying during template linking to use similar logic as API
Merge in ZBX/zabbix from feature/ZBX-19813-6.2 to release/6.2 * commit '8f28ff9f636f929c86776fefdf65f5cf2ae3dc78': ........S. [ZBX-19813] improved interface update during LLD linking and changed interface copying during template linking to use similar logic as API (cherry picked from commit de192ff23245b89d6d6d76a503d8a4ae71726b48)
-rw-r--r--ChangeLog.d/bugfix/ZBX-198131
-rw-r--r--src/libs/zbxdbwrap/host.c743
-rw-r--r--src/zabbix_server/lld/lld_host.c433
-rw-r--r--src/zabbix_server/operations.c5
4 files changed, 465 insertions, 717 deletions
diff --git a/ChangeLog.d/bugfix/ZBX-19813 b/ChangeLog.d/bugfix/ZBX-19813
new file mode 100644
index 00000000000..bc3de5fb538
--- /dev/null
+++ b/ChangeLog.d/bugfix/ZBX-19813
@@ -0,0 +1 @@
+........S. [ZBX-19813] reworked inteface updates in template linking and lld (wiper)
diff --git a/src/libs/zbxdbwrap/host.c b/src/libs/zbxdbwrap/host.c
index f9236e5ae76..1579ad1846a 100644
--- a/src/libs/zbxdbwrap/host.c
+++ b/src/libs/zbxdbwrap/host.c
@@ -2056,75 +2056,29 @@ ZBX_PTR_VECTOR_IMPL(macros, zbx_macros_prototype_t *)
typedef struct
{
- char *community_orig;
char *community;
- char *securityname_orig;
char *securityname;
- char *authpassphrase_orig;
char *authpassphrase;
- char *privpassphrase_orig;
char *privpassphrase;
- char *contextname_orig;
char *contextname;
- unsigned char securitylevel_orig;
unsigned char securitylevel;
- unsigned char authprotocol_orig;
unsigned char authprotocol;
- unsigned char privprotocol_orig;
unsigned char privprotocol;
- unsigned char version_orig;
unsigned char version;
- unsigned char bulk_orig;
unsigned char bulk;
-#define ZBX_FLAG_HPINTERFACE_SNMP_RESET_FLAG __UINT64_C(0x00000000)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_TYPE __UINT64_C(0x00000001)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_BULK __UINT64_C(0x00000002)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_COMMUNITY __UINT64_C(0x00000004)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECNAME __UINT64_C(0x00000008)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECLEVEL __UINT64_C(0x00000010)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPASS __UINT64_C(0x00000020)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPASS __UINT64_C(0x00000040)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPROTOCOL __UINT64_C(0x00000080)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPROTOCOL __UINT64_C(0x00000100)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_CONTEXT __UINT64_C(0x00000200)
-#define ZBX_FLAG_HPINTERFACE_SNMP_UPDATE \
- (ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_TYPE | ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_BULK | \
- ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_COMMUNITY | ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECNAME | \
- ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECLEVEL | ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPASS | \
- ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPASS | ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPROTOCOL | \
- ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPROTOCOL | ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_CONTEXT)
-#define ZBX_FLAG_HPINTERFACE_SNMP_CREATE __UINT64_C(0x00000400)
- zbx_uint64_t flags;
}
zbx_interface_prototype_snmp_t;
typedef struct
{
zbx_uint64_t interfaceid;
- unsigned char main_orig;
unsigned char main;
- unsigned char type_orig;
unsigned char type;
- unsigned char useip_orig;
unsigned char useip;
- char *ip_orig;
char *ip;
- char *dns_orig;
char *dns;
- char *port_orig;
char *port;
-#define ZBX_FLAG_HPINTERFACE_RESET_FLAG __UINT64_C(0x00000000)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_MAIN __UINT64_C(0x00000001)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_TYPE __UINT64_C(0x00000002)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_USEIP __UINT64_C(0x00000004)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_IP __UINT64_C(0x00000008)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_DNS __UINT64_C(0x00000010)
-#define ZBX_FLAG_HPINTERFACE_UPDATE_PORT __UINT64_C(0x00000020)
-#define ZBX_FLAG_HPINTERFACE_UPDATE \
- (ZBX_FLAG_HPINTERFACE_UPDATE_MAIN | ZBX_FLAG_HPINTERFACE_UPDATE_TYPE | \
- ZBX_FLAG_HPINTERFACE_UPDATE_USEIP | ZBX_FLAG_HPINTERFACE_UPDATE_IP | \
- ZBX_FLAG_HPINTERFACE_UPDATE_DNS | ZBX_FLAG_HPINTERFACE_UPDATE_PORT)
- zbx_uint64_t flags;
+
union _data
{
zbx_interface_prototype_snmp_t *snmp;
@@ -2189,32 +2143,8 @@ static void DBhost_interface_free(zbx_interfaces_prototype_t *interface)
zbx_free(interface->dns);
zbx_free(interface->port);
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_IP))
- zbx_free(interface->ip_orig);
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_DNS))
- zbx_free(interface->dns_orig);
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_PORT))
- zbx_free(interface->port_orig);
-
if (INTERFACE_TYPE_SNMP == interface->type)
{
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_COMMUNITY))
- zbx_free(interface->data.snmp->community_orig);
-
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECNAME))
- zbx_free(interface->data.snmp->securityname_orig);
-
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPASS))
- zbx_free(interface->data.snmp->authpassphrase_orig);
-
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPASS))
- zbx_free(interface->data.snmp->privpassphrase_orig);
-
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_CONTEXT))
- zbx_free(interface->data.snmp->contextname_orig);
-
zbx_free(interface->data.snmp->community);
zbx_free(interface->data.snmp->securityname);
zbx_free(interface->data.snmp->authpassphrase);
@@ -2780,168 +2710,6 @@ static int DBhost_prototypes_macro_make(zbx_vector_macros_t *hostmacros, zbx_uin
/******************************************************************************
* *
- * Purpose: fill empty value in interfaces with input parameters *
- * *
- * Parameters: interfaces - [IN/OUT] list of host interfaces *
- * interfaceid - [IN] interface id *
- * del_snmp_ids - [IN/OUT] list of SNMP interfaces to delete *
- * ifmain - [IN] interface main *
- * type - [IN] interface type *
- * useip - [IN] interface useip *
- * ip - [IN] interface ip *
- * dns - [IN] interface dns *
- * port - [IN] interface port *
- * snmp_type - [IN] interface_snmp version *
- * bulk - [IN] interface_snmp bulk *
- * community - [IN] interface_snmp community *
- * securityname - [IN] interface_snmp securityname *
- * securitylevel - [IN] interface_snmp securitylevel *
- * authpassphrase - [IN] interface_snmp authpassphrase *
- * privpassphrase - [IN] interface_snmp privpassphrase *
- * authprotocol - [IN] interface_snmp authprotocol *
- * privprotocol - [IN] interface_snmp privprotocol *
- * contextname - [IN] interface_snmp contextname *
- * *
- * Return value: SUCCEED - the host interface was found *
- * FAIL - in the other case *
- ******************************************************************************/
-static int DBhost_prototypes_interface_make(zbx_vector_interfaces_t *interfaces, zbx_uint64_t interfaceid,
- zbx_vector_uint64_t *del_snmp_ids, unsigned char ifmain, unsigned char type, unsigned char useip,
- const char *ip, const char *dns, const char *port, unsigned char snmp_type, unsigned char bulk,
- const char *community, const char *securityname, unsigned char securitylevel,
- const char *authpassphrase, const char *privpassphrase, unsigned char authprotocol,
- unsigned char privprotocol, const char *contextname)
-{
- zbx_interfaces_prototype_t *interface;
- int i;
-
- for (i = 0; i < interfaces->values_num; i++)
- {
- interface = interfaces->values[i];
-
- if (0 == interface->interfaceid)
- {
- interface->interfaceid = interfaceid;
-
- if (interface->main != ifmain)
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_MAIN;
- interface->main_orig = ifmain;
- }
-
- if (interface->type != type)
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_TYPE;
- interface->type_orig = type;
- }
-
- if (interface->useip != useip)
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_USEIP;
- interface->useip_orig = useip;
- }
-
- if (0 != strcmp(interface->ip, ip))
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_IP;
- interface->ip_orig = zbx_strdup(NULL, ip);
- }
-
- if (0 != strcmp(interface->dns, dns))
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_DNS;
- interface->dns_orig = zbx_strdup(NULL, dns);
- }
-
- if (0 != strcmp(interface->port, port))
- {
- interface->flags |= ZBX_FLAG_HPINTERFACE_UPDATE_PORT;
- interface->port_orig = zbx_strdup(NULL, port);
- }
-
- if (INTERFACE_TYPE_SNMP == interface->type)
- {
- zbx_interface_prototype_snmp_t *snmp = interface->data.snmp;
-
- if (INTERFACE_TYPE_SNMP == type)
- {
- if (snmp->version != snmp_type)
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_TYPE;
- snmp->version_orig = snmp_type;
- }
-
- if (snmp->bulk != bulk)
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_BULK;
- snmp->bulk_orig = bulk;
- }
-
- if (0 != strcmp(snmp->community, community))
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_COMMUNITY;
- snmp->community_orig = zbx_strdup(NULL, community);
- }
-
- if (0 != strcmp(snmp->securityname, securityname))
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECNAME;
- snmp->securityname_orig = zbx_strdup(NULL, securityname);
- }
-
- if (snmp->securitylevel != securitylevel)
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECLEVEL;
- snmp->securitylevel_orig = securitylevel;
- }
-
- if (0 != strcmp(snmp->authpassphrase, authpassphrase))
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPASS;
- snmp->authpassphrase_orig = zbx_strdup(NULL, authpassphrase);
- }
-
- if (0 != strcmp(snmp->privpassphrase, privpassphrase))
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPASS;
- snmp->privpassphrase_orig = zbx_strdup(NULL, privpassphrase);
- }
-
- if (snmp->authprotocol != authprotocol)
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPROTOCOL;
- snmp->authprotocol_orig = authprotocol;
- }
-
- if (snmp->privprotocol != privprotocol)
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPROTOCOL;
- snmp->privprotocol_orig = privprotocol;
- }
-
- if (0 != strcmp(snmp->contextname, contextname))
- {
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_CONTEXT;
- snmp->contextname_orig = zbx_strdup(NULL, contextname);
- }
- }
- else
- snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_CREATE;
- }
- else if (INTERFACE_TYPE_SNMP == type)
- {
- zbx_vector_uint64_append(del_snmp_ids, interfaceid);
- }
-
- return SUCCEED;
- }
- }
-
- return FAIL;
-}
-
-/******************************************************************************
- * *
* Parameters: host_prototypes - [IN/OUT] list of host prototypes *
* should be sorted by templateid *
* del_macroids - [OUT] sorted list of host macroids which *
@@ -3215,6 +2983,113 @@ static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes)
zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__);
}
+static int host_prototype_interfaces_compare(const zbx_interfaces_prototype_t *ifold,
+ const zbx_interfaces_prototype_t *ifnew)
+{
+ if (ifold->type != ifnew->type)
+ return FAIL;
+
+ if (ifold->main != ifnew->main)
+ return FAIL;
+
+ if (ifold->useip != ifnew->useip)
+ return FAIL;
+
+ if (0 != strcmp(ifold->ip, ifnew->ip))
+ return FAIL;
+
+ if (0 != strcmp(ifold->dns, ifnew->dns))
+ return FAIL;
+
+ if (0 != strcmp(ifold->port, ifnew->port))
+ return FAIL;
+
+ if (INTERFACE_TYPE_SNMP == ifold->type)
+ {
+ if (ifold->data.snmp->version != ifnew->data.snmp->version)
+ return FAIL;
+
+ if (ifold->data.snmp->bulk != ifnew->data.snmp->bulk)
+ return FAIL;
+
+ if (0 != strcmp(ifold->data.snmp->community, ifnew->data.snmp->community))
+ return FAIL;
+
+ if (0 != strcmp(ifold->data.snmp->securityname, ifnew->data.snmp->securityname))
+ return FAIL;
+
+ if (ifold->data.snmp->securitylevel != ifnew->data.snmp->securitylevel)
+ return FAIL;
+
+ if (0 != strcmp(ifold->data.snmp->authpassphrase, ifnew->data.snmp->authpassphrase))
+ return FAIL;
+
+ if (0 != strcmp(ifold->data.snmp->privpassphrase, ifnew->data.snmp->privpassphrase))
+ return FAIL;
+
+ if (ifold->data.snmp->authprotocol != ifnew->data.snmp->authprotocol)
+ return FAIL;
+
+ if (ifold->data.snmp->privprotocol != ifnew->data.snmp->privprotocol)
+ return FAIL;
+
+ if (0 != strcmp(ifold->data.snmp->contextname, ifnew->data.snmp->contextname))
+ return FAIL;
+ }
+
+ return SUCCEED;
+}
+
+static void host_prototype_interfaces_make(zbx_uint64_t hostid, zbx_vector_ptr_t *host_prototypes,
+ zbx_vector_interfaces_t *old_interfaces, zbx_vector_uint64_t *del_interfaceids)
+{
+ int i, j;
+ zbx_host_prototype_t *host_prototype;
+
+ for (i = 0; i < host_prototypes->values_num; i++)
+ {
+ host_prototype = (zbx_host_prototype_t *)host_prototypes->values[i];
+
+ if (host_prototype->hostid == hostid)
+ break;
+ }
+
+ if (i == host_prototypes->values_num)
+ {
+ THIS_SHOULD_NEVER_HAPPEN;
+ goto out;
+ }
+
+ /* find matching interfaces */
+
+ for (i = 0; i < host_prototype->interfaces.values_num; i++)
+ {
+ zbx_interfaces_prototype_t *interface = (zbx_interfaces_prototype_t *)
+ host_prototype->interfaces.values[i];
+
+ if (0 != interface->interfaceid)
+ continue;
+
+ for (j = 0; j < old_interfaces->values_num; j++)
+ {
+ if (SUCCEED == host_prototype_interfaces_compare(old_interfaces->values[j], interface))
+ {
+ interface->interfaceid = old_interfaces->values[j]->interfaceid;
+ DBhost_interface_free(old_interfaces->values[j]);
+ zbx_vector_interfaces_remove_noorder(old_interfaces, j);
+ break;
+ }
+ }
+ }
+
+ /* remove deleted/modified interfaces */
+ for (i = 0; i < old_interfaces->values_num; i++)
+ zbx_vector_uint64_append(del_interfaceids, old_interfaces->values[i]->interfaceid);
+out:
+ zbx_vector_interfaces_clear_ext(old_interfaces, DBhost_interface_free);
+}
+
+
/******************************************************************************
* *
* Purpose: prepare interfaces to be added, updated or removed from DB *
@@ -3222,15 +3097,12 @@ static void DBhost_prototypes_tags_make(zbx_vector_ptr_t *host_prototypes)
* should be sorted by templateid *
* del_interfaceids - [OUT] sorted list of host interface *
* ids which should be deleted *
- * del_snmp_interfaceids - [OUT] sorted list of host snmp *
- * interface ids which should be *
- * deleted *
* *
* Comments: auxiliary function for DBcopy_template_host_prototypes() *
* *
******************************************************************************/
static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
- zbx_vector_uint64_t *del_interfaceids, zbx_vector_uint64_t *del_snmp_interfaceids)
+ zbx_vector_uint64_t *del_interfaceids)
{
DB_RESULT result;
DB_ROW row;
@@ -3293,13 +3165,6 @@ static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
interface->ip = zbx_strdup(NULL, row[4]);
interface->dns = zbx_strdup(NULL, row[5]);
interface->port = zbx_strdup(NULL, row[6]);
- interface->flags = ZBX_FLAG_HPINTERFACE_RESET_FLAG;
- interface->main_orig = 0;
- interface->type_orig = 0;
- interface->useip_orig = 0;
- interface->ip_orig = NULL;
- interface->dns_orig = NULL;
- interface->port_orig = NULL;
if (INTERFACE_TYPE_SNMP == interface->type)
{
@@ -3317,18 +3182,7 @@ static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
ZBX_STR2UCHAR(snmp->authprotocol, row[14]);
ZBX_STR2UCHAR(snmp->privprotocol, row[15]);
snmp->contextname = zbx_strdup(NULL, row[16]);
- snmp->flags = ZBX_FLAG_HPINTERFACE_SNMP_RESET_FLAG;
interface->data.snmp = snmp;
- snmp->community_orig = NULL;
- snmp->securityname_orig = NULL;
- snmp->authpassphrase_orig = NULL;
- snmp->privpassphrase_orig = NULL;
- snmp->contextname_orig = NULL;
- snmp->securitylevel_orig = 0;
- snmp->authprotocol_orig = 0;
- snmp->privprotocol_orig = 0;
- snmp->version_orig = 0;
- snmp->bulk_orig = 0;
}
else
interface->data.snmp = NULL;
@@ -3354,6 +3208,11 @@ static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
if (0 != hostids.values_num)
{
+ zbx_vector_interfaces_t old_interfaces;
+ zbx_uint64_t last_hostid = 0;
+
+ zbx_vector_interfaces_create(&old_interfaces);
+
zbx_vector_uint64_sort(&hostids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
sql_offset = 0;
@@ -3374,85 +3233,55 @@ static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
{
ZBX_STR2UINT64(hostid, row[1]);
- for (i = 0; i < host_prototypes->values_num; i++)
+ if (0 != last_hostid && hostid != last_hostid)
{
- host_prototype = (zbx_host_prototype_t *)host_prototypes->values[i];
-
- if (host_prototype->hostid == hostid)
- {
- unsigned char type;
- uint64_t interfaceid;
-
- ZBX_STR2UINT64(interfaceid, row[0]);
- ZBX_STR2UCHAR(type, row[3]);
-
- if (INTERFACE_TYPE_SNMP == type)
- {
- if (FAIL == DBhost_prototypes_interface_make(
- &host_prototype->interfaces, interfaceid,
- del_snmp_interfaceids,
- (unsigned char)atoi(row[2]), /* main */
- type,
- (unsigned char)atoi(row[4]), /* useip */
- row[5], /* ip */
- row[6], /* dns */
- row[7], /* port */
- (unsigned char)atoi(row[8]), /* version */
- (unsigned char)atoi(row[9]), /* bulk */
- row[10], /* community */
- row[11], /* securityname */
- (unsigned char)atoi(row[12]), /* securitylevel */
- row[13], /* authpassphrase */
- row[14], /* privpassphrase */
- (unsigned char)atoi(row[15]), /* authprotocol */
- (unsigned char)atoi(row[16]), /* privprotocol */
- row[17])) /* contextname */
- {
- zbx_vector_uint64_append(del_interfaceids, interfaceid);
-
- zbx_audit_host_prototype_create_entry(ZBX_AUDIT_ACTION_UPDATE,
- host_prototype->hostid, host_prototype->host);
-
- zbx_audit_host_prototype_update_json_delete_interface(
- host_prototype->hostid, interfaceid);
- }
- }
- else
- {
- if (FAIL == DBhost_prototypes_interface_make(
- &host_prototype->interfaces, interfaceid,
- del_snmp_interfaceids,
- (unsigned char)atoi(row[2]), /* main */
- type,
- (unsigned char)atoi(row[4]), /* useip */
- row[5], /* ip */
- row[6], /* dns */
- row[7], /* port */
- 0, 0, NULL, NULL, 0, NULL, NULL, 0, 0, NULL))
- {
- zbx_vector_uint64_append(del_interfaceids, interfaceid);
+ host_prototype_interfaces_make(last_hostid, host_prototypes, &old_interfaces,
+ del_interfaceids);
+ }
- zbx_audit_host_prototype_create_entry(ZBX_AUDIT_ACTION_UPDATE,
- host_prototype->hostid, host_prototype->host);
+ last_hostid = hostid;
- zbx_audit_host_prototype_update_json_delete_interface(
- host_prototype->hostid, interfaceid);
- }
- }
+ interface = (zbx_interfaces_prototype_t *)zbx_malloc(NULL, sizeof(zbx_interfaces_prototype_t));
+ ZBX_STR2UINT64(interface->interfaceid, row[0]);
+ ZBX_STR2UCHAR(interface->main, row[2]);
+ ZBX_STR2UCHAR(interface->type, row[3]);
+ ZBX_STR2UCHAR(interface->useip, row[4]);
+ interface->ip = zbx_strdup(NULL, row[5]);
+ interface->dns = zbx_strdup(NULL, row[6]);
+ interface->port = zbx_strdup(NULL, row[7]);
- break;
- }
+ if (INTERFACE_TYPE_SNMP == interface->type)
+ {
+ zbx_interface_prototype_snmp_t *snmp;
+
+ snmp = (zbx_interface_prototype_snmp_t *)zbx_malloc(NULL,
+ sizeof(zbx_interface_prototype_snmp_t));
+ ZBX_STR2UCHAR(snmp->version, row[8]);
+ ZBX_STR2UCHAR(snmp->bulk, row[9]);
+ snmp->community = zbx_strdup(NULL, row[10]);
+ snmp->securityname = zbx_strdup(NULL, row[11]);
+ ZBX_STR2UCHAR(snmp->securitylevel, row[12]);
+ snmp->authpassphrase = zbx_strdup(NULL, row[13]);
+ snmp->privpassphrase = zbx_strdup(NULL, row[14]);
+ ZBX_STR2UCHAR(snmp->authprotocol, row[15]);
+ ZBX_STR2UCHAR(snmp->privprotocol, row[16]);
+ snmp->contextname = zbx_strdup(NULL, row[17]);
+ interface->data.snmp = snmp;
}
+ else
+ interface->data.snmp = NULL;
- /* no interfaces found for this host prototype, but there must be at least one */
- if (i == host_prototypes->values_num)
- THIS_SHOULD_NEVER_HAPPEN;
+ zbx_vector_interfaces_append(&old_interfaces, interface);
}
DBfree_result(result);
+
+ if (0 != old_interfaces.values_num)
+ host_prototype_interfaces_make(last_hostid, host_prototypes, &old_interfaces, del_interfaceids);
+
+ zbx_vector_interfaces_destroy(&old_interfaces);
}
zbx_vector_uint64_sort(del_interfaceids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
- zbx_vector_uint64_sort(del_snmp_interfaceids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
zbx_vector_uint64_destroy(&hostids);
zbx_free(sql);
@@ -3462,144 +3291,18 @@ static void DBhost_prototypes_interfaces_make(zbx_vector_ptr_t *host_prototypes,
/******************************************************************************
* *
- * Purpose: prepare sql for update record of interface_snmp table *
- * *
- * Parameters: hostid - [IN] host identifier *
- * interfaceid - [IN] snmp interface id; *
- * snmp - [IN] snmp interface prototypes for update *
- * sql - [IN/OUT] sql string *
- * sql_alloc - [IN/OUT] size of sql string *
- * sql_offset - [IN/OUT] offset in sql string *
- * *
- ******************************************************************************/
-static void DBhost_prototypes_interface_snmp_prepare_sql(zbx_uint64_t hostid, const zbx_uint64_t interfaceid,
- const zbx_interface_prototype_snmp_t *snmp, char **sql, size_t *sql_alloc, size_t *sql_offset)
-{
- const char *d = "";
- char *esc;
-
- zbx_strcpy_alloc(sql, sql_alloc, sql_offset, "update interface_snmp set ");
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_TYPE))
- {
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "version=%d", (int)snmp->version);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_version(hostid, interfaceid,
- snmp->version_orig, snmp->version);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_BULK))
- {
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%sbulk=%d", d, (int)snmp->bulk);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_bulk(hostid, interfaceid, snmp->bulk_orig,
- snmp->bulk);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_COMMUNITY))
- {
- esc = DBdyn_escape_string(snmp->community);
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%scommunity='%s'", d, esc);
- zbx_free(esc);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_community(hostid, interfaceid,
- snmp->community_orig, snmp->community);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECNAME))
- {
- esc = DBdyn_escape_string(snmp->securityname);
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%ssecurityname='%s'", d, esc);
- zbx_free(esc);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_securityname(hostid, interfaceid,
- snmp->securityname_orig, snmp->securityname);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_SECLEVEL))
- {
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%ssecuritylevel=%d", d, (int)snmp->securitylevel);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_securitylevel(hostid, interfaceid,
- snmp->securitylevel_orig, snmp->securitylevel);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPASS))
- {
- esc = DBdyn_escape_string(snmp->authpassphrase);
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%sauthpassphrase='%s'", d, esc);
- zbx_free(esc);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_authpassphrase(hostid, interfaceid,
- snmp->authpassphrase_orig, snmp->authpassphrase);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPASS))
- {
- esc = DBdyn_escape_string(snmp->privpassphrase);
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%sprivpassphrase='%s'", d, esc);
- zbx_free(esc);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_privpassphrase(hostid, interfaceid,
- snmp->privpassphrase_orig, snmp->privpassphrase);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_AUTHPROTOCOL))
- {
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%sauthprotocol=%d", d, (int)snmp->authprotocol);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_authprotocol(hostid, interfaceid,
- snmp->authprotocol_orig, snmp->authprotocol);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_PRIVPROTOCOL))
- {
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%sprivprotocol=%d", d, (int)snmp->privprotocol);
- d = ",";
-
- zbx_audit_host_prototype_update_json_update_interface_privprotocol(hostid, interfaceid,
- snmp->privprotocol_orig, snmp->privprotocol);
- }
-
- if (0 != (snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE_CONTEXT))
- {
- esc = DBdyn_escape_string(snmp->contextname);
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, "%scontextname='%s'", d, esc);
- zbx_free(esc);
-
- zbx_audit_host_prototype_update_json_update_interface_contextname(hostid, interfaceid,
- snmp->contextname_orig, snmp->contextname);
- }
-
- zbx_snprintf_alloc(sql, sql_alloc, sql_offset, " where interfaceid=" ZBX_FS_UI64 ";\n", interfaceid);
-
- DBexecute_overflowed_sql(sql, sql_alloc, sql_offset);
-}
-
-/******************************************************************************
- * *
* Purpose: auxiliary function for DBcopy_template_host_prototypes() *
* *
* 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_interfaceids - [IN] interface ids for delete *
- * del_snmpids - [IN] SNMP interface ids for delete *
* db_insert_htemplates - [IN/OUT] templates insert structure *
* *
******************************************************************************/
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_interfaceids, const zbx_vector_uint64_t *del_snmpids,
- zbx_db_insert_t *db_insert_htemplates)
+ const zbx_vector_uint64_t *del_interfaceids, 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,
@@ -3611,8 +3314,8 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
hosttagid = 0, interfaceid = 0;
int i, j, new_hosts = 0, new_hosts_templates = 0, new_group_prototypes = 0,
upd_group_prototypes = 0, new_hostmacros = 0, upd_hostmacros = 0,
- new_tags = 0, new_interfaces = 0, upd_interfaces = 0, new_snmp = 0,
- upd_snmp = 0, new_inventory_modes = 0, upd_inventory_modes = 0, res = SUCCEED;
+ new_tags = 0, new_interfaces = 0, new_snmp = 0,
+ new_inventory_modes = 0, upd_inventory_modes = 0, res = SUCCEED;
zbx_db_insert_t db_insert, db_insert_hdiscovery, db_insert_gproto,
db_insert_hmacro, db_insert_tag, db_insert_iface, db_insert_snmp,
db_insert_inventory_mode;
@@ -3717,21 +3420,21 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
interface = host_prototype->interfaces.values[j];
if (0 == interface->interfaceid)
- new_interfaces++;
- else if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE))
- upd_interfaces++;
-
- if (INTERFACE_TYPE_SNMP == interface->type)
{
- if (0 == interface->interfaceid)
- interface->data.snmp->flags |= ZBX_FLAG_HPINTERFACE_SNMP_CREATE;
+ new_interfaces++;
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_CREATE))
- new_snmp++;
- else if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE))
- upd_snmp++;
+ if (INTERFACE_TYPE_SNMP == interface->type)
+ new_snmp++;
}
}
+
+ for (j = 0; j < del_interfaceids->values_num; j++)
+ {
+ zbx_audit_host_prototype_create_entry(ZBX_AUDIT_ACTION_UPDATE, host_prototype->hostid,
+ host_prototype->host);
+ zbx_audit_host_prototype_update_json_delete_interface(host_prototype->hostid,
+ del_interfaceids->values[j]);
+ }
}
if (0 != new_hosts)
@@ -3755,8 +3458,7 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
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 ||
- 0 != del_snmpids->values_num || 0 != del_interfaceids->values_num ||
- 0 != del_inventory_modes_hostids.values_num)
+ 0 != del_interfaceids->values_num || 0 != del_inventory_modes_hostids.values_num)
{
sql2 = (char *)zbx_malloc(sql2, sql2_alloc);
zbx_DBbegin_multiple_update(&sql2, &sql2_alloc, &sql2_offset);
@@ -3786,14 +3488,6 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, ";\n");
}
- if (0 != del_snmpids->values_num)
- {
- zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, "delete from interface_snmp where");
- DBadd_condition_alloc(&sql2, &sql2_alloc, &sql2_offset, "interfaceid",
- del_snmpids->values, del_snmpids->values_num);
- zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, ";\n");
- }
-
if (0 != del_interfaceids->values_num)
{
zbx_strcpy_alloc(&sql2, &sql2_alloc, &sql2_offset, "delete from interface where");
@@ -4108,87 +3802,8 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
zbx_audit_host_prototype_update_json_add_interfaces(host_prototype->hostid,
interface->interfaceid, interface->main, interface->type,
interface->useip, interface->ip, interface->dns, atoi(interface->port));
- }
- else if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE))
- {
- const char *d = "";
-
- zbx_strcpy_alloc(&sql1, &sql1_alloc, &sql1_offset, "update interface set ");
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_MAIN))
- {
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%smain=%d", d,
- interface->main);
- d = ",";
- zbx_audit_host_prototype_update_json_update_interface_main(
- host_prototype->hostid, interface->interfaceid,
- interface->main_orig, interface->main);
- }
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_TYPE))
- {
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%stype=%d", d,
- interface->type);
- d = ",";
- zbx_audit_host_prototype_update_json_update_interface_type(
- host_prototype->hostid, interface->interfaceid,
- interface->type_orig, interface->type);
- }
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_USEIP))
- {
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%suseip=%d", d,
- interface->useip);
- d = ",";
- zbx_audit_host_prototype_update_json_update_interface_useip(
- host_prototype->hostid, interface->interfaceid,
- interface->useip_orig, interface->useip);
- }
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_IP))
- {
- value_esc = DBdyn_escape_string(interface->ip);
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%sip='%s'", d, value_esc);
- zbx_free(value_esc);
- d = ",";
- zbx_audit_host_prototype_update_json_update_interface_ip(
- host_prototype->hostid, interface->interfaceid,
- interface->ip_orig, interface->ip);
- }
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_DNS))
- {
- value_esc = DBdyn_escape_string(interface->dns);
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%sdns='%s'", d,
- value_esc);
- zbx_free(value_esc);
- d = ",";
- zbx_audit_host_prototype_update_json_update_interface_dns(
- host_prototype->hostid, interface->interfaceid,
- interface->dns_orig, interface->dns);
- }
-
- if (0 != (interface->flags & ZBX_FLAG_HPINTERFACE_UPDATE_PORT))
- {
- value_esc = DBdyn_escape_string(interface->port);
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset, "%sport='%s'", d,
- value_esc);
- zbx_free(value_esc);
- zbx_audit_host_prototype_update_json_update_interface_port(
- host_prototype->hostid, interface->interfaceid,
- atoi(interface->port_orig), atoi(interface->port));
- }
-
- zbx_snprintf_alloc(&sql1, &sql1_alloc, &sql1_offset,
- " where interfaceid=" ZBX_FS_UI64 ";\n", interface->interfaceid);
-
- if (FAIL == (res = DBexecute_overflowed_sql(&sql1, &sql1_alloc, &sql1_offset)))
- break;
- }
-
- if (INTERFACE_TYPE_SNMP == interface->type)
- {
- if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_CREATE))
+ if (INTERFACE_TYPE_SNMP == interface->type)
{
zbx_db_insert_add_values(&db_insert_snmp, interface->interfaceid,
(int)interface->data.snmp->version,
@@ -4214,14 +3829,6 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
interface->data.snmp->contextname,
interface->interfaceid);
}
- else if (0 != (interface->data.snmp->flags & ZBX_FLAG_HPINTERFACE_SNMP_UPDATE))
- {
- zbx_audit_host_prototype_update_json_update_interface_details_create_entry(
- host_prototype->hostid, interface->interfaceid);
- DBhost_prototypes_interface_snmp_prepare_sql(host_prototype->hostid,
- interface->interfaceid, interface->data.snmp, &sql1,
- &sql1_alloc, &sql1_offset);
- }
}
}
}
@@ -4308,7 +3915,7 @@ static void DBhost_prototypes_save(const zbx_vector_ptr_t *host_prototypes,
}
if (SUCCEED == res && (NULL != sql1 || new_hosts != host_prototypes->values_num || 0 != upd_group_prototypes ||
- 0 != upd_hostmacros || 0 != upd_interfaces || 0 != upd_snmp || 0 != upd_inventory_modes))
+ 0 != upd_hostmacros || 0 != upd_inventory_modes))
{
zbx_DBend_multiple_update(&sql1, &sql1_alloc, &sql1_offset);
@@ -4319,8 +3926,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_interfaceids->values_num || 0 != del_snmpids->values_num ||
- 0 != del_inventory_modes_hostids.values_num))
+ 0 != del_interfaceids->values_num || 0 != del_inventory_modes_hostids.values_num))
{
zbx_DBend_multiple_update(&sql2, &sql2_alloc, &sql2_offset);
@@ -4367,27 +3973,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_interfaceids,
- del_snmp_interfaceids;
+ zbx_vector_uint64_t del_hosttemplateids, del_group_prototypeids, del_macroids, del_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_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);
- DBhost_prototypes_interfaces_make(&host_prototypes, &del_interfaceids, &del_snmp_interfaceids);
+ DBhost_prototypes_interfaces_make(&host_prototypes, &del_interfaceids);
DBhost_prototypes_save(&host_prototypes, &del_hosttemplateids, &del_macroids,
- &del_interfaceids, &del_snmp_interfaceids, db_insert_htemplates);
+ &del_interfaceids, db_insert_htemplates);
DBgroup_prototypes_delete(&del_group_prototypeids);
zbx_vector_uint64_destroy(&del_macroids);
zbx_vector_uint64_destroy(&del_group_prototypeids);
- zbx_vector_uint64_destroy(&del_snmp_interfaceids);
zbx_vector_uint64_destroy(&del_interfaceids);
zbx_vector_uint64_destroy(&del_hosttemplateids);
}
diff --git a/src/zabbix_server/lld/lld_host.c b/src/zabbix_server/lld/lld_host.c
index 1e1a96c55b2..45502dcc33e 100644
--- a/src/zabbix_server/lld/lld_host.c
+++ b/src/zabbix_server/lld/lld_host.c
@@ -145,6 +145,9 @@ typedef struct
}
zbx_lld_interface_t;
+ZBX_PTR_VECTOR_DECL(lld_interface, zbx_lld_interface_t *)
+ZBX_PTR_VECTOR_IMPL(lld_interface, zbx_lld_interface_t *)
+
static void lld_interface_free(zbx_lld_interface_t *interface)
{
zbx_free(interface->port);
@@ -3795,152 +3798,265 @@ static void lld_interfaces_get(zbx_uint64_t id, zbx_vector_ptr_t *interfaces, un
zbx_vector_ptr_sort(interfaces, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
}
-static void lld_interface_make(zbx_vector_ptr_t *interfaces, zbx_uint64_t parent_interfaceid,
- zbx_uint64_t interfaceid, unsigned char type, unsigned char main, unsigned char useip, const char *ip,
- const char *dns, const char *port, unsigned char snmp_type, unsigned char bulk, const char *community,
- const char *securityname, unsigned char securitylevel, const char *authpassphrase,
- const char *privpassphrase, unsigned char authprotocol, unsigned char privprotocol,
- const char *contextname)
+/******************************************************************************
+ * *
+ * Purpose: check if two interfaces match by comparing all fields (including *
+ * prototype interface id) *
+ * *
+ * Parameters: ifold - [IN] the old (existing) interface *
+ * ifnew - [IN] the new (discovered) interface *
+ * *
+ * Return value: The interface fields update bitmask in low 32 bits and *
+ * snmp fields update bitmask in high 32 bits *
+ * *
+ ******************************************************************************/
+static zbx_uint64_t lld_interface_compare(const zbx_lld_interface_t *ifold, const zbx_lld_interface_t *ifnew)
{
- zbx_lld_interface_t *interface = NULL;
- int i, interface_found = 0;
+ zbx_uint64_t flags = 0, snmp_flags = 0;
- for (i = 0; i < interfaces->values_num; i++)
- {
- interface = (zbx_lld_interface_t *)interfaces->values[i];
+ if (ifold->type != ifnew->type)
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_TYPE;
- if (0 != interface->interfaceid)
- continue;
+ if (ifold->main != ifnew->main)
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_MAIN;
- if (interface->parent_interfaceid == parent_interfaceid)
- {
- interface_found = 1;
- break;
- }
+ if (ifold->useip != ifnew->useip)
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_USEIP;
+
+ if (0 != strcmp(ifold->ip, ifnew->ip))
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_IP;
+
+ if (0 != strcmp(ifold->dns, ifnew->dns))
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_DNS;
+
+ if (0 != strcmp(ifold->port, ifnew->port))
+ flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_PORT;
+
+ if (ifold->flags != ifnew->flags)
+ {
+ if (0 == ifold->flags)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_CREATE;
+ else
+ flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_REMOVE;
+
+ /* Add all field update to make snmp type change low priority match. */
+ /* When saving create/remove flags are checked before update, so */
+ /* adding update flags won't affect interface saving. */
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE;
}
- if (0 == interface_found)
+ if (INTERFACE_TYPE_SNMP == ifold->type && INTERFACE_TYPE_SNMP == ifnew->type)
{
- /* interface should be deleted */
- interface = (zbx_lld_interface_t *)zbx_malloc(NULL, sizeof(zbx_lld_interface_t));
+ if (ifold->data.snmp->version != ifnew->data.snmp->version)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_TYPE;
- interface->interfaceid = interfaceid;
- interface->parent_interfaceid = 0;
- interface->type = type;
- interface->main = main;
- interface->useip = 0;
- interface->ip = NULL;
- interface->dns = NULL;
- interface->port = NULL;
- interface->ip_orig = NULL;
- interface->dns_orig = NULL;
- interface->port_orig = NULL;
- interface->data.snmp = NULL;
- interface->main_orig = main;
- interface->type_orig = type;
- interface->useip_orig = 0;
- interface->flags = ZBX_FLAG_LLD_INTERFACE_REMOVE;
+ if (ifold->data.snmp->bulk != ifnew->data.snmp->bulk)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_BULK;
- zbx_vector_ptr_append(interfaces, interface);
+ if (0 != strcmp(ifold->data.snmp->community, ifnew->data.snmp->community))
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_COMMUNITY;
+
+ if (0 != strcmp(ifold->data.snmp->securityname, ifnew->data.snmp->securityname))
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECNAME;
+
+ if (ifold->data.snmp->securitylevel != ifnew->data.snmp->securitylevel)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECLEVEL;
+
+ if (0 != strcmp(ifold->data.snmp->authpassphrase, ifnew->data.snmp->authpassphrase))
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPASS;
+
+ if (0 != strcmp(ifold->data.snmp->privpassphrase, ifnew->data.snmp->privpassphrase))
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPASS;
+
+ if (ifold->data.snmp->authprotocol != ifnew->data.snmp->authprotocol)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPROTOCOL;
+
+ if (ifold->data.snmp->privprotocol != ifnew->data.snmp->privprotocol)
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPROTOCOL;
+
+ if (0 != strcmp(ifold->data.snmp->contextname, ifnew->data.snmp->contextname))
+ snmp_flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_CONTEXT;
}
- else
+
+ return (snmp_flags << 32) | flags;
+}
+
+typedef struct
+{
+ zbx_lld_interface_t *ifold;
+ zbx_lld_interface_t *ifnew;
+ int diff_num;
+ zbx_uint64_t flags;
+}
+zbx_if_update_t;
+
+ZBX_PTR_VECTOR_DECL(if_update, zbx_if_update_t *)
+ZBX_PTR_VECTOR_IMPL(if_update, zbx_if_update_t *)
+
+static int lld_if_update_compare(const void *d1, const void *d2)
+{
+ const zbx_if_update_t *u1 = *(const zbx_if_update_t * const *)d1;
+ const zbx_if_update_t *u2 = *(const zbx_if_update_t * const *)d2;
+
+ return u1->diff_num - u2->diff_num;
+}
+
+static zbx_uint64_t popcount64(zbx_uint64_t mask)
+{
+ mask -= (mask >> 1) & __UINT64_C(0x5555555555555555);
+ mask = (mask & __UINT64_C(0x3333333333333333)) + (mask >> 2 & __UINT64_C(0x3333333333333333));
+ return ((mask + (mask >> 4)) & __UINT64_C(0xf0f0f0f0f0f0f0f)) * __UINT64_C(0x101010101010101) >> 56;
+}
+
+static void lld_interfaces_link(const zbx_lld_interface_t *ifold, zbx_lld_interface_t *ifnew, zbx_uint64_t flags)
+{
+ ifnew->interfaceid = ifold->interfaceid;
+ ifnew->flags |= (flags & 0xffffffff);
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_TYPE))
+ ifnew->type_orig = ifold->type;
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_MAIN))
+ ifnew->main_orig = ifold->main;
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_USEIP))
+ ifnew->useip_orig = ifold->useip;
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_IP))
+ ifnew->ip_orig = zbx_strdup(NULL, ifold->ip);
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_DNS))
+ ifnew->dns_orig = zbx_strdup(NULL, ifold->dns);
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_UPDATE_PORT))
+ ifnew->port_orig = zbx_strdup(NULL, ifold->port);
+
+ if (0 != (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_DATA_EXISTS))
{
- /* interface already has been added */
- if (interface->type != type)
+ ifnew->data.snmp->flags |= (flags >> 32);
+
+ if (0 == (ifnew->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_CREATE))
{
- interface->type_orig = type;
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_TYPE;
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_TYPE))
+ ifnew->data.snmp->version_orig = ifold->data.snmp->version;
- if (INTERFACE_TYPE_SNMP == type)
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_REMOVE;
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_BULK))
+ ifnew->data.snmp->bulk_orig = ifold->data.snmp->bulk;
- if (INTERFACE_TYPE_SNMP == interface->type)
- interface->data.snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_CREATE;
- }
- if (interface->main != main)
- {
- interface->main_orig = main;
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_MAIN;
- }
- if (interface->useip != useip)
- {
- interface->useip_orig = useip;
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_USEIP;
- }
- if (0 != strcmp(interface->ip, ip))
- {
- interface->ip_orig = zbx_strdup(NULL, ip);
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_IP;
- }
- if (0 != strcmp(interface->dns, dns))
- {
- interface->dns_orig = zbx_strdup(NULL, dns);
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_DNS;
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_COMMUNITY))
+ ifnew->data.snmp->community_orig = zbx_strdup(NULL, ifold->data.snmp->community);
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECNAME))
+ ifnew->data.snmp->securityname_orig = zbx_strdup(NULL, ifold->data.snmp->securityname);
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECLEVEL))
+ ifnew->data.snmp->securitylevel_orig = ifold->data.snmp->securitylevel;
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPASS))
+ ifnew->data.snmp->authpassphrase_orig = zbx_strdup(NULL, ifold->data.snmp->authpassphrase);
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPASS))
+ ifnew->data.snmp->privpassphrase_orig = zbx_strdup(NULL, ifold->data.snmp->privpassphrase);
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPROTOCOL))
+ ifnew->data.snmp->authprotocol_orig = ifold->data.snmp->authprotocol;
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPROTOCOL))
+ ifnew->data.snmp->privprotocol_orig = ifold->data.snmp->privprotocol;
+
+ if (0 != (ifnew->data.snmp->flags & ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_CONTEXT))
+ ifnew->data.snmp->contextname_orig = zbx_strdup(NULL, ifold->data.snmp->contextname);
}
- if (0 != strcmp(interface->port, port))
+ }
+}
+
+static void lld_host_interfaces_make(zbx_uint64_t hostid, zbx_vector_ptr_t *hosts,
+ zbx_vector_lld_interface_t *interfaces)
+{
+ int i, j;
+ zbx_lld_host_t *host;
+ zbx_if_update_t *update;
+ zbx_vector_if_update_t updates;
+
+ if (FAIL == (i = zbx_vector_ptr_bsearch(hosts, &hostid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
+ {
+ zbx_vector_lld_interface_clear_ext(interfaces, lld_interface_free);
+ THIS_SHOULD_NEVER_HAPPEN;
+ return;
+ }
+
+ host = (zbx_lld_host_t *)hosts->values[i];
+
+ /* prepare old-new interface match matrix as vector, sorted by least number of unmatched fields */
+
+ zbx_vector_if_update_create(&updates);
+
+ for (i = 0; i < host->interfaces.values_num; i++)
+ {
+ zbx_lld_interface_t *ifnew = (zbx_lld_interface_t *)host->interfaces.values[i];
+
+ for (j = 0; j < interfaces->values_num; j++)
{
- interface->port_orig = zbx_strdup(NULL, port);
- interface->flags |= ZBX_FLAG_LLD_INTERFACE_UPDATE_PORT;
+ if (ifnew->parent_interfaceid != interfaces->values[j]->parent_interfaceid)
+ continue;
+
+ update = (zbx_if_update_t *)zbx_malloc(NULL, sizeof(zbx_if_update_t));
+ update->ifnew = ifnew;
+ update->ifold = interfaces->values[j];
+ update->flags = lld_interface_compare(update->ifold, update->ifnew);
+ update->diff_num = popcount64(update->flags);
+
+ zbx_vector_if_update_append(&updates, update);
}
+ }
- if (INTERFACE_TYPE_SNMP == interface->type && interface->type == type)
- {
- zbx_lld_interface_snmp_t *snmp = interface->data.snmp;
+ zbx_vector_if_update_sort(&updates, lld_if_update_compare);
- if (snmp->version != snmp_type)
- {
- snmp->version_orig = snmp_type;
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_TYPE;
- }
- if (snmp->bulk != bulk)
- {
- snmp->bulk_orig = bulk;
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_BULK;
- }
- if (0 != strcmp(snmp->community, community))
- {
- snmp->community_orig = zbx_strdup(NULL, community);
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_COMMUNITY;
- }
- if (0 != strcmp(snmp->securityname, securityname))
- {
- snmp->securityname_orig = zbx_strdup(NULL, securityname);
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECNAME;
- }
- if (snmp->securitylevel != securitylevel)
- {
- snmp->securitylevel_orig = securitylevel;
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_SECLEVEL;
- }
- if (0 != strcmp(snmp->authpassphrase, authpassphrase))
- {
- snmp->authpassphrase_orig = zbx_strdup(NULL, authpassphrase);
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPASS;
- }
- if (0 != strcmp(snmp->privpassphrase, privpassphrase))
- {
- snmp->privpassphrase_orig = zbx_strdup(NULL, privpassphrase);
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPASS;
- }
- if (snmp->authprotocol != authprotocol)
- {
- snmp->authprotocol_orig = authprotocol;
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_AUTHPROTOCOL;
- }
- if (snmp->privprotocol != privprotocol)
+ /* update new interface id to matching old interface id and set update flags accordingly */
+
+ while (0 != updates.values_num)
+ {
+ update = updates.values[0];
+
+ lld_interfaces_link(update->ifold, update->ifnew, update->flags);
+
+ zbx_vector_if_update_remove(&updates, 0);
+
+ for (i = 0; i < updates.values_num;)
+ {
+ if (update->ifnew == updates.values[i]->ifnew || update->ifold == updates.values[i]->ifold)
{
- snmp->privprotocol_orig = privprotocol;
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_PRIVPROTOCOL;
+ zbx_free(updates.values[i]);
+ zbx_vector_if_update_remove(&updates, i);
}
- if (0 != strcmp(snmp->contextname, contextname))
+ else
+ i++;
+ }
+
+ for (i = 0; i < interfaces->values_num;)
+ {
+ if (interfaces->values[i] == update->ifold)
{
- snmp->contextname_orig = zbx_strdup(NULL, contextname);
- snmp->flags |= ZBX_FLAG_LLD_INTERFACE_SNMP_UPDATE_CONTEXT;
+ lld_interface_free(interfaces->values[i]);
+ zbx_vector_lld_interface_remove_noorder(interfaces, i);
+ break;
}
+ else
+ i++;
}
+
+ zbx_free(update);
}
- interface->interfaceid = interfaceid;
+ /* mark leftover old interfaces to be removed */
+
+ for (i = 0; i < interfaces->values_num; i++)
+ interfaces->values[i]->flags |= ZBX_FLAG_LLD_INTERFACE_REMOVE;
+
+ zbx_vector_ptr_append_array(&host->interfaces, (void **)interfaces->values, interfaces->values_num);
+ zbx_vector_lld_interface_clear(interfaces);
+
+ zbx_vector_if_update_destroy(&updates);
}
/******************************************************************************
@@ -3959,7 +4075,7 @@ static void lld_interfaces_make(const zbx_vector_ptr_t *interfaces, zbx_vector_p
DB_ROW row;
int i, j;
zbx_vector_uint64_t hostids;
- zbx_uint64_t parent_interfaceid, hostid, interfaceid;
+ zbx_uint64_t hostid;
zbx_lld_host_t *host;
zbx_lld_interface_t *new_interface, *interface;
@@ -4056,8 +4172,12 @@ static void lld_interfaces_make(const zbx_vector_ptr_t *interfaces, zbx_vector_p
if (0 != hostids.values_num)
{
- char *sql = NULL;
- size_t sql_alloc = 0, sql_offset = 0;
+ char *sql = NULL;
+ size_t sql_alloc = 0, sql_offset = 0;
+ zbx_vector_lld_interface_t old_interfaces;
+ zbx_uint64_t last_hostid = 0;
+
+ zbx_vector_lld_interface_create(&old_interfaces);
zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
"select hi.hostid,id.parent_interfaceid,hi.interfaceid,hi.type,hi.main,hi.useip,hi.ip,"
@@ -4070,6 +4190,7 @@ static void lld_interfaces_make(const zbx_vector_ptr_t *interfaces, zbx_vector_p
" on hi.interfaceid=s.interfaceid"
" where");
DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "hi.hostid", hostids.values, hostids.values_num);
+ zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by hi.hostid");
result = DBselect("%s", sql);
@@ -4077,39 +4198,61 @@ static void lld_interfaces_make(const zbx_vector_ptr_t *interfaces, zbx_vector_p
while (NULL != (row = DBfetch(result)))
{
- unsigned char interface_type;
-
ZBX_STR2UINT64(hostid, row[0]);
- ZBX_DBROW2UINT64(parent_interfaceid, row[1]);
- ZBX_DBROW2UINT64(interfaceid, row[2]);
- if (FAIL == (i = zbx_vector_ptr_bsearch(hosts, &hostid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
- {
- THIS_SHOULD_NEVER_HAPPEN;
- continue;
- }
+ if (0 != last_hostid && hostid != last_hostid)
+ lld_host_interfaces_make(last_hostid, hosts, &old_interfaces);
- host = (zbx_lld_host_t *)hosts->values[i];
- ZBX_STR2UCHAR(interface_type, row[3]);
+ last_hostid = hostid;
+
+ interface = (zbx_lld_interface_t *)zbx_malloc(NULL, sizeof(zbx_lld_interface_t));
+ memset(interface, 0, sizeof(zbx_lld_interface_t));
+
+ ZBX_DBROW2UINT64(interface->parent_interfaceid, row[1]);
+ ZBX_DBROW2UINT64(interface->interfaceid, row[2]);
+ ZBX_STR2UCHAR(interface->type, row[3]);
+ ZBX_STR2UCHAR(interface->main, row[4]);
+ ZBX_STR2UCHAR(interface->useip, row[5]);
+ interface->ip = zbx_strdup(NULL, row[6]);
+ interface->dns = zbx_strdup(NULL, row[7]);
+ interface->port = zbx_strdup(NULL, row[8]);
- if (INTERFACE_TYPE_SNMP == interface_type)
+ if (INTERFACE_TYPE_SNMP == interface->type)
{
- lld_interface_make(&host->interfaces, parent_interfaceid, interfaceid,
- interface_type, (unsigned char)atoi(row[4]),
- (unsigned char)atoi(row[5]), row[6], row[7], row[8],
- (unsigned char)atoi(row[9]), (unsigned char)atoi(row[10]), row[11],
- row[12], (unsigned char)atoi(row[13]), row[14], row[15],
- (unsigned char)atoi(row[16]), (unsigned char)atoi(row[17]), row[18]);
+ zbx_lld_interface_snmp_t *snmp;
+
+ snmp = (zbx_lld_interface_snmp_t *)zbx_malloc(NULL, sizeof(zbx_lld_interface_snmp_t));
+ memset(snmp, 0, sizeof(zbx_lld_interface_snmp_t));
+
+ ZBX_STR2UCHAR(snmp->version, row[9]);
+ ZBX_STR2UCHAR(snmp->bulk, row[10]);
+ snmp->community = zbx_strdup(NULL, row[11]);
+ snmp->securityname = zbx_strdup(NULL, row[12]);
+ ZBX_STR2UCHAR(snmp->securitylevel, row[13]);
+ snmp->authpassphrase = zbx_strdup(NULL, row[14]);
+ snmp->privpassphrase = zbx_strdup(NULL, row[15]);
+ ZBX_STR2UCHAR(snmp->authprotocol, row[16]);
+ ZBX_STR2UCHAR(snmp->privprotocol, row[17]);
+ snmp->contextname = zbx_strdup(NULL, row[18]);
+
+ snmp->flags = 0x00;
+ interface->flags = ZBX_FLAG_LLD_INTERFACE_SNMP_DATA_EXISTS;
+ interface->data.snmp = snmp;
}
else
{
- lld_interface_make(&host->interfaces, parent_interfaceid, interfaceid,
- interface_type, (unsigned char)atoi(row[4]),
- (unsigned char)atoi(row[5]), row[6], row[7], row[8],
- 0, 0, NULL, NULL, 0, NULL, NULL,0, 0, NULL);
+ interface->flags = 0x00;
+ interface->data.snmp = NULL;
}
+
+ zbx_vector_lld_interface_append(&old_interfaces, interface);
}
DBfree_result(result);
+
+ if (0 != old_interfaces.values_num)
+ lld_host_interfaces_make(last_hostid, hosts, &old_interfaces);
+
+ zbx_vector_lld_interface_destroy(&old_interfaces);
}
zbx_vector_uint64_destroy(&hostids);
diff --git a/src/zabbix_server/operations.c b/src/zabbix_server/operations.c
index 197fd6f809b..309814fb22c 100644
--- a/src/zabbix_server/operations.c
+++ b/src/zabbix_server/operations.c
@@ -300,12 +300,13 @@ static zbx_uint64_t add_discovered_host(const ZBX_DB_EVENT *event, int *status,
" where h.hostid=i.hostid"
" and i.ip=ds.ip"
" and h.status in (%d,%d)"
+ " and h.flags<>%d"
" and h.proxy_hostid%s"
" and ds.dhostid=" ZBX_FS_UI64
- " and h.flags <> %d"
" order by h.hostid",
HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
- DBsql_id_cmp(proxy_hostid), dhostid, ZBX_FLAG_DISCOVERY_PROTOTYPE);
+ ZBX_FLAG_DISCOVERY_PROTOTYPE,
+ DBsql_id_cmp(proxy_hostid), dhostid);
if (NULL != (row2 = DBfetch(result2)))
{