1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 **/
19
20 #include "lld.h"
21 #include "db.h"
22 #include "log.h"
23 #include "zbxalgo.h"
24 #include "zbxserver.h"
25
26 typedef struct
27 {
28 zbx_uint64_t itemid;
29 zbx_uint64_t valuemapid;
30 zbx_uint64_t interfaceid;
31 char *name;
32 char *key;
33 char *delay_flex;
34 char *trapper_hosts;
35 char *units;
36 char *formula;
37 char *logtimefmt;
38 char *params;
39 char *ipmi_sensor;
40 char *snmp_community;
41 char *snmp_oid;
42 char *snmpv3_securityname;
43 char *snmpv3_authpassphrase;
44 char *snmpv3_privpassphrase;
45 char *snmpv3_contextname;
46 char *username;
47 char *password;
48 char *publickey;
49 char *privatekey;
50 char *description;
51 char *port;
52 int delay;
53 int history;
54 int trends;
55 unsigned char type;
56 unsigned char value_type;
57 unsigned char data_type;
58 unsigned char status;
59 unsigned char multiplier;
60 unsigned char delta;
61 unsigned char snmpv3_securitylevel;
62 unsigned char snmpv3_authprotocol;
63 unsigned char snmpv3_privprotocol;
64 unsigned char authtype;
65 zbx_vector_ptr_t lld_rows;
66 zbx_vector_ptr_t applications;
67 }
68 zbx_lld_item_prototype_t;
69
70 typedef struct
71 {
72 zbx_uint64_t itemid;
73 zbx_uint64_t parent_itemid;
74 #define ZBX_FLAG_LLD_ITEM_UNSET __UINT64_C(0x0000000000000000)
75 #define ZBX_FLAG_LLD_ITEM_DISCOVERED __UINT64_C(0x0000000000000001)
76 #define ZBX_FLAG_LLD_ITEM_UPDATE_NAME __UINT64_C(0x0000000000000002)
77 #define ZBX_FLAG_LLD_ITEM_UPDATE_KEY __UINT64_C(0x0000000000000004)
78 #define ZBX_FLAG_LLD_ITEM_UPDATE_TYPE __UINT64_C(0x0000000000000008)
79 #define ZBX_FLAG_LLD_ITEM_UPDATE_VALUE_TYPE __UINT64_C(0x0000000000000010)
80 #define ZBX_FLAG_LLD_ITEM_UPDATE_DATA_TYPE __UINT64_C(0x0000000000000020)
81 #define ZBX_FLAG_LLD_ITEM_UPDATE_DELAY __UINT64_C(0x0000000000000040)
82 #define ZBX_FLAG_LLD_ITEM_UPDATE_DELAY_FLEX __UINT64_C(0x0000000000000080)
83 #define ZBX_FLAG_LLD_ITEM_UPDATE_HISTORY __UINT64_C(0x0000000000000100)
84 #define ZBX_FLAG_LLD_ITEM_UPDATE_TRENDS __UINT64_C(0x0000000000000200)
85 #define ZBX_FLAG_LLD_ITEM_UPDATE_TRAPPER_HOSTS __UINT64_C(0x0000000000000400)
86 #define ZBX_FLAG_LLD_ITEM_UPDATE_UNITS __UINT64_C(0x0000000000000800)
87 #define ZBX_FLAG_LLD_ITEM_UPDATE_MULTIPLIER __UINT64_C(0x0000000000001000)
88 #define ZBX_FLAG_LLD_ITEM_UPDATE_DELTA __UINT64_C(0x0000000000002000)
89 #define ZBX_FLAG_LLD_ITEM_UPDATE_FORMULA __UINT64_C(0x0000000000004000)
90 #define ZBX_FLAG_LLD_ITEM_UPDATE_LOGTIMEFMT __UINT64_C(0x0000000000008000)
91 #define ZBX_FLAG_LLD_ITEM_UPDATE_VALUEMAPID __UINT64_C(0x0000000000010000)
92 #define ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS __UINT64_C(0x0000000000020000)
93 #define ZBX_FLAG_LLD_ITEM_UPDATE_IPMI_SENSOR __UINT64_C(0x0000000000040000)
94 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_COMMUNITY __UINT64_C(0x0000000000080000)
95 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID __UINT64_C(0x0000000000100000)
96 #define ZBX_FLAG_LLD_ITEM_UPDATE_PORT __UINT64_C(0x0000000000200000)
97 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYNAME __UINT64_C(0x0000000000400000)
98 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYLEVEL __UINT64_C(0x0000000000800000)
99 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPROTOCOL __UINT64_C(0x0000000001000000)
100 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPASSPHRASE __UINT64_C(0x0000000002000000)
101 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPROTOCOL __UINT64_C(0x0000000004000000)
102 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPASSPHRASE __UINT64_C(0x0000000008000000)
103 #define ZBX_FLAG_LLD_ITEM_UPDATE_AUTHTYPE __UINT64_C(0x0000000010000000)
104 #define ZBX_FLAG_LLD_ITEM_UPDATE_USERNAME __UINT64_C(0x0000000020000000)
105 #define ZBX_FLAG_LLD_ITEM_UPDATE_PASSWORD __UINT64_C(0x0000000040000000)
106 #define ZBX_FLAG_LLD_ITEM_UPDATE_PUBLICKEY __UINT64_C(0x0000000080000000)
107 #define ZBX_FLAG_LLD_ITEM_UPDATE_PRIVATEKEY __UINT64_C(0x0000000100000000)
108 #define ZBX_FLAG_LLD_ITEM_UPDATE_DESCRIPTION __UINT64_C(0x0000000200000000)
109 #define ZBX_FLAG_LLD_ITEM_UPDATE_INTERFACEID __UINT64_C(0x0000000400000000)
110 #define ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_CONTEXTNAME __UINT64_C(0x0000000800000000)
111 #define ZBX_FLAG_LLD_ITEM_UPDATE \
112 (ZBX_FLAG_LLD_ITEM_UPDATE_NAME | ZBX_FLAG_LLD_ITEM_UPDATE_KEY | ZBX_FLAG_LLD_ITEM_UPDATE_TYPE | \
113 ZBX_FLAG_LLD_ITEM_UPDATE_VALUE_TYPE | ZBX_FLAG_LLD_ITEM_UPDATE_DATA_TYPE | \
114 ZBX_FLAG_LLD_ITEM_UPDATE_DELAY | ZBX_FLAG_LLD_ITEM_UPDATE_DELAY_FLEX | \
115 ZBX_FLAG_LLD_ITEM_UPDATE_HISTORY | ZBX_FLAG_LLD_ITEM_UPDATE_TRENDS | \
116 ZBX_FLAG_LLD_ITEM_UPDATE_TRAPPER_HOSTS | ZBX_FLAG_LLD_ITEM_UPDATE_UNITS | \
117 ZBX_FLAG_LLD_ITEM_UPDATE_MULTIPLIER | ZBX_FLAG_LLD_ITEM_UPDATE_DELTA | \
118 ZBX_FLAG_LLD_ITEM_UPDATE_FORMULA | ZBX_FLAG_LLD_ITEM_UPDATE_LOGTIMEFMT | \
119 ZBX_FLAG_LLD_ITEM_UPDATE_VALUEMAPID | ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS | \
120 ZBX_FLAG_LLD_ITEM_UPDATE_IPMI_SENSOR | ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_COMMUNITY | \
121 ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID | ZBX_FLAG_LLD_ITEM_UPDATE_PORT | \
122 ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYNAME | ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYLEVEL | \
123 ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPROTOCOL | ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPASSPHRASE | \
124 ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPROTOCOL | ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPASSPHRASE | \
125 ZBX_FLAG_LLD_ITEM_UPDATE_AUTHTYPE | ZBX_FLAG_LLD_ITEM_UPDATE_USERNAME | \
126 ZBX_FLAG_LLD_ITEM_UPDATE_PASSWORD | ZBX_FLAG_LLD_ITEM_UPDATE_PUBLICKEY | \
127 ZBX_FLAG_LLD_ITEM_UPDATE_PRIVATEKEY | ZBX_FLAG_LLD_ITEM_UPDATE_DESCRIPTION | \
128 ZBX_FLAG_LLD_ITEM_UPDATE_INTERFACEID | ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_CONTEXTNAME)
129 zbx_uint64_t flags;
130 char *key_proto;
131 char *name;
132 char *name_proto;
133 char *key;
134 char *key_orig;
135 char *units;
136 char *units_orig;
137 char *params;
138 char *params_orig;
139 char *ipmi_sensor;
140 char *ipmi_sensor_orig;
141 char *snmp_oid;
142 char *snmp_oid_orig;
143 char *description;
144 char *description_orig;
145 int lastcheck;
146 int ts_delete;
147 const zbx_lld_row_t *lld_row;
148 }
149 zbx_lld_item_t;
150
151 /* item index by prototype (parent) id and lld row */
152 typedef struct
153 {
154 zbx_uint64_t parent_itemid;
155 zbx_lld_row_t *lld_row;
156 zbx_lld_item_t *item;
157 }
158 zbx_lld_item_index_t;
159
160 typedef struct
161 {
162 zbx_uint64_t application_prototypeid;
163 zbx_uint64_t itemid;
164 char *name;
165 }
166 zbx_lld_application_prototype_t;
167
168 typedef struct
169 {
170 zbx_uint64_t applicationid;
171 zbx_uint64_t application_prototypeid;
172 zbx_uint64_t application_discoveryid;
173 int lastcheck;
174 int ts_delete;
175 #define ZBX_FLAG_LLD_APPLICATION_UNSET __UINT64_C(0x0000000000000000)
176 #define ZBX_FLAG_LLD_APPLICATION_DISCOVERED __UINT64_C(0x0000000000000001)
177 #define ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME __UINT64_C(0x0000000000000002)
178 #define ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY __UINT64_C(0x0000000100000000)
179 #define ZBX_FLAG_LLD_APPLICATION_REMOVE_DISCOVERY __UINT64_C(0x0000000200000000)
180 #define ZBX_FLAG_LLD_APPLICATION_REMOVE __UINT64_C(0x0000000400000000)
181 zbx_uint64_t flags;
182 char *name;
183 char *name_proto;
184 char *name_orig;
185 const zbx_lld_row_t *lld_row;
186 }
187 zbx_lld_application_t;
188
189 /* reference to an item either by its id (existing items) or structure (new items) */
190 typedef struct
191 {
192 zbx_uint64_t itemid;
193 zbx_lld_item_t *item;
194 }
195 zbx_lld_item_ref_t;
196
197 /* reference to an application either by its id (existing applications) or structure (new applications) */
198 typedef struct
199 {
200 zbx_uint64_t applicationid;
201 zbx_lld_application_t *application;
202 }
203 zbx_lld_application_ref_t;
204
205 /* item prototype-application link reference by application id (existing applications) */
206 /* or application prototype structure (application prototypes) */
207 typedef struct
208 {
209 zbx_lld_application_prototype_t *application_prototype;
210 zbx_uint64_t applicationid;
211 }
212 zbx_lld_item_application_ref_t;
213
214 /* item-application link */
215 typedef struct
216 {
217 zbx_uint64_t itemappid;
218 zbx_lld_item_ref_t item_ref;
219 zbx_lld_application_ref_t application_ref;
220 #define ZBX_FLAG_LLD_ITEM_APPLICATION_UNSET __UINT64_C(0x0000000000000000)
221 #define ZBX_FLAG_LLD_ITEM_APPLICATION_DISCOVERED __UINT64_C(0x0000000000000001)
222 zbx_uint64_t flags;
223 }
224 zbx_lld_item_application_t;
225
226 /* application index by prototypeid and lld row */
227 typedef struct
228 {
229 zbx_uint64_t application_prototypeid;
230 const zbx_lld_row_t *lld_row;
231 zbx_lld_application_t *application;
232 }
233 zbx_lld_application_index_t;
234
235 /* items index hashset support functions */
lld_item_index_hash_func(const void * data)236 static zbx_hash_t lld_item_index_hash_func(const void *data)
237 {
238 zbx_lld_item_index_t *item_index = (zbx_lld_item_index_t *)data;
239 zbx_hash_t hash;
240
241 hash = ZBX_DEFAULT_UINT64_HASH_ALGO(&item_index->parent_itemid,
242 sizeof(item_index->parent_itemid), ZBX_DEFAULT_HASH_SEED);
243 return ZBX_DEFAULT_PTR_HASH_ALGO(&item_index->lld_row, sizeof(item_index->lld_row), hash);
244 }
245
lld_item_index_compare_func(const void * d1,const void * d2)246 static int lld_item_index_compare_func(const void *d1, const void *d2)
247 {
248 zbx_lld_item_index_t *i1 = (zbx_lld_item_index_t *)d1;
249 zbx_lld_item_index_t *i2 = (zbx_lld_item_index_t *)d2;
250
251 ZBX_RETURN_IF_NOT_EQUAL(i1->parent_itemid, i2->parent_itemid);
252 ZBX_RETURN_IF_NOT_EQUAL(i1->lld_row, i2->lld_row);
253
254 return 0;
255 }
256
257 /* application index hashset support functions */
lld_application_index_hash_func(const void * data)258 static zbx_hash_t lld_application_index_hash_func(const void *data)
259 {
260 zbx_lld_application_index_t *application_index = (zbx_lld_application_index_t *)data;
261 zbx_hash_t hash;
262
263 hash = ZBX_DEFAULT_UINT64_HASH_ALGO(&application_index->application_prototypeid,
264 sizeof(application_index->application_prototypeid), ZBX_DEFAULT_HASH_SEED);
265 return ZBX_DEFAULT_PTR_HASH_ALGO(&application_index->lld_row, sizeof(application_index->lld_row), hash);
266 }
267
lld_application_index_compare_func(const void * d1,const void * d2)268 static int lld_application_index_compare_func(const void *d1, const void *d2)
269 {
270 zbx_lld_application_index_t *i1 = (zbx_lld_application_index_t *)d1;
271 zbx_lld_application_index_t *i2 = (zbx_lld_application_index_t *)d2;
272
273 ZBX_RETURN_IF_NOT_EQUAL(i1->application_prototypeid, i2->application_prototypeid);
274 ZBX_RETURN_IF_NOT_EQUAL(i1->lld_row, i2->lld_row);
275
276 return 0;
277 }
278
279 /* comparison function for discovered application lookup by name */
lld_application_compare_name(const void * d1,const void * d2)280 static int lld_application_compare_name(const void *d1, const void *d2)
281 {
282 const zbx_lld_application_t *a1 = *(zbx_lld_application_t **)d1;
283 const zbx_lld_application_t *a2 = *(zbx_lld_application_t **)d2;
284
285 if (0 == (a1->flags & a2->flags))
286 return -1;
287
288 if (NULL == a1->name || NULL == a2->name)
289 return -1;
290
291 return strcmp(a1->name, a2->name);
292 }
293
294 /* comparison function for discovered application lookup by original name name */
lld_application_compare_name_orig(const void * d1,const void * d2)295 static int lld_application_compare_name_orig(const void *d1, const void *d2)
296 {
297 const zbx_lld_application_t *a1 = *(zbx_lld_application_t **)d1;
298 const zbx_lld_application_t *a2 = *(zbx_lld_application_t **)d2;
299
300 if (0 == (a1->flags & a2->flags))
301 return -1;
302
303 if (NULL == a1->name_orig || NULL == a2->name_orig)
304 return -1;
305
306 return strcmp(a1->name_orig, a2->name_orig);
307 }
308
309 /* string pointer hashset (used to check for duplicate item keys) support functions */
lld_items_keys_hash_func(const void * data)310 static zbx_hash_t lld_items_keys_hash_func(const void *data)
311 {
312 return ZBX_DEFAULT_STRING_HASH_FUNC(*(char **)data);
313 }
314
lld_items_keys_compare_func(const void * d1,const void * d2)315 static int lld_items_keys_compare_func(const void *d1, const void *d2)
316 {
317 return ZBX_DEFAULT_STR_COMPARE_FUNC(d1, d2);
318 }
319
320 /* items - applications hashset support */
lld_item_application_hash_func(const void * data)321 static zbx_hash_t lld_item_application_hash_func(const void *data)
322 {
323 const zbx_lld_item_application_t *item_application = data;
324 zbx_hash_t hash;
325
326 hash = ZBX_DEFAULT_HASH_ALGO(&item_application->item_ref, sizeof(item_application->item_ref),
327 ZBX_DEFAULT_HASH_SEED);
328 return ZBX_DEFAULT_HASH_ALGO(&item_application->application_ref, sizeof(item_application->application_ref),
329 hash);
330 }
331
lld_item_application_compare_func(const void * d1,const void * d2)332 static int lld_item_application_compare_func(const void *d1, const void *d2)
333 {
334 const zbx_lld_item_application_t *ia1 = (zbx_lld_item_application_t *)d1;
335 const zbx_lld_item_application_t *ia2 = (zbx_lld_item_application_t *)d2;
336
337 ZBX_RETURN_IF_NOT_EQUAL(ia1->item_ref.itemid, ia2->item_ref.itemid);
338 ZBX_RETURN_IF_NOT_EQUAL(ia1->item_ref.item, ia2->item_ref.item);
339 ZBX_RETURN_IF_NOT_EQUAL(ia1->application_ref.applicationid, ia2->application_ref.applicationid);
340 ZBX_RETURN_IF_NOT_EQUAL(ia1->application_ref.application, ia2->application_ref.application);
341
342 return 0;
343 }
344
lld_application_prototype_free(zbx_lld_application_prototype_t * application_prototype)345 static void lld_application_prototype_free(zbx_lld_application_prototype_t *application_prototype)
346 {
347 zbx_free(application_prototype->name);
348 zbx_free(application_prototype);
349 }
350
lld_application_free(zbx_lld_application_t * application)351 static void lld_application_free(zbx_lld_application_t *application)
352 {
353 zbx_free(application->name_orig);
354 zbx_free(application->name_proto);
355 zbx_free(application->name);
356 zbx_free(application);
357 }
358
lld_item_prototype_free(zbx_lld_item_prototype_t * item_prototype)359 static void lld_item_prototype_free(zbx_lld_item_prototype_t *item_prototype)
360 {
361 zbx_free(item_prototype->name);
362 zbx_free(item_prototype->key);
363 zbx_free(item_prototype->delay_flex);
364 zbx_free(item_prototype->trapper_hosts);
365 zbx_free(item_prototype->units);
366 zbx_free(item_prototype->formula);
367 zbx_free(item_prototype->logtimefmt);
368 zbx_free(item_prototype->params);
369 zbx_free(item_prototype->ipmi_sensor);
370 zbx_free(item_prototype->snmp_community);
371 zbx_free(item_prototype->snmp_oid);
372 zbx_free(item_prototype->snmpv3_securityname);
373 zbx_free(item_prototype->snmpv3_authpassphrase);
374 zbx_free(item_prototype->snmpv3_privpassphrase);
375 zbx_free(item_prototype->snmpv3_contextname);
376 zbx_free(item_prototype->username);
377 zbx_free(item_prototype->password);
378 zbx_free(item_prototype->publickey);
379 zbx_free(item_prototype->privatekey);
380 zbx_free(item_prototype->description);
381 zbx_free(item_prototype->port);
382
383 zbx_vector_ptr_destroy(&item_prototype->lld_rows);
384
385 zbx_vector_ptr_clear_ext(&item_prototype->applications, zbx_default_mem_free_func);
386 zbx_vector_ptr_destroy(&item_prototype->applications);
387
388 zbx_free(item_prototype);
389 }
390
lld_item_free(zbx_lld_item_t * item)391 static void lld_item_free(zbx_lld_item_t *item)
392 {
393 zbx_free(item->key_proto);
394 zbx_free(item->name);
395 zbx_free(item->name_proto);
396 zbx_free(item->key);
397 zbx_free(item->key_orig);
398 zbx_free(item->units);
399 zbx_free(item->units_orig);
400 zbx_free(item->params);
401 zbx_free(item->params_orig);
402 zbx_free(item->ipmi_sensor);
403 zbx_free(item->ipmi_sensor_orig);
404 zbx_free(item->snmp_oid);
405 zbx_free(item->snmp_oid_orig);
406 zbx_free(item->description);
407 zbx_free(item->description_orig);
408 zbx_free(item);
409 }
410
411 /******************************************************************************
412 * *
413 * Function: lld_items_get *
414 * *
415 * Purpose: retrieves existing items for the specified item prototypes *
416 * *
417 * Parameters: item_prototypes - [IN] item prototypes *
418 * items - [OUT] list of items *
419 * *
420 ******************************************************************************/
lld_items_get(const zbx_vector_ptr_t * item_prototypes,zbx_vector_ptr_t * items)421 static void lld_items_get(const zbx_vector_ptr_t *item_prototypes, zbx_vector_ptr_t *items)
422 {
423 const char *__function_name = "lld_items_get";
424
425 DB_RESULT result;
426 DB_ROW row;
427 zbx_lld_item_t *item;
428 zbx_uint64_t db_valuemapid, db_interfaceid;
429 zbx_vector_uint64_t parent_itemids;
430 int i;
431 char *sql = NULL;
432 size_t sql_alloc = 0, sql_offset = 0;
433
434 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
435
436 zbx_vector_uint64_create(&parent_itemids);
437 zbx_vector_uint64_reserve(&parent_itemids, item_prototypes->values_num);
438
439 for (i = 0; i < item_prototypes->values_num; i++)
440 {
441 const zbx_lld_item_prototype_t *item_prototype;
442
443 item_prototype = (const zbx_lld_item_prototype_t *)item_prototypes->values[i];
444
445 zbx_vector_uint64_append(&parent_itemids, item_prototype->itemid);
446 }
447
448 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
449 "select id.itemid,id.key_,id.lastcheck,id.ts_delete,i.name,i.key_,i.type,i.value_type,"
450 "i.data_type,i.delay,i.delay_flex,i.history,i.trends,i.trapper_hosts,i.units,"
451 "i.multiplier,i.delta,i.formula,i.logtimefmt,i.valuemapid,i.params,i.ipmi_sensor,"
452 "i.snmp_community,i.snmp_oid,i.port,i.snmpv3_securityname,i.snmpv3_securitylevel,"
453 "i.snmpv3_authprotocol,i.snmpv3_authpassphrase,i.snmpv3_privprotocol,"
454 "i.snmpv3_privpassphrase,i.authtype,i.username,i.password,i.publickey,i.privatekey,"
455 "i.description,i.interfaceid,i.snmpv3_contextname,id.parent_itemid"
456 " from item_discovery id"
457 " join items i"
458 " on id.itemid=i.itemid"
459 " where");
460
461 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "id.parent_itemid", parent_itemids.values,
462 parent_itemids.values_num);
463
464 zbx_vector_uint64_destroy(&parent_itemids);
465
466 result = DBselect("%s", sql);
467
468 zbx_free(sql);
469
470 while (NULL != (row = DBfetch(result)))
471 {
472 zbx_uint64_t parent_itemid;
473 int index;
474 zbx_lld_item_prototype_t *item_prototype;
475
476 ZBX_STR2UINT64(parent_itemid, row[39]);
477
478 if (FAIL == (index = zbx_vector_ptr_bsearch(item_prototypes, &parent_itemid,
479 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
480 {
481 THIS_SHOULD_NEVER_HAPPEN;
482 continue;
483 }
484
485 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[index];
486
487 item = zbx_malloc(NULL, sizeof(zbx_lld_item_t));
488
489 ZBX_STR2UINT64(item->itemid, row[0]);
490 item->parent_itemid = parent_itemid;
491 item->key_proto = zbx_strdup(NULL, row[1]);
492 item->lastcheck = atoi(row[2]);
493 item->ts_delete = atoi(row[3]);
494 item->name = zbx_strdup(NULL, row[4]);
495 item->name_proto = NULL;
496 item->key = zbx_strdup(NULL, row[5]);
497 item->key_orig = NULL;
498 item->flags = ZBX_FLAG_LLD_ITEM_UNSET;
499
500 if ((unsigned char)atoi(row[6]) != item_prototype->type)
501 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_TYPE;
502
503 if ((unsigned char)atoi(row[7]) != item_prototype->value_type)
504 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_VALUE_TYPE;
505
506 if ((unsigned char)atoi(row[8]) != item_prototype->data_type)
507 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_DATA_TYPE;
508
509 if (atoi(row[9]) != item_prototype->delay)
510 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_DELAY;
511
512 if (0 != strcmp(row[10], item_prototype->delay_flex))
513 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_DELAY_FLEX;
514
515 if (atoi(row[11]) != item_prototype->history)
516 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_HISTORY;
517
518 if (atoi(row[12]) != item_prototype->trends)
519 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_TRENDS;
520
521 if (0 != strcmp(row[13], item_prototype->trapper_hosts))
522 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_TRAPPER_HOSTS;
523
524 item->units = zbx_strdup(NULL, row[14]);
525 item->units_orig = NULL;
526
527 if ((unsigned char)atoi(row[15]) != item_prototype->multiplier)
528 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_MULTIPLIER;
529
530 if ((unsigned char)atoi(row[16]) != item_prototype->delta)
531 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_DELTA;
532
533 if (0 != strcmp(row[17], item_prototype->formula))
534 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_FORMULA;
535
536 if (0 != strcmp(row[18], item_prototype->logtimefmt))
537 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_LOGTIMEFMT;
538
539 ZBX_DBROW2UINT64(db_valuemapid, row[19]);
540 if (db_valuemapid != item_prototype->valuemapid)
541 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_VALUEMAPID;
542
543 item->params = zbx_strdup(NULL, row[20]);
544 item->params_orig = NULL;
545
546 item->ipmi_sensor = zbx_strdup(NULL, row[21]);
547 item->ipmi_sensor_orig = NULL;
548
549 if (0 != strcmp(row[22], item_prototype->snmp_community))
550 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_COMMUNITY;
551
552 item->snmp_oid = zbx_strdup(NULL, row[23]);
553 item->snmp_oid_orig = NULL;
554
555 if (0 != strcmp(row[24], item_prototype->port))
556 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PORT;
557
558 if (0 != strcmp(row[25], item_prototype->snmpv3_securityname))
559 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYNAME;
560
561 if ((unsigned char)atoi(row[26]) != item_prototype->snmpv3_securitylevel)
562 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYLEVEL;
563
564 if ((unsigned char)atoi(row[27]) != item_prototype->snmpv3_authprotocol)
565 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPROTOCOL;
566
567 if (0 != strcmp(row[28], item_prototype->snmpv3_authpassphrase))
568 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPASSPHRASE;
569
570 if ((unsigned char)atoi(row[29]) != item_prototype->snmpv3_privprotocol)
571 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPROTOCOL;
572
573 if (0 != strcmp(row[30], item_prototype->snmpv3_privpassphrase))
574 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPASSPHRASE;
575
576 if ((unsigned char)atoi(row[31]) != item_prototype->authtype)
577 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_AUTHTYPE;
578
579 if (0 != strcmp(row[32], item_prototype->username))
580 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_USERNAME;
581
582 if (0 != strcmp(row[33], item_prototype->password))
583 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PASSWORD;
584
585 if (0 != strcmp(row[34], item_prototype->publickey))
586 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PUBLICKEY;
587
588 if (0 != strcmp(row[35], item_prototype->privatekey))
589 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PRIVATEKEY;
590
591 item->description = zbx_strdup(NULL, row[36]);
592 item->description_orig = NULL;
593
594 ZBX_DBROW2UINT64(db_interfaceid, row[37]);
595 if (db_interfaceid != item_prototype->interfaceid)
596 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_INTERFACEID;
597
598 if (0 != strcmp(row[38], item_prototype->snmpv3_contextname))
599 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_CONTEXTNAME;
600
601 item->lld_row = NULL;
602
603 zbx_vector_ptr_append(items, item);
604 }
605 DBfree_result(result);
606
607 zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
608
609 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
610 }
611
612 /******************************************************************************
613 * *
614 * Function: lld_validate_item_field *
615 * *
616 ******************************************************************************/
lld_validate_item_field(zbx_lld_item_t * item,char ** field,char ** field_orig,zbx_uint64_t flag,size_t field_len,char ** error)617 static void lld_validate_item_field(zbx_lld_item_t *item, char **field, char **field_orig, zbx_uint64_t flag,
618 size_t field_len, char **error)
619 {
620 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
621 return;
622
623 /* only new items or items with changed data will be validated */
624 if (0 != item->itemid && 0 == (item->flags & flag))
625 return;
626
627 if (SUCCEED != zbx_is_utf8(*field))
628 {
629 zbx_replace_invalid_utf8(*field);
630 *error = zbx_strdcatf(*error, "Cannot %s item: value \"%s\" has invalid UTF-8 sequence.\n",
631 (0 != item->itemid ? "update" : "create"), *field);
632 }
633 else if (zbx_strlen_utf8(*field) > field_len)
634 {
635 *error = zbx_strdcatf(*error, "Cannot %s item: value \"%s\" is too long.\n",
636 (0 != item->itemid ? "update" : "create"), *field);
637 }
638 else if (ZBX_FLAG_LLD_ITEM_UPDATE_NAME == flag && '\0' == **field)
639 {
640 *error = zbx_strdcatf(*error, "Cannot %s item: name is empty.\n",
641 (0 != item->itemid ? "update" : "create"));
642 }
643 else
644 return;
645
646 if (0 != item->itemid)
647 lld_field_str_rollback(field, field_orig, &item->flags, flag);
648 else
649 item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
650 }
651
652 /******************************************************************************
653 * *
654 * Function: lld_items_validate *
655 * *
656 * Parameters: items - [IN] list of items; must be sorted by itemid *
657 * *
658 ******************************************************************************/
lld_items_validate(zbx_uint64_t hostid,zbx_vector_ptr_t * items,char ** error)659 static void lld_items_validate(zbx_uint64_t hostid, zbx_vector_ptr_t *items, char **error)
660 {
661 const char *__function_name = "lld_items_validate";
662
663 DB_RESULT result;
664 DB_ROW row;
665 int i;
666 zbx_lld_item_t *item;
667 zbx_vector_uint64_t itemids;
668 zbx_vector_str_t keys;
669 zbx_hashset_t items_keys;
670
671 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
672
673 zbx_vector_uint64_create(&itemids);
674 zbx_vector_str_create(&keys); /* list of item keys */
675
676 /* check an item name validity */
677 for (i = 0; i < items->values_num; i++)
678 {
679 item = (zbx_lld_item_t *)items->values[i];
680
681 lld_validate_item_field(item, &item->name, &item->name_proto,
682 ZBX_FLAG_LLD_ITEM_UPDATE_NAME, ITEM_NAME_LEN, error);
683 lld_validate_item_field(item, &item->key, &item->key_orig,
684 ZBX_FLAG_LLD_ITEM_UPDATE_KEY, ITEM_KEY_LEN, error);
685 lld_validate_item_field(item, &item->units, &item->units_orig,
686 ZBX_FLAG_LLD_ITEM_UPDATE_UNITS, ITEM_UNITS_LEN, error);
687 lld_validate_item_field(item, &item->params, &item->params_orig,
688 ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS, ITEM_PARAM_LEN, error);
689 lld_validate_item_field(item, &item->ipmi_sensor, &item->ipmi_sensor_orig,
690 ZBX_FLAG_LLD_ITEM_UPDATE_IPMI_SENSOR, ITEM_IPMI_SENSOR_LEN, error);
691 lld_validate_item_field(item, &item->snmp_oid, &item->snmp_oid_orig,
692 ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID, ITEM_SNMP_OID_LEN, error);
693 lld_validate_item_field(item, &item->description, &item->description_orig,
694 ZBX_FLAG_LLD_ITEM_UPDATE_DESCRIPTION, ITEM_DESCRIPTION_LEN, error);
695 }
696
697 /* check duplicated item keys */
698
699 zbx_hashset_create(&items_keys, items->values_num, lld_items_keys_hash_func, lld_items_keys_compare_func);
700
701 /* add 'good' (existing, discovered and not updated) keys to the hashset */
702 for (i = 0; i < items->values_num; i++)
703 {
704 item = (zbx_lld_item_t *)items->values[i];
705
706 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
707 continue;
708
709 /* skip new or updated item keys */
710 if (0 == item->itemid || 0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_KEY))
711 continue;
712
713 zbx_hashset_insert(&items_keys, &item->key, sizeof(char *));
714 }
715
716 /* check new and updated keys for duplicated keys in discovered items */
717 for (i = 0; i < items->values_num; i++)
718 {
719 item = (zbx_lld_item_t *)items->values[i];
720
721 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
722 continue;
723
724 /* only new items or items with changed key will be validated */
725 if (0 != item->itemid && 0 == (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_KEY))
726 continue;
727
728 if (NULL != zbx_hashset_search(&items_keys, &item->key))
729 {
730 *error = zbx_strdcatf(*error, "Cannot %s item:"
731 " item with the same key \"%s\" already exists.\n",
732 (0 != item->itemid ? "update" : "create"), item->key);
733
734 if (0 != item->itemid)
735 {
736 lld_field_str_rollback(&item->key, &item->key_orig, &item->flags,
737 ZBX_FLAG_LLD_ITEM_UPDATE_KEY);
738 }
739 else
740 item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
741 }
742 else
743 zbx_hashset_insert(&items_keys, &item->key, sizeof(char *));
744 }
745
746 zbx_hashset_destroy(&items_keys);
747
748 /* check duplicated keys in DB */
749
750 for (i = 0; i < items->values_num; i++)
751 {
752 item = (zbx_lld_item_t *)items->values[i];
753
754 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
755 continue;
756
757 if (0 != item->itemid)
758 zbx_vector_uint64_append(&itemids, item->itemid);
759
760 if (0 != item->itemid && 0 == (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_KEY))
761 continue;
762
763 zbx_vector_str_append(&keys, item->key);
764 }
765
766 if (0 != keys.values_num)
767 {
768 char *sql = NULL;
769 size_t sql_alloc = 256, sql_offset = 0;
770
771 sql = zbx_malloc(sql, sql_alloc);
772
773 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
774 "select key_"
775 " from items"
776 " where hostid=" ZBX_FS_UI64
777 " and",
778 hostid);
779 DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "key_",
780 (const char **)keys.values, keys.values_num);
781
782 if (0 != itemids.values_num)
783 {
784 zbx_vector_uint64_sort(&itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
785 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " and not");
786 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid",
787 itemids.values, itemids.values_num);
788 }
789
790 result = DBselect("%s", sql);
791
792 while (NULL != (row = DBfetch(result)))
793 {
794 for (i = 0; i < items->values_num; i++)
795 {
796 item = (zbx_lld_item_t *)items->values[i];
797
798 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
799 continue;
800
801 if (0 == strcmp(item->key, row[0]))
802 {
803 *error = zbx_strdcatf(*error, "Cannot %s item:"
804 " item with the same key \"%s\" already exists.\n",
805 (0 != item->itemid ? "update" : "create"), item->key);
806
807 if (0 != item->itemid)
808 {
809 lld_field_str_rollback(&item->key, &item->key_orig, &item->flags,
810 ZBX_FLAG_LLD_ITEM_UPDATE_KEY);
811 }
812 else
813 item->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
814
815 continue;
816 }
817 }
818 }
819 DBfree_result(result);
820
821 zbx_free(sql);
822 }
823
824 zbx_vector_str_destroy(&keys);
825 zbx_vector_uint64_destroy(&itemids);
826
827 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
828 }
829
830 /******************************************************************************
831 * *
832 * Function: substitute_formula_macros *
833 * *
834 * Purpose: substitutes lld macros in calculated item formula expression *
835 * *
836 * Parameters: data - [IN/OUT] the expression *
837 * jp_row - [IN] the lld data row *
838 * error - [IN] pointer to string for reporting errors *
839 * max_error_len - [IN] size of 'error' string *
840 * *
841 ******************************************************************************/
substitute_formula_macros(char ** data,const struct zbx_json_parse * jp_row,char * error,size_t max_error_len)842 static int substitute_formula_macros(char **data, const struct zbx_json_parse *jp_row,
843 char *error, size_t max_error_len)
844 {
845 const char *__function_name = "substitute_formula_macros";
846
847 char *exp, *tmp, *e, *p, *param = NULL;
848 size_t exp_alloc = 128, exp_offset = 0, tmp_alloc = 128, tmp_offset = 0, f_pos, par_l, par_r, sep_pos;
849 int ret = FAIL;
850
851 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
852
853 exp = zbx_malloc(NULL, exp_alloc);
854 tmp = zbx_malloc(NULL, tmp_alloc);
855
856 for (e = *data; SUCCEED == zbx_function_find(e, &f_pos, &par_l, &par_r, error, max_error_len); e += par_r + 1)
857 {
858 /* substitute LLD macros in the part of the string preceding function parameters */
859
860 zbx_strncpy_alloc(&tmp, &tmp_alloc, &tmp_offset, e, par_l + 1);
861 if (SUCCEED != substitute_discovery_macros(&tmp, jp_row, ZBX_MACRO_NUMERIC, error, max_error_len))
862 goto out;
863
864 tmp_offset = strlen(tmp);
865 zbx_strncpy_alloc(&exp, &exp_alloc, &exp_offset, tmp, tmp_offset);
866
867 tmp_alloc = tmp_offset + 1;
868 tmp_offset = 0;
869
870 /* substitute LLD macros in function parameters */
871
872 for (p = e + par_l + 1; p < e + par_r; p += sep_pos + 1)
873 {
874 size_t param_pos, param_len;
875 int quoted;
876
877 e[par_r] = '\0';
878 zbx_function_param_parse(p, ¶m_pos, ¶m_len, &sep_pos);
879 e[par_r] = ')';
880
881 /* copy what was before the parameter */
882 zbx_strncpy_alloc(&exp, &exp_alloc, &exp_offset, p, param_pos);
883
884 /* prepare the parameter (macro substitutions and quoting) */
885
886 zbx_free(param);
887 param = zbx_function_param_unquote_dyn(p + param_pos, param_len, "ed);
888
889 if (p == e + par_l + 1)
890 {
891 char *key = NULL, *host = NULL;
892
893 if (SUCCEED != parse_host_key(param, &host, &key) ||
894 SUCCEED != substitute_key_macros(&key, NULL, NULL, jp_row,
895 MACRO_TYPE_ITEM_KEY, NULL, 0))
896 {
897 zbx_snprintf(error, max_error_len, "Invalid first parameter \"%s\"", param);
898 zbx_free(host);
899 zbx_free(key);
900 goto out;
901 }
902
903 zbx_free(param);
904 if (NULL != host)
905 {
906 param = zbx_dsprintf(NULL, "%s:%s", host, key);
907 zbx_free(host);
908 zbx_free(key);
909 }
910 else
911 param = key;
912 }
913 else
914 substitute_discovery_macros(¶m, jp_row, ZBX_MACRO_ANY, NULL, 0);
915
916 if (SUCCEED != zbx_function_param_quote(¶m, quoted))
917 {
918 zbx_snprintf(error, max_error_len, "Cannot quote parameter \"%s\"", param);
919 goto out;
920 }
921
922 /* copy the parameter */
923 zbx_strcpy_alloc(&exp, &exp_alloc, &exp_offset, param);
924
925 /* copy what was after the parameter (including separator) */
926 zbx_strncpy_alloc(&exp, &exp_alloc, &exp_offset, p + param_pos + param_len,
927 sep_pos - param_pos - param_len + 1);
928 }
929 }
930
931 if (par_l > par_r)
932 goto out;
933
934 /* substitute LLD macros in the remaining part */
935
936 zbx_strcpy_alloc(&tmp, &tmp_alloc, &tmp_offset, e);
937 if (SUCCEED != substitute_discovery_macros(&tmp, jp_row, ZBX_MACRO_NUMERIC, error, max_error_len))
938 goto out;
939
940 zbx_strcpy_alloc(&exp, &exp_alloc, &exp_offset, tmp);
941
942 ret = SUCCEED;
943 out:
944 zbx_free(param);
945 zbx_free(tmp);
946
947 if (SUCCEED == ret)
948 {
949 zbx_free(*data);
950 *data = exp;
951 }
952 else
953 zbx_free(exp);
954
955 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
956
957 return ret;
958 }
959
960 /******************************************************************************
961 * *
962 * Function: lld_item_make *
963 * *
964 * Purpose: creates a new item based on item prototype and lld data row *
965 * *
966 * Parameters: item_prototype - [IN] the item prototype *
967 * lld_row - [IN] the lld row *
968 * *
969 * Returns: The created item or NULL if cannot create new item from prototype *
970 * *
971 ******************************************************************************/
lld_item_make(const zbx_lld_item_prototype_t * item_prototype,const zbx_lld_row_t * lld_row,char ** error)972 static zbx_lld_item_t *lld_item_make(const zbx_lld_item_prototype_t *item_prototype, const zbx_lld_row_t *lld_row,
973 char **error)
974 {
975 const char *__function_name = "lld_item_make";
976
977 zbx_lld_item_t *item;
978 const struct zbx_json_parse *jp_row = (struct zbx_json_parse *)&lld_row->jp_row;
979 char err[MAX_STRING_LEN];
980 int ret;
981
982 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
983
984 item = zbx_malloc(NULL, sizeof(zbx_lld_item_t));
985
986 item->itemid = 0;
987 item->parent_itemid = item_prototype->itemid;
988 item->lastcheck = 0;
989 item->ts_delete = 0;
990 item->key_proto = NULL;
991
992 item->name = zbx_strdup(NULL, item_prototype->name);
993 item->name_proto = NULL;
994 substitute_discovery_macros(&item->name, jp_row, ZBX_MACRO_ANY, NULL, 0);
995 zbx_lrtrim(item->name, ZBX_WHITESPACE);
996
997 item->key = zbx_strdup(NULL, item_prototype->key);
998 item->key_orig = NULL;
999 ret = substitute_key_macros(&item->key, NULL, NULL, jp_row, MACRO_TYPE_ITEM_KEY, err, sizeof(err));
1000
1001 item->units = zbx_strdup(NULL, item_prototype->units);
1002 item->units_orig = NULL;
1003 substitute_discovery_macros(&item->units, jp_row, ZBX_MACRO_ANY, NULL, 0);
1004 zbx_lrtrim(item->units, ZBX_WHITESPACE);
1005
1006 item->params = zbx_strdup(NULL, item_prototype->params);
1007 item->params_orig = NULL;
1008
1009 if (ITEM_TYPE_CALCULATED == item_prototype->type)
1010 {
1011 if (SUCCEED == ret)
1012 ret = substitute_formula_macros(&item->params, jp_row, err, sizeof(err));
1013 }
1014 else
1015 substitute_discovery_macros(&item->params, jp_row, ZBX_MACRO_ANY, NULL, 0);
1016
1017 zbx_lrtrim(item->params, ZBX_WHITESPACE);
1018
1019 item->ipmi_sensor = zbx_strdup(NULL, item_prototype->ipmi_sensor);
1020 item->ipmi_sensor_orig = NULL;
1021 substitute_discovery_macros(&item->ipmi_sensor, jp_row, ZBX_MACRO_ANY, NULL, 0);
1022 /* zbx_lrtrim(item->ipmi_sensor, ZBX_WHITESPACE); is not missing here */
1023
1024 item->snmp_oid = zbx_strdup(NULL, item_prototype->snmp_oid);
1025 item->snmp_oid_orig = NULL;
1026 substitute_key_macros(&item->snmp_oid, NULL, NULL, jp_row, MACRO_TYPE_SNMP_OID, NULL, 0);
1027 zbx_lrtrim(item->snmp_oid, ZBX_WHITESPACE);
1028
1029 item->description = zbx_strdup(NULL, item_prototype->description);
1030 item->description_orig = NULL;
1031 substitute_discovery_macros(&item->description, jp_row, ZBX_MACRO_ANY, NULL, 0);
1032 zbx_lrtrim(item->description, ZBX_WHITESPACE);
1033
1034 item->flags = ZBX_FLAG_LLD_ITEM_DISCOVERED;
1035 item->lld_row = lld_row;
1036
1037 if (SUCCEED != ret)
1038 {
1039 *error = zbx_strdcatf(*error, "Cannot create item: %s.\n", err);
1040 lld_item_free(item);
1041 item = NULL;
1042 }
1043
1044 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
1045
1046 return item;
1047 }
1048
1049 /******************************************************************************
1050 * *
1051 * Function: lld_item_update *
1052 * *
1053 * Purpose: updates an existing item based on item prototype and lld data row *
1054 * *
1055 * Parameters: item_prototype - [IN] the item prototype *
1056 * lld_row - [IN] the lld row *
1057 * item - [IN] an existing item or NULL *
1058 * *
1059 ******************************************************************************/
lld_item_update(const zbx_lld_item_prototype_t * item_prototype,const zbx_lld_row_t * lld_row,zbx_lld_item_t * item,char ** error)1060 static void lld_item_update(const zbx_lld_item_prototype_t *item_prototype, const zbx_lld_row_t *lld_row,
1061 zbx_lld_item_t *item, char **error)
1062 {
1063 const char *__function_name = "lld_item_update";
1064
1065 char *buffer = NULL, err[MAX_STRING_LEN];
1066 struct zbx_json_parse *jp_row = (struct zbx_json_parse *)&lld_row->jp_row;
1067
1068 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1069
1070 buffer = zbx_strdup(buffer, item_prototype->name);
1071 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
1072 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1073 if (0 != strcmp(item->name, buffer))
1074 {
1075 item->name_proto = item->name;
1076 item->name = buffer;
1077 buffer = NULL;
1078 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_NAME;
1079 }
1080
1081 if (0 != strcmp(item->key_proto, item_prototype->key))
1082 {
1083 buffer = zbx_strdup(buffer, item_prototype->key);
1084
1085 if (SUCCEED == substitute_key_macros(&buffer, NULL, NULL, jp_row, MACRO_TYPE_ITEM_KEY, err,
1086 sizeof(err)))
1087 {
1088 item->key_orig = item->key;
1089 item->key = buffer;
1090 buffer = NULL;
1091 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_KEY;
1092 }
1093 else
1094 *error = zbx_strdcatf(*error, "Cannot update item: %s.\n", err);
1095 }
1096
1097 buffer = zbx_strdup(buffer, item_prototype->units);
1098 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
1099 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1100 if (0 != strcmp(item->units, buffer))
1101 {
1102 item->units_orig = item->units;
1103 item->units = buffer;
1104 buffer = NULL;
1105 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_UNITS;
1106 }
1107
1108 buffer = zbx_strdup(buffer, item_prototype->params);
1109
1110 if (ITEM_TYPE_CALCULATED == item_prototype->type)
1111 {
1112 if (SUCCEED == substitute_formula_macros(&buffer, jp_row, err, sizeof(err)))
1113 {
1114 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1115
1116 if (0 != strcmp(item->params, buffer))
1117 {
1118 item->params_orig = item->params;
1119 item->params = buffer;
1120 buffer = NULL;
1121 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS;
1122 }
1123 }
1124 else
1125 *error = zbx_strdcatf(*error, "Cannot update item: %s.\n", err);
1126 }
1127 else
1128 {
1129 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
1130 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1131
1132 if (0 != strcmp(item->params, buffer))
1133 {
1134 item->params_orig = item->params;
1135 item->params = buffer;
1136 buffer = NULL;
1137 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS;
1138 }
1139 }
1140
1141 buffer = zbx_strdup(buffer, item_prototype->ipmi_sensor);
1142 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
1143 /* zbx_lrtrim(buffer, ZBX_WHITESPACE); is not missing here */
1144 if (0 != strcmp(item->ipmi_sensor, buffer))
1145 {
1146 item->ipmi_sensor_orig = item->ipmi_sensor;
1147 item->ipmi_sensor = buffer;
1148 buffer = NULL;
1149 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_IPMI_SENSOR;
1150 }
1151
1152 buffer = zbx_strdup(buffer, item_prototype->snmp_oid);
1153 substitute_key_macros(&buffer, NULL, NULL, jp_row, MACRO_TYPE_SNMP_OID, NULL, 0);
1154 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1155 if (0 != strcmp(item->snmp_oid, buffer))
1156 {
1157 item->snmp_oid_orig = item->snmp_oid;
1158 item->snmp_oid = buffer;
1159 buffer = NULL;
1160 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID;
1161 }
1162
1163 buffer = zbx_strdup(buffer, item_prototype->description);
1164 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
1165 zbx_lrtrim(buffer, ZBX_WHITESPACE);
1166 if (0 != strcmp(item->description, buffer))
1167 {
1168 item->description_orig = item->description;
1169 item->description = buffer;
1170 buffer = NULL;
1171 item->flags |= ZBX_FLAG_LLD_ITEM_UPDATE_DESCRIPTION;
1172 }
1173
1174 item->flags |= ZBX_FLAG_LLD_ITEM_DISCOVERED;
1175 item->lld_row = lld_row;
1176
1177 zbx_free(buffer);
1178
1179 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
1180 }
1181
1182 /******************************************************************************
1183 * *
1184 * Function: lld_items_make *
1185 * *
1186 * Purpose: updates existing items and creates new ones based on item *
1187 * item prototypes and lld data *
1188 * *
1189 * Parameters: item_prototypes - [IN] the item prototypes *
1190 * lld_rows - [IN] the lld data rows *
1191 * items - [IN/OUT] sorted list of items *
1192 * items_index - [OUT] index of items based on prototype ids *
1193 * and lld rows. Used to quckly find an *
1194 * item by prototype and lld_row. *
1195 * *
1196 ******************************************************************************/
lld_items_make(const zbx_vector_ptr_t * item_prototypes,const zbx_vector_ptr_t * lld_rows,zbx_vector_ptr_t * items,zbx_hashset_t * items_index,char ** error)1197 static void lld_items_make(const zbx_vector_ptr_t *item_prototypes, const zbx_vector_ptr_t *lld_rows,
1198 zbx_vector_ptr_t *items, zbx_hashset_t *items_index, char **error)
1199 {
1200 const char *__function_name = "lld_items_make";
1201 int i, j, index;
1202 zbx_lld_item_prototype_t *item_prototype;
1203 zbx_lld_item_t *item;
1204 zbx_lld_row_t *lld_row;
1205 zbx_lld_item_index_t *item_index, item_index_local;
1206 char *buffer = NULL;
1207
1208 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1209
1210 /* create the items index */
1211 for (i = 0; i < item_prototypes->values_num; i++)
1212 {
1213 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[i];
1214
1215 for (j = 0; j < lld_rows->values_num; j++)
1216 zbx_vector_ptr_append(&item_prototype->lld_rows, lld_rows->values[j]);
1217 }
1218
1219 /* Iterate in reverse order because usually the items are created in the same order as */
1220 /* incoming lld rows. Iterating in reverse optimizes lld_row removal from item prototypes. */
1221 for (i = items->values_num - 1; i >= 0; i--)
1222 {
1223 item = (zbx_lld_item_t *)items->values[i];
1224
1225 if (FAIL == (index = zbx_vector_ptr_bsearch(item_prototypes, &item->parent_itemid,
1226 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
1227 {
1228 THIS_SHOULD_NEVER_HAPPEN;
1229 continue;
1230 }
1231
1232 item_prototype = item_prototypes->values[index];
1233
1234 for (j = item_prototype->lld_rows.values_num - 1; j >= 0; j--)
1235 {
1236 lld_row = (zbx_lld_row_t *)item_prototype->lld_rows.values[j];
1237
1238 buffer = zbx_strdup(buffer, item->key_proto);
1239
1240 if (SUCCEED != substitute_key_macros(&buffer, NULL, NULL, &lld_row->jp_row, MACRO_TYPE_ITEM_KEY,
1241 NULL, 0))
1242 {
1243 continue;
1244 }
1245
1246 if (0 == strcmp(item->key, buffer))
1247 {
1248 item_index_local.parent_itemid = item->parent_itemid;
1249 item_index_local.lld_row = lld_row;
1250 item_index_local.item = item;
1251 zbx_hashset_insert(items_index, &item_index_local, sizeof(item_index_local));
1252
1253 zbx_vector_ptr_remove_noorder(&item_prototype->lld_rows, j);
1254 break;
1255 }
1256 }
1257 }
1258
1259 zbx_free(buffer);
1260
1261 /* update/create discovered items */
1262 for (i = 0; i < item_prototypes->values_num; i++)
1263 {
1264 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[i];
1265 item_index_local.parent_itemid = item_prototype->itemid;
1266
1267 for (j = 0; j < lld_rows->values_num; j++)
1268 {
1269 item_index_local.lld_row = (zbx_lld_row_t *)lld_rows->values[j];
1270
1271 if (NULL == (item_index = zbx_hashset_search(items_index, &item_index_local)))
1272 {
1273 if (NULL != (item = lld_item_make(item_prototype, item_index_local.lld_row, error)))
1274 {
1275 /* add the created item to items vector and update index */
1276 zbx_vector_ptr_append(items, item);
1277 item_index_local.item = item;
1278 zbx_hashset_insert(items_index, &item_index_local, sizeof(item_index_local));
1279 }
1280 }
1281 else
1282 lld_item_update(item_prototype, item_index_local.lld_row, item_index->item, error);
1283 }
1284 }
1285
1286 zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
1287
1288 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d items", __function_name, items->values_num);
1289 }
1290
1291 /******************************************************************************
1292 * *
1293 * Function: lld_items_save *
1294 * *
1295 * Parameters: hostid - [IN] parent host id *
1296 * item_prototypes - [IN] item prototypes *
1297 * items - [IN/OUT] items to save *
1298 * host_locked - [IN/OUT] host record is locked *
1299 * *
1300 * Return value: SUCCEED - if items were successfully saved or saving was not *
1301 * necessary *
1302 * FAIL - items cannot be saved *
1303 * *
1304 ******************************************************************************/
lld_items_save(zbx_uint64_t hostid,const zbx_vector_ptr_t * item_prototypes,zbx_vector_ptr_t * items,int * host_locked)1305 static int lld_items_save(zbx_uint64_t hostid, const zbx_vector_ptr_t *item_prototypes, zbx_vector_ptr_t *items,
1306 int *host_locked)
1307 {
1308 const char *__function_name = "lld_items_save";
1309
1310 int ret = SUCCEED, index, i, new_items = 0, upd_items = 0;
1311 zbx_lld_item_t *item;
1312 const zbx_lld_item_prototype_t *item_prototype;
1313 zbx_uint64_t itemid = 0, itemdiscoveryid = 0;
1314 char *sql = NULL, *value_esc;
1315 size_t sql_alloc = 8 * ZBX_KIBIBYTE, sql_offset = 0;
1316 zbx_db_insert_t db_insert, db_insert_idiscovery;
1317
1318 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1319
1320 if (0 == items->values_num)
1321 goto out;
1322
1323 for (i = 0; i < items->values_num; i++)
1324 {
1325 item = (zbx_lld_item_t *)items->values[i];
1326
1327 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
1328 continue;
1329
1330 if (0 == item->itemid)
1331 new_items++;
1332 else if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE))
1333 upd_items++;
1334 }
1335
1336 if (0 == new_items && 0 == upd_items)
1337 goto out;
1338
1339 if (0 == *host_locked)
1340 {
1341 if (SUCCEED != DBlock_hostid(hostid))
1342 {
1343 /* the host was removed while processing lld rule */
1344 ret = FAIL;
1345 goto out;
1346 }
1347
1348 *host_locked = 1;
1349 }
1350
1351 if (0 != new_items)
1352 {
1353 itemid = DBget_maxid_num("items", new_items);
1354 itemdiscoveryid = DBget_maxid_num("item_discovery", new_items);
1355
1356 zbx_db_insert_prepare(&db_insert, "items", "itemid", "name", "key_", "hostid", "type", "value_type",
1357 "data_type", "delay", "delay_flex", "history", "trends", "status", "trapper_hosts",
1358 "units", "multiplier", "delta", "formula", "logtimefmt", "valuemapid", "params",
1359 "ipmi_sensor", "snmp_community", "snmp_oid", "port", "snmpv3_securityname",
1360 "snmpv3_securitylevel", "snmpv3_authprotocol", "snmpv3_authpassphrase",
1361 "snmpv3_privprotocol", "snmpv3_privpassphrase", "authtype", "username", "password",
1362 "publickey", "privatekey", "description", "interfaceid", "flags", "snmpv3_contextname",
1363 NULL);
1364
1365 zbx_db_insert_prepare(&db_insert_idiscovery, "item_discovery", "itemdiscoveryid", "itemid",
1366 "parent_itemid", "key_", NULL);
1367 }
1368
1369 if (0 != upd_items)
1370 {
1371 sql = zbx_malloc(sql, sql_alloc);
1372 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
1373 }
1374
1375 for (i = 0; i < items->values_num; i++)
1376 {
1377 item = (zbx_lld_item_t *)items->values[i];
1378
1379 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
1380 continue;
1381
1382 if (FAIL == (index = zbx_vector_ptr_bsearch(item_prototypes, &item->parent_itemid,
1383 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
1384 {
1385 THIS_SHOULD_NEVER_HAPPEN;
1386 continue;
1387 }
1388
1389 item_prototype = item_prototypes->values[index];
1390
1391 if (0 == item->itemid)
1392 {
1393 item->itemid = itemid++;
1394
1395 zbx_db_insert_add_values(&db_insert, item->itemid, item->name, item->key, hostid,
1396 (int)item_prototype->type, (int)item_prototype->value_type,
1397 (int)item_prototype->data_type, item_prototype->delay,
1398 item_prototype->delay_flex, item_prototype->history, item_prototype->trends,
1399 (int)item_prototype->status, item_prototype->trapper_hosts, item->units,
1400 (int)item_prototype->multiplier, (int)item_prototype->delta,
1401 item_prototype->formula, item_prototype->logtimefmt, item_prototype->valuemapid,
1402 item->params, item->ipmi_sensor, item_prototype->snmp_community, item->snmp_oid,
1403 item_prototype->port, item_prototype->snmpv3_securityname,
1404 (int)item_prototype->snmpv3_securitylevel,
1405 (int)item_prototype->snmpv3_authprotocol, item_prototype->snmpv3_authpassphrase,
1406 (int)item_prototype->snmpv3_privprotocol, item_prototype->snmpv3_privpassphrase,
1407 (int)item_prototype->authtype, item_prototype->username,
1408 item_prototype->password, item_prototype->publickey, item_prototype->privatekey,
1409 item->description, item_prototype->interfaceid, (int)ZBX_FLAG_DISCOVERY_CREATED,
1410 item_prototype->snmpv3_contextname);
1411
1412 zbx_db_insert_add_values(&db_insert_idiscovery, itemdiscoveryid++, item->itemid,
1413 item->parent_itemid, item_prototype->key);
1414 }
1415 else
1416 {
1417 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE))
1418 {
1419 const char *d = "";
1420
1421 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update items set ");
1422 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_NAME))
1423 {
1424 value_esc = DBdyn_escape_string(item->name);
1425 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "name='%s'", value_esc);
1426 zbx_free(value_esc);
1427 d = ",";
1428 }
1429 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_KEY))
1430 {
1431 value_esc = DBdyn_escape_string(item->key);
1432 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%skey_='%s'", d, value_esc);
1433 zbx_free(value_esc);
1434 d = ",";
1435 }
1436 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_TYPE))
1437 {
1438 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%stype=%d", d,
1439 (int)item_prototype->type);
1440 d = ",";
1441 }
1442 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_VALUE_TYPE))
1443 {
1444 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%svalue_type=%d",
1445 d, (int)item_prototype->value_type);
1446 d = ",";
1447 }
1448 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_DATA_TYPE))
1449 {
1450 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdata_type=%d",
1451 d, (int)item_prototype->data_type);
1452 d = ",";
1453 }
1454 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_DELAY))
1455 {
1456 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdelay=%d", d,
1457 item_prototype->delay);
1458 d = ",";
1459 }
1460 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_DELAY_FLEX))
1461 {
1462 value_esc = DBdyn_escape_string(item_prototype->delay_flex);
1463 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdelay_flex='%s'",
1464 d, value_esc);
1465 zbx_free(value_esc);
1466 d = ",";
1467 }
1468 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_HISTORY))
1469 {
1470 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%shistory=%d",
1471 d, item_prototype->history);
1472 d = ",";
1473 }
1474 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_TRENDS))
1475 {
1476 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%strends=%d", d,
1477 item_prototype->trends);
1478 d = ",";
1479 }
1480 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_TRAPPER_HOSTS))
1481 {
1482 value_esc = DBdyn_escape_string(item_prototype->trapper_hosts);
1483 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%strapper_hosts='%s'",
1484 d, value_esc);
1485 zbx_free(value_esc);
1486 d = ",";
1487 }
1488 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_UNITS))
1489 {
1490 value_esc = DBdyn_escape_string(item->units);
1491 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sunits='%s'",
1492 d, value_esc);
1493 zbx_free(value_esc);
1494 d = ",";
1495 }
1496 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_MULTIPLIER))
1497 {
1498 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%smultiplier=%d",
1499 d, (int)item_prototype->multiplier);
1500 d = ",";
1501 }
1502 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_DELTA))
1503 {
1504 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdelta=%d",
1505 d, (int)item_prototype->delta);
1506 d = ",";
1507 }
1508 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_FORMULA))
1509 {
1510 value_esc = DBdyn_escape_string(item_prototype->formula);
1511 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sformula='%s'",
1512 d, value_esc);
1513 zbx_free(value_esc);
1514 d = ",";
1515 }
1516 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_LOGTIMEFMT))
1517 {
1518 value_esc = DBdyn_escape_string(item_prototype->logtimefmt);
1519 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%slogtimefmt='%s'",
1520 d, value_esc);
1521 zbx_free(value_esc);
1522 d = ",";
1523 }
1524 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_VALUEMAPID))
1525 {
1526 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%svaluemapid=%s",
1527 d, DBsql_id_ins(item_prototype->valuemapid));
1528 d = ",";
1529 }
1530 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_PARAMS))
1531 {
1532 value_esc = DBdyn_escape_string(item->params);
1533 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sparams='%s'",
1534 d, value_esc);
1535 zbx_free(value_esc);
1536 d = ",";
1537 }
1538 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_IPMI_SENSOR))
1539 {
1540 value_esc = DBdyn_escape_string(item->ipmi_sensor);
1541 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sipmi_sensor='%s'",
1542 d, value_esc);
1543 zbx_free(value_esc);
1544 d = ",";
1545 }
1546 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_COMMUNITY))
1547 {
1548 value_esc = DBdyn_escape_string(item_prototype->snmp_community);
1549 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%ssnmp_community='%s'",
1550 d, value_esc);
1551 zbx_free(value_esc);
1552 d = ",";
1553 }
1554 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMP_OID))
1555 {
1556 value_esc = DBdyn_escape_string(item->snmp_oid);
1557 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%ssnmp_oid='%s'",
1558 d, value_esc);
1559 zbx_free(value_esc);
1560 d = ",";
1561 }
1562 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_PORT))
1563 {
1564 value_esc = DBdyn_escape_string(item_prototype->port);
1565 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sport='%s'",
1566 d, value_esc);
1567 zbx_free(value_esc);
1568 d = ",";
1569 }
1570 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYNAME))
1571 {
1572 value_esc = DBdyn_escape_string(item_prototype->snmpv3_securityname);
1573 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1574 "%ssnmpv3_securityname='%s'", d, value_esc);
1575 zbx_free(value_esc);
1576 d = ",";
1577 }
1578 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_SECURITYLEVEL))
1579 {
1580 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1581 "%ssnmpv3_securitylevel=%d", d,
1582 (int)item_prototype->snmpv3_securitylevel);
1583 d = ",";
1584 }
1585 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPROTOCOL))
1586 {
1587 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1588 "%ssnmpv3_authprotocol=%d", d,
1589 (int)item_prototype->snmpv3_authprotocol);
1590 d = ",";
1591 }
1592 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_AUTHPASSPHRASE))
1593 {
1594 value_esc = DBdyn_escape_string(item_prototype->snmpv3_authpassphrase);
1595 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1596 "%ssnmpv3_authpassphrase='%s'", d, value_esc);
1597 zbx_free(value_esc);
1598 d = ",";
1599 }
1600 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPROTOCOL))
1601 {
1602 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1603 "%ssnmpv3_privprotocol=%d", d,
1604 (int)item_prototype->snmpv3_privprotocol);
1605 d = ",";
1606 }
1607 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_PRIVPASSPHRASE))
1608 {
1609 value_esc = DBdyn_escape_string(item_prototype->snmpv3_privpassphrase);
1610 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1611 "%ssnmpv3_privpassphrase='%s'", d, value_esc);
1612 zbx_free(value_esc);
1613 d = ",";
1614 }
1615 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_AUTHTYPE))
1616 {
1617 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sauthtype=%d",
1618 d, (int)item_prototype->authtype);
1619 d = ",";
1620 }
1621 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_USERNAME))
1622 {
1623 value_esc = DBdyn_escape_string(item_prototype->username);
1624 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%susername='%s'",
1625 d, value_esc);
1626 zbx_free(value_esc);
1627 d = ",";
1628 }
1629 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_PASSWORD))
1630 {
1631 value_esc = DBdyn_escape_string(item_prototype->password);
1632 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spassword='%s'",
1633 d, value_esc);
1634 zbx_free(value_esc);
1635 d = ",";
1636 }
1637 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_PUBLICKEY))
1638 {
1639 value_esc = DBdyn_escape_string(item_prototype->publickey);
1640 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%spublickey='%s'",
1641 d, value_esc);
1642 zbx_free(value_esc);
1643 d = ",";
1644 }
1645 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_PRIVATEKEY))
1646 {
1647 value_esc = DBdyn_escape_string(item_prototype->privatekey);
1648 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sprivatekey='%s'",
1649 d, value_esc);
1650 zbx_free(value_esc);
1651 d = ",";
1652 }
1653 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_DESCRIPTION))
1654 {
1655 value_esc = DBdyn_escape_string(item->description);
1656 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sdescription='%s'",
1657 d, value_esc);
1658 zbx_free(value_esc);
1659 d = ",";
1660
1661 }
1662 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_INTERFACEID))
1663 {
1664 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%sinterfaceid=%s",
1665 d, DBsql_id_ins(item_prototype->interfaceid));
1666 d = ",";
1667 }
1668 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_SNMPV3_CONTEXTNAME))
1669 {
1670 value_esc = DBdyn_escape_string(item_prototype->snmpv3_contextname);
1671 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1672 "%ssnmpv3_contextname='%s'", d, value_esc);
1673 zbx_free(value_esc);
1674 }
1675
1676 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where itemid=" ZBX_FS_UI64 ";\n",
1677 item->itemid);
1678 }
1679
1680 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_UPDATE_KEY))
1681 {
1682 value_esc = DBdyn_escape_string(item_prototype->key);
1683 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
1684 "update item_discovery"
1685 " set key_='%s'"
1686 " where itemid=" ZBX_FS_UI64 ";\n",
1687 value_esc, item->itemid);
1688 zbx_free(value_esc);
1689 }
1690 }
1691
1692 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
1693 }
1694
1695 if (0 != upd_items)
1696 {
1697 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
1698 DBexecute("%s", sql);
1699 zbx_free(sql);
1700 }
1701
1702 if (0 != new_items)
1703 {
1704 zbx_db_insert_execute(&db_insert);
1705 zbx_db_insert_clean(&db_insert);
1706
1707 zbx_db_insert_execute(&db_insert_idiscovery);
1708 zbx_db_insert_clean(&db_insert_idiscovery);
1709
1710 zbx_vector_ptr_sort(items, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
1711 }
1712 out:
1713 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
1714
1715 return ret;
1716 }
1717
1718 /******************************************************************************
1719 * *
1720 * Function: lld_applications_save *
1721 * *
1722 * Parameters: hostid - [IN] host id *
1723 * applications - [IN/OUT] applications to save *
1724 * application_prototypes - [IN] the application prototypes *
1725 * host_locked - [IN/OUT] host record is locked *
1726 * *
1727 ******************************************************************************/
lld_applications_save(zbx_uint64_t hostid,zbx_vector_ptr_t * applications,const zbx_vector_ptr_t * application_prototypes,int * host_locked)1728 static int lld_applications_save(zbx_uint64_t hostid, zbx_vector_ptr_t *applications,
1729 const zbx_vector_ptr_t *application_prototypes, int *host_locked)
1730 {
1731 const char *__function_name = "lld_applications_save";
1732 int ret = SUCCEED, i, new_applications = 0, new_discoveries = 0, index;
1733 zbx_lld_application_t *application;
1734 const zbx_lld_application_prototype_t *application_prototype;
1735 zbx_uint64_t applicationid, application_discoveryid;
1736 zbx_db_insert_t db_insert, db_insert_discovery;
1737 zbx_vector_uint64_t del_applicationids, del_discoveryids;
1738 char *sql_a = NULL, *sql_ad = NULL, *name;
1739 size_t sql_a_alloc = 0, sql_a_offset = 0, sql_ad_alloc = 0, sql_ad_offset = 0;
1740
1741 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1742
1743 if (0 == applications->values_num)
1744 goto out;
1745
1746 if (0 == *host_locked)
1747 {
1748 if (SUCCEED != DBlock_hostid(hostid))
1749 {
1750 /* the host was removed while processing lld rule */
1751 ret = FAIL;
1752 goto out;
1753 }
1754
1755 *host_locked = 1;
1756 }
1757
1758 zbx_vector_uint64_create(&del_applicationids);
1759 zbx_vector_uint64_create(&del_discoveryids);
1760
1761 /* Count new applications and application discoveries. */
1762 /* Note that an application might have been discovered by another lld rule. */
1763 /* In this case the discovered items will be linked to this application and */
1764 /* new application discovery record, linking the prototype to this */
1765 /* application, will be created. */
1766 for (i = 0; i < applications->values_num; i++)
1767 {
1768 application = (zbx_lld_application_t *)applications->values[i];
1769
1770 if (0 != (application->flags & ZBX_FLAG_LLD_APPLICATION_REMOVE))
1771 {
1772 zbx_vector_uint64_append(&del_applicationids, application->applicationid);
1773 continue;
1774 }
1775
1776 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
1777 continue;
1778
1779 if (0 == application->applicationid)
1780 new_applications++;
1781
1782 if (0 != (application->flags & ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY))
1783 new_discoveries++;
1784 }
1785
1786 /* insert new applications, application discoveries and prepare a list of applications to be removed */
1787
1788 if (0 != new_applications)
1789 {
1790 applicationid = DBget_maxid_num("applications", new_applications);
1791 zbx_db_insert_prepare(&db_insert, "applications", "applicationid", "hostid", "name", "flags", NULL);
1792 }
1793
1794 if (0 != new_discoveries)
1795 {
1796 application_discoveryid = DBget_maxid_num("application_discovery", new_discoveries);
1797 zbx_db_insert_prepare(&db_insert_discovery, "application_discovery", "application_discoveryid",
1798 "applicationid", "application_prototypeid", "name", NULL);
1799 }
1800
1801 for (i = 0; i < applications->values_num; i++)
1802 {
1803 DBexecute_overflowed_sql(&sql_a, &sql_a_alloc, &sql_a_offset);
1804 DBexecute_overflowed_sql(&sql_ad, &sql_ad_alloc, &sql_ad_offset);
1805
1806 application = (zbx_lld_application_t *)applications->values[i];
1807
1808 if (0 != (application->flags & ZBX_FLAG_LLD_APPLICATION_REMOVE_DISCOVERY))
1809 {
1810 zbx_vector_uint64_append(&del_discoveryids, application->application_discoveryid);
1811 continue;
1812 }
1813
1814 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
1815 continue;
1816
1817 if (FAIL == (index = zbx_vector_ptr_search(application_prototypes,
1818 &application->application_prototypeid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
1819 {
1820 THIS_SHOULD_NEVER_HAPPEN;
1821 continue;
1822 }
1823
1824 application_prototype = (zbx_lld_application_prototype_t *)application_prototypes->values[index];
1825
1826 if (0 == application->applicationid)
1827 {
1828 application->applicationid = applicationid++;
1829 zbx_db_insert_add_values(&db_insert, application->applicationid, hostid, application->name,
1830 ZBX_FLAG_DISCOVERY_CREATED);
1831 }
1832
1833 if (0 != (application->flags & ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME))
1834 {
1835 name = DBdyn_escape_string(application->name);
1836 zbx_snprintf_alloc(&sql_a, &sql_a_alloc, &sql_a_offset,
1837 "update applications set name='%s'"
1838 " where applicationid=" ZBX_FS_UI64 ";\n",
1839 name, application->applicationid);
1840 zbx_free(name);
1841
1842 name = DBdyn_escape_string(application_prototype->name);
1843 zbx_snprintf_alloc(&sql_ad, &sql_ad_alloc, &sql_ad_offset,
1844 "update application_discovery set name='%s'"
1845 " where application_discoveryid=" ZBX_FS_UI64 ";\n",
1846 name, application->application_discoveryid);
1847 zbx_free(name);
1848 continue;
1849 }
1850
1851 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY))
1852 continue;
1853
1854 application->application_discoveryid = application_discoveryid++;
1855 zbx_db_insert_add_values(&db_insert_discovery, application->application_discoveryid,
1856 application->applicationid, application->application_prototypeid,
1857 application_prototype->name);
1858 }
1859
1860 if (0 != del_applicationids.values_num)
1861 {
1862 zbx_strcpy_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, "delete from applications where");
1863 DBadd_condition_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, "applicationid", del_applicationids.values,
1864 del_applicationids.values_num);
1865 zbx_strcpy_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, ";\n");
1866 }
1867
1868 if (0 != del_discoveryids.values_num)
1869 {
1870 zbx_strcpy_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, "delete from application_discovery where");
1871 DBadd_condition_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, "application_discoveryid",
1872 del_discoveryids.values, del_discoveryids.values_num);
1873 zbx_strcpy_alloc(&sql_a, &sql_a_alloc, &sql_a_offset, ";\n");
1874 }
1875
1876 if (NULL != sql_a)
1877 {
1878 DBexecute("%s", sql_a);
1879 zbx_free(sql_a);
1880 }
1881
1882 if (NULL != sql_ad)
1883 {
1884 DBexecute("%s", sql_ad);
1885 zbx_free(sql_ad);
1886 }
1887
1888 if (0 != new_applications)
1889 {
1890 zbx_db_insert_execute(&db_insert);
1891 zbx_db_insert_clean(&db_insert);
1892
1893 zbx_vector_ptr_sort(applications, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
1894 }
1895
1896 if (0 != new_discoveries)
1897 {
1898 zbx_db_insert_execute(&db_insert_discovery);
1899 zbx_db_insert_clean(&db_insert_discovery);
1900 }
1901
1902 zbx_vector_uint64_destroy(&del_discoveryids);
1903 zbx_vector_uint64_destroy(&del_applicationids);
1904 out:
1905 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
1906
1907 return ret;
1908 }
1909
1910 /******************************************************************************
1911 * *
1912 * Function: lld_item_application_validate *
1913 * *
1914 * Purpose: validates undiscovered item-application link to determine if it *
1915 * should be removed *
1916 * *
1917 * Parameters: items_application - [IN] an item-application link to validate *
1918 * items - [IN] the related items *
1919 * applications - [IN] the related applications *
1920 * *
1921 * Return value: SUCCEED - item-application link should not be removed *
1922 * FAIL - item-application link should be removed *
1923 * *
1924 * Comments: Undiscovered item-application link must be removed if either the *
1925 * application was not discovered or item was discovered. *
1926 * The only case when undiscovered item-application link is not *
1927 * removed is when we have valid application and undiscovered item. *
1928 * In this case we leave item-application link untouched and it *
1929 * will 'expire' together with item. *
1930 * *
1931 ******************************************************************************/
lld_item_application_validate(const zbx_lld_item_application_t * item_application,const zbx_vector_ptr_t * items,const zbx_vector_ptr_t * applications)1932 static int lld_item_application_validate(const zbx_lld_item_application_t *item_application,
1933 const zbx_vector_ptr_t *items, const zbx_vector_ptr_t *applications)
1934 {
1935 const zbx_lld_application_t *application;
1936 const zbx_lld_item_t *item;
1937 int index;
1938
1939 if (FAIL == (index = zbx_vector_ptr_bsearch(applications, &item_application->application_ref.applicationid,
1940 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
1941 {
1942 /* Applications vector contains only discovered applications and */
1943 /* apparently the item was linked to a normal application. */
1944 /* Undiscovered item-application links to normal application must */
1945 /* be removed if item has been also discovered - this means that */
1946 /* the item prototype - application link was removed by frontend. */
1947 goto check_item;
1948 }
1949
1950 application = (zbx_lld_application_t *)applications->values[index];
1951
1952 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
1953 return FAIL;
1954
1955 check_item:
1956 if (FAIL == (index = zbx_vector_ptr_bsearch(items, &item_application->item_ref.itemid,
1957 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
1958 {
1959 THIS_SHOULD_NEVER_HAPPEN;
1960 return FAIL;
1961 }
1962
1963 item = (zbx_lld_item_t *)items->values[index];
1964
1965 if (0 != (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
1966 return FAIL;
1967
1968 return SUCCEED;
1969 }
1970
1971 /******************************************************************************
1972 * *
1973 * Function: lld_items_applications_save *
1974 * *
1975 * Parameters: items_applications - [IN] item-application links *
1976 * *
1977 ******************************************************************************/
lld_items_applications_save(zbx_hashset_t * items_applications,const zbx_vector_ptr_t * items,const zbx_vector_ptr_t * applications)1978 static void lld_items_applications_save(zbx_hashset_t *items_applications, const zbx_vector_ptr_t *items,
1979 const zbx_vector_ptr_t *applications)
1980 {
1981 const char *__function_name = "lld_items_applications_save";
1982 zbx_hashset_iter_t iter;
1983 zbx_lld_item_application_t *item_application;
1984 zbx_vector_uint64_t del_itemappids;
1985 int new_item_applications = 0;
1986 zbx_uint64_t itemappid, applicationid, itemid;
1987 zbx_db_insert_t db_insert;
1988
1989 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
1990
1991 if (0 == items_applications->num_data)
1992 goto out;
1993
1994 zbx_vector_uint64_create(&del_itemappids);
1995
1996 /* count new item-application links */
1997 zbx_hashset_iter_reset(items_applications, &iter);
1998
1999 while (NULL != (item_application = zbx_hashset_iter_next(&iter)))
2000 {
2001 if (0 == item_application->itemappid)
2002 new_item_applications++;
2003 }
2004
2005 if (0 != new_item_applications)
2006 {
2007 itemappid = DBget_maxid_num("items_applications", new_item_applications);
2008 zbx_db_insert_prepare(&db_insert, "items_applications", "itemappid", "applicationid", "itemid", NULL);
2009 }
2010
2011 zbx_hashset_iter_reset(items_applications, &iter);
2012
2013 while (NULL != (item_application = zbx_hashset_iter_next(&iter)))
2014 {
2015 if (0 != item_application->itemappid)
2016 {
2017 /* add for removal the old links that aren't discovered and can be removed */
2018 if (0 == (item_application->flags & ZBX_FLAG_LLD_ITEM_APPLICATION_DISCOVERED) &&
2019 FAIL == lld_item_application_validate(item_application, items, applications))
2020 {
2021 zbx_vector_uint64_append(&del_itemappids, item_application->itemappid);
2022 }
2023
2024 continue;
2025 }
2026
2027 if (0 == (applicationid = item_application->application_ref.applicationid))
2028 applicationid = item_application->application_ref.application->applicationid;
2029
2030 if (0 == (itemid = item_application->item_ref.itemid))
2031 itemid = item_application->item_ref.item->itemid;
2032
2033 item_application->itemappid = itemappid++;
2034 zbx_db_insert_add_values(&db_insert, item_application->itemappid, applicationid, itemid);
2035 }
2036
2037 if (0 != new_item_applications)
2038 {
2039 zbx_db_insert_execute(&db_insert);
2040 zbx_db_insert_clean(&db_insert);
2041 }
2042
2043 /* remove deprecated links */
2044 if (0 != del_itemappids.values_num)
2045 {
2046 char *sql = NULL;
2047 size_t sql_alloc = 0, sql_offset = 0;
2048
2049 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from items_applications where");
2050 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemappid", del_itemappids.values,
2051 del_itemappids.values_num);
2052
2053 DBexecute("%s", sql);
2054
2055 zbx_free(sql);
2056 }
2057
2058 zbx_vector_uint64_destroy(&del_itemappids);
2059 out:
2060 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
2061 }
2062
2063 /******************************************************************************
2064 * *
2065 * Function: lld_remove_lost_items *
2066 * *
2067 * Purpose: updates item_discovery.lastcheck and item_discovery.ts_delete *
2068 * fields; removes lost resources *
2069 * *
2070 ******************************************************************************/
lld_remove_lost_items(const zbx_vector_ptr_t * items,unsigned short lifetime,int lastcheck)2071 static void lld_remove_lost_items(const zbx_vector_ptr_t *items, unsigned short lifetime, int lastcheck)
2072 {
2073 const char *__function_name = "lld_remove_lost_items";
2074 char *sql = NULL;
2075 size_t sql_alloc = 0, sql_offset = 0;
2076 zbx_lld_item_t *item;
2077 zbx_vector_uint64_t del_itemids, lc_itemids, ts_itemids;
2078 zbx_vector_uint64_pair_t discovery_itemts;
2079 int i, lifetime_sec;
2080
2081 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2082
2083 if (0 == items->values_num)
2084 goto out;
2085
2086 lifetime_sec = lifetime * SEC_PER_DAY;
2087
2088 zbx_vector_uint64_create(&del_itemids);
2089 zbx_vector_uint64_create(&lc_itemids);
2090 zbx_vector_uint64_create(&ts_itemids);
2091 zbx_vector_uint64_pair_create(&discovery_itemts);
2092
2093 for (i = 0; i < items->values_num; i++)
2094 {
2095 item = (zbx_lld_item_t *)items->values[i];
2096
2097 if (0 == item->itemid)
2098 continue;
2099
2100 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
2101 {
2102 if (item->lastcheck < lastcheck - lifetime_sec)
2103 {
2104 zbx_vector_uint64_append(&del_itemids, item->itemid);
2105 }
2106 else if (item->ts_delete != item->lastcheck + lifetime_sec)
2107 {
2108 zbx_uint64_pair_t itemts;
2109
2110 itemts.first = item->itemid;
2111 itemts.second = item->lastcheck + lifetime_sec;
2112 zbx_vector_uint64_pair_append(&discovery_itemts, itemts);
2113 }
2114 }
2115 else
2116 {
2117 zbx_vector_uint64_append(&lc_itemids, item->itemid);
2118 if (0 != item->ts_delete)
2119 zbx_vector_uint64_append(&ts_itemids, item->itemid);
2120 }
2121 }
2122
2123 if (0 == discovery_itemts.values_num && 0 == lc_itemids.values_num && 0 == ts_itemids.values_num &&
2124 0 == del_itemids.values_num)
2125 {
2126 goto clean;
2127 }
2128
2129 /* update item discovery table */
2130
2131 DBbegin();
2132
2133 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
2134
2135 for (i = 0; i < discovery_itemts.values_num; i++)
2136 {
2137 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
2138 "update item_discovery"
2139 " set ts_delete=%d"
2140 " where itemid=" ZBX_FS_UI64 ";\n",
2141 (int)discovery_itemts.values[i].second, discovery_itemts.values[i].first);
2142
2143 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2144 }
2145
2146 if (0 != lc_itemids.values_num)
2147 {
2148 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update item_discovery set lastcheck=%d where",
2149 lastcheck);
2150 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid",
2151 lc_itemids.values, lc_itemids.values_num);
2152 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2153
2154 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2155 }
2156
2157 if (0 != ts_itemids.values_num)
2158 {
2159 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update item_discovery set ts_delete=0 where");
2160 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid",
2161 ts_itemids.values, ts_itemids.values_num);
2162 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2163 }
2164
2165 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
2166
2167 if (16 < sql_offset) /* in ORACLE always present begin..end; */
2168 DBexecute("%s", sql);
2169
2170 zbx_free(sql);
2171
2172 /* remove 'lost' items */
2173 if (0 != del_itemids.values_num)
2174 {
2175 zbx_vector_uint64_sort(&del_itemids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2176 DBdelete_items(&del_itemids);
2177 }
2178
2179 DBcommit();
2180 clean:
2181 zbx_vector_uint64_pair_destroy(&discovery_itemts);
2182 zbx_vector_uint64_destroy(&ts_itemids);
2183 zbx_vector_uint64_destroy(&lc_itemids);
2184 zbx_vector_uint64_destroy(&del_itemids);
2185 out:
2186 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
2187 }
2188
2189 /******************************************************************************
2190 * *
2191 * Function: lld_remove_lost_applications *
2192 * *
2193 * Purpose: updates application_discovery lastcheck and ts_delete fields, *
2194 * removes lost resources *
2195 * *
2196 ******************************************************************************/
lld_remove_lost_applications(zbx_uint64_t lld_ruleid,const zbx_vector_ptr_t * applications,unsigned short lifetime,int lastcheck)2197 static void lld_remove_lost_applications(zbx_uint64_t lld_ruleid, const zbx_vector_ptr_t *applications,
2198 unsigned short lifetime, int lastcheck)
2199 {
2200 const char *__function_name = "lld_remove_lost_applications";
2201 DB_RESULT result;
2202 DB_ROW row;
2203 char *sql = NULL;
2204 size_t sql_alloc = 0, sql_offset = 0;
2205 zbx_vector_uint64_t del_applicationids, del_discoveryids, ts_discoveryids, lc_discoveryids;
2206 zbx_vector_uint64_pair_t discovery_applicationts;
2207 int i, lifetime_sec, index;
2208 const zbx_lld_application_t *application;
2209 zbx_uint64_t applicationid;
2210
2211 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2212
2213 if (0 == applications->values_num)
2214 goto out;
2215
2216 lifetime_sec = lifetime * SEC_PER_DAY;
2217
2218 zbx_vector_uint64_create(&del_applicationids);
2219 zbx_vector_uint64_create(&del_discoveryids);
2220 zbx_vector_uint64_create(&ts_discoveryids);
2221 zbx_vector_uint64_create(&lc_discoveryids);
2222 zbx_vector_uint64_pair_create(&discovery_applicationts);
2223
2224 /* prepare application discovery update vector */
2225 for (i = 0; i < applications->values_num; i++)
2226 {
2227 application = (const zbx_lld_application_t *)applications->values[i];
2228
2229 if (0 == application->applicationid)
2230 continue;
2231
2232 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
2233 {
2234 if (application->lastcheck < lastcheck - lifetime_sec)
2235 {
2236 zbx_vector_uint64_append(&del_applicationids, application->applicationid);
2237 zbx_vector_uint64_append(&del_discoveryids, application->application_discoveryid);
2238 }
2239 else if (application->ts_delete != application->lastcheck + lifetime_sec)
2240 {
2241 zbx_uint64_pair_t applicationts;
2242
2243 applicationts.first = application->application_discoveryid;
2244 applicationts.second = application->lastcheck + lifetime_sec;
2245 zbx_vector_uint64_pair_append(&discovery_applicationts, applicationts);
2246 }
2247 }
2248 else
2249 {
2250 zbx_vector_uint64_append(&lc_discoveryids, application->application_discoveryid);
2251 if (0 != application->ts_delete)
2252 zbx_vector_uint64_append(&ts_discoveryids, application->application_discoveryid);
2253 }
2254 }
2255
2256 /* check if the applications are really 'lost' (not discovered by other discovery rules) */
2257 if (0 != del_applicationids.values_num)
2258 {
2259 zbx_vector_uint64_sort(&del_applicationids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2260
2261 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
2262 "select ad.applicationid from application_discovery ad,application_prototype ap"
2263 " where ad.application_prototypeid=ap.application_prototypeid"
2264 " and ap.itemid<>" ZBX_FS_UI64
2265 " and",
2266 lld_ruleid);
2267 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "ad.applicationid", del_applicationids.values,
2268 del_applicationids.values_num);
2269 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by ad.applicationid desc");
2270
2271 result = DBselect("%s", sql);
2272
2273 sql_offset = 0;
2274
2275 while (NULL != (row = DBfetch(result)))
2276 {
2277 ZBX_STR2UINT64(applicationid, row[0]);
2278
2279 if (FAIL != (index = zbx_vector_uint64_bsearch(&del_applicationids, applicationid,
2280 ZBX_DEFAULT_UINT64_COMPARE_FUNC)))
2281 {
2282 zbx_vector_uint64_remove(&del_applicationids, index);
2283 }
2284 }
2285
2286 DBfree_result(result);
2287 }
2288
2289 if (0 == discovery_applicationts.values_num && 0 == del_applicationids.values_num &&
2290 0 == del_discoveryids.values_num && 0 == ts_discoveryids.values_num &&
2291 0 == lc_discoveryids.values_num)
2292 {
2293 goto clean;
2294 }
2295
2296 /* remove lost applications and update application discovery table */
2297
2298 DBbegin();
2299
2300 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
2301
2302 for (i = 0; i < discovery_applicationts.values_num; i++)
2303 {
2304 zbx_uint64_pair_t *applicationts = &(discovery_applicationts.values[i]);
2305
2306 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
2307 "update application_discovery"
2308 " set ts_delete=%d"
2309 " where application_discoveryid=" ZBX_FS_UI64 ";\n",
2310 (int)applicationts->second, applicationts->first);
2311
2312 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2313 }
2314
2315 if (0 != del_discoveryids.values_num)
2316 {
2317 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from application_discovery where");
2318 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "application_discoveryid",
2319 del_discoveryids.values, del_discoveryids.values_num);
2320 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2321
2322 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2323 }
2324
2325 if (0 != ts_discoveryids.values_num)
2326 {
2327 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update application_discovery"
2328 " set ts_delete=0 where");
2329 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "application_discoveryid",
2330 ts_discoveryids.values, ts_discoveryids.values_num);
2331 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2332
2333 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2334 }
2335
2336 if (0 != lc_discoveryids.values_num)
2337 {
2338 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "update application_discovery"
2339 " set lastcheck=%d where", lastcheck);
2340 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "application_discoveryid",
2341 lc_discoveryids.values, lc_discoveryids.values_num);
2342 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2343
2344 DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset);
2345 }
2346
2347 if (0 != del_applicationids.values_num)
2348 {
2349 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "delete from applications where");
2350 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "applicationid", del_applicationids.values,
2351 del_applicationids.values_num);
2352 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, ";\n");
2353 }
2354
2355 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
2356
2357 if (16 < sql_offset) /* in ORACLE always present begin..end; */
2358 DBexecute("%s", sql);
2359
2360 DBcommit();
2361 clean:
2362 zbx_free(sql);
2363
2364 zbx_vector_uint64_pair_destroy(&discovery_applicationts);
2365 zbx_vector_uint64_destroy(&lc_discoveryids);
2366 zbx_vector_uint64_destroy(&ts_discoveryids);
2367 zbx_vector_uint64_destroy(&del_discoveryids);
2368 zbx_vector_uint64_destroy(&del_applicationids);
2369 out:
2370 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
2371 }
2372
lld_item_links_populate(const zbx_vector_ptr_t * item_prototypes,const zbx_vector_ptr_t * lld_rows,zbx_hashset_t * items_index)2373 static void lld_item_links_populate(const zbx_vector_ptr_t *item_prototypes, const zbx_vector_ptr_t *lld_rows,
2374 zbx_hashset_t *items_index)
2375 {
2376 int i, j;
2377 zbx_lld_item_prototype_t *item_prototype;
2378 zbx_lld_item_index_t *item_index, item_index_local;
2379 zbx_lld_item_link_t *item_link;
2380
2381 for (i = 0; i < item_prototypes->values_num; i++)
2382 {
2383 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[i];
2384 item_index_local.parent_itemid = item_prototype->itemid;
2385
2386 for (j = 0; j < lld_rows->values_num; j++)
2387 {
2388 item_index_local.lld_row = (zbx_lld_row_t *)lld_rows->values[j];
2389
2390 if (NULL == (item_index = zbx_hashset_search(items_index, &item_index_local)))
2391 continue;
2392
2393 if (0 == (item_index->item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
2394 continue;
2395
2396 item_link = (zbx_lld_item_link_t *)zbx_malloc(NULL, sizeof(zbx_lld_item_link_t));
2397
2398 item_link->parent_itemid = item_index->item->parent_itemid;
2399 item_link->itemid = item_index->item->itemid;
2400
2401 zbx_vector_ptr_append(&item_index_local.lld_row->item_links, item_link);
2402 }
2403 }
2404 }
2405
lld_item_links_sort(zbx_vector_ptr_t * lld_rows)2406 void lld_item_links_sort(zbx_vector_ptr_t *lld_rows)
2407 {
2408 int i;
2409
2410 for (i = 0; i < lld_rows->values_num; i++)
2411 {
2412 zbx_lld_row_t *lld_row = (zbx_lld_row_t *)lld_rows->values[i];
2413
2414 zbx_vector_ptr_sort(&lld_row->item_links, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
2415 }
2416 }
2417
2418 /******************************************************************************
2419 * *
2420 * Function: lld_application_prototypes_get *
2421 * *
2422 * Purpose: gets the discovery rule application prototypes from database *
2423 * *
2424 * Parameters: lld_ruleid - [IN] the discovery rule id *
2425 * application_prototypes - [OUT] the applications prototypes *
2426 * defined for the discovery rule, *
2427 * sorted by prototype id *
2428 * *
2429 ******************************************************************************/
lld_application_prototypes_get(zbx_uint64_t lld_ruleid,zbx_vector_ptr_t * application_prototypes)2430 static void lld_application_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *application_prototypes)
2431 {
2432 const char *__function_name = "lld_application_prototypes_get";
2433 DB_RESULT result;
2434 DB_ROW row;
2435 zbx_lld_application_prototype_t *application_prototype;
2436
2437 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2438
2439 result = DBselect(
2440 "select application_prototypeid,name"
2441 " from application_prototype"
2442 " where itemid=" ZBX_FS_UI64,
2443 lld_ruleid);
2444
2445 while (NULL != (row = DBfetch(result)))
2446 {
2447 application_prototype = (zbx_lld_application_prototype_t *)zbx_malloc(NULL,
2448 sizeof(zbx_lld_application_prototype_t));
2449
2450 ZBX_STR2UINT64(application_prototype->application_prototypeid, row[0]);
2451 application_prototype->itemid = lld_ruleid;
2452 application_prototype->name = zbx_strdup(NULL, row[1]);
2453
2454 zbx_vector_ptr_append(application_prototypes, application_prototype);
2455 }
2456 DBfree_result(result);
2457
2458 zbx_vector_ptr_sort(application_prototypes, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
2459
2460 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d prototypes", __function_name, application_prototypes->values_num);
2461 }
2462
2463 /******************************************************************************
2464 * *
2465 * Function: lld_item_application_prototypes_get *
2466 * *
2467 * Purpose: gets the discovery rule item-application link prototypes from *
2468 * database *
2469 * *
2470 * Parameters: item_prototypes - [IN/OUT] item prototypes *
2471 * application_prototypes - [IN] the application prototypes *
2472 * defined for the discovery rule *
2473 * *
2474 ******************************************************************************/
lld_item_application_prototypes_get(const zbx_vector_ptr_t * item_prototypes,const zbx_vector_ptr_t * application_prototypes)2475 static void lld_item_application_prototypes_get(const zbx_vector_ptr_t *item_prototypes,
2476 const zbx_vector_ptr_t *application_prototypes)
2477 {
2478 const char *__function_name = "lld_item_application_prototypes_get";
2479 DB_RESULT result;
2480 DB_ROW row;
2481 int i, index;
2482 zbx_uint64_t application_prototypeid, itemid;
2483 zbx_vector_uint64_t item_prototypeids;
2484 char *sql = NULL;
2485 size_t sql_alloc = 0, sql_offset = 0;
2486 zbx_lld_item_application_ref_t *item_application_prototype;
2487 zbx_lld_item_prototype_t *item_prototype;
2488
2489 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2490
2491 zbx_vector_uint64_create(&item_prototypeids);
2492
2493 /* get item prototype links to application prototypes */
2494
2495 for (i = 0; i < item_prototypes->values_num; i++)
2496 {
2497 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[i];
2498
2499 zbx_vector_uint64_append(&item_prototypeids, item_prototype->itemid);
2500 }
2501
2502 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
2503 "select application_prototypeid,itemid"
2504 " from item_application_prototype"
2505 " where");
2506
2507 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid",
2508 item_prototypeids.values, item_prototypeids.values_num);
2509
2510 result = DBselect("%s", sql);
2511
2512 while (NULL != (row = DBfetch(result)))
2513 {
2514 ZBX_STR2UINT64(application_prototypeid, row[0]);
2515
2516 if (FAIL == (index = zbx_vector_ptr_search(application_prototypes, &application_prototypeid,
2517 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
2518 {
2519 THIS_SHOULD_NEVER_HAPPEN;
2520 continue;
2521 }
2522
2523 item_application_prototype = (zbx_lld_item_application_ref_t *)zbx_malloc(NULL,
2524 sizeof(zbx_lld_item_application_ref_t));
2525
2526 item_application_prototype->application_prototype = application_prototypes->values[index];
2527 item_application_prototype->applicationid = 0;
2528
2529 ZBX_STR2UINT64(itemid, row[1]);
2530 index = zbx_vector_ptr_bsearch(item_prototypes, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
2531 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[index];
2532
2533 zbx_vector_ptr_append(&item_prototype->applications, item_application_prototype);
2534 }
2535 DBfree_result(result);
2536
2537 /* get item prototype links to real applications */
2538
2539 sql_offset = 0;
2540 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset,
2541 "select applicationid,itemid"
2542 " from items_applications"
2543 " where");
2544
2545 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "itemid",
2546 item_prototypeids.values, item_prototypeids.values_num);
2547
2548 result = DBselect("%s", sql);
2549
2550 while (NULL != (row = DBfetch(result)))
2551 {
2552 item_application_prototype = (zbx_lld_item_application_ref_t *)zbx_malloc(NULL,
2553 sizeof(zbx_lld_item_application_ref_t));
2554
2555 item_application_prototype->application_prototype = NULL;
2556 ZBX_STR2UINT64(item_application_prototype->applicationid, row[0]);
2557
2558 ZBX_STR2UINT64(itemid, row[1]);
2559 index = zbx_vector_ptr_bsearch(item_prototypes, &itemid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
2560 item_prototype = (zbx_lld_item_prototype_t *)item_prototypes->values[index];
2561
2562 zbx_vector_ptr_append(&item_prototype->applications, item_application_prototype);
2563 }
2564 DBfree_result(result);
2565
2566 zbx_free(sql);
2567 zbx_vector_uint64_destroy(&item_prototypeids);
2568
2569 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
2570 }
2571
2572 /******************************************************************************
2573 * *
2574 * Function: lld_applications_get *
2575 * *
2576 * Purpose: gets applications previously discovered by the discovery rule *
2577 * *
2578 * Parameters: lld_ruleid - [IN] the discovery rule id *
2579 * applications - [OUT] the applications *
2580 * *
2581 ******************************************************************************/
lld_applications_get(zbx_uint64_t lld_ruleid,zbx_vector_ptr_t * applications)2582 static void lld_applications_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *applications)
2583 {
2584 const char *__function_name = "lld_applications_get";
2585 DB_RESULT result;
2586 DB_ROW row;
2587 zbx_lld_application_t *application;
2588
2589 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2590
2591 result = DBselect(
2592 "select a.applicationid,a.name,ap.application_prototypeid,ad.lastcheck,ad.ts_delete,ad.name,"
2593 "ad.application_discoveryid"
2594 " from applications a,application_discovery ad,application_prototype ap"
2595 " where ap.itemid=" ZBX_FS_UI64
2596 " and ad.application_prototypeid=ap.application_prototypeid"
2597 " and a.applicationid=ad.applicationid",
2598 lld_ruleid);
2599
2600 while (NULL != (row = DBfetch(result)))
2601 {
2602 application = (zbx_lld_application_t *)zbx_malloc(NULL, sizeof(zbx_lld_application_t));
2603
2604 ZBX_STR2UINT64(application->applicationid, row[0]);
2605 ZBX_STR2UINT64(application->application_prototypeid, row[2]);
2606 ZBX_STR2UINT64(application->application_discoveryid, row[6]);
2607 application->name = zbx_strdup(NULL, row[1]);
2608 application->lastcheck = atoi(row[3]);
2609 application->ts_delete = atoi(row[4]);
2610 application->name_proto = zbx_strdup(NULL, row[5]);
2611 application->name_orig = NULL;
2612 application->flags = ZBX_FLAG_LLD_APPLICATION_UNSET;
2613 application->lld_row = NULL;
2614
2615 zbx_vector_ptr_append(applications, application);
2616 }
2617 DBfree_result(result);
2618
2619 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d applications", __function_name, applications->values_num);
2620 }
2621
2622 /******************************************************************************
2623 * *
2624 * Function: lld_application_make *
2625 * *
2626 * Purpose: create a new application or mark an existing application as *
2627 * discovered based on prototype and lld row *
2628 * *
2629 * Parameters: application_prototype - [IN] the application prototype *
2630 * lld_row - [IN] the lld row *
2631 * applications - [IN/OUT] the applications *
2632 * applications_index - [IN/OUT] the application index by *
2633 * prototype id and lld row *
2634 * *
2635 ******************************************************************************/
lld_application_make(const zbx_lld_application_prototype_t * application_prototype,const zbx_lld_row_t * lld_row,zbx_vector_ptr_t * applications,zbx_hashset_t * applications_index)2636 static void lld_application_make(const zbx_lld_application_prototype_t *application_prototype,
2637 const zbx_lld_row_t *lld_row, zbx_vector_ptr_t *applications, zbx_hashset_t *applications_index)
2638 {
2639 zbx_lld_application_t *application;
2640 zbx_lld_application_index_t *application_index, application_index_local;
2641 struct zbx_json_parse *jp_row = (struct zbx_json_parse *)&lld_row->jp_row;
2642 char *buffer = NULL;
2643
2644 application_index_local.application_prototypeid = application_prototype->application_prototypeid;
2645 application_index_local.lld_row = lld_row;
2646
2647 if (NULL == (application_index = zbx_hashset_search(applications_index, &application_index_local)))
2648 {
2649 application = (zbx_lld_application_t *)zbx_malloc(NULL, sizeof(zbx_lld_application_t));
2650 application->applicationid = 0;
2651 application->application_prototypeid = application_prototype->application_prototypeid;
2652 application->application_discoveryid = 0;
2653 application->ts_delete = 0;
2654
2655 application->name = zbx_strdup(NULL, application_prototype->name);
2656 substitute_discovery_macros(&application->name, jp_row, ZBX_MACRO_ANY, NULL, 0);
2657 zbx_lrtrim(application->name, ZBX_WHITESPACE);
2658
2659 application->name_proto = zbx_strdup(NULL, application_prototype->name);
2660 application->name_orig = NULL;
2661 application->flags = ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY;
2662 application->lld_row = lld_row;
2663
2664 zbx_vector_ptr_append(applications, application);
2665
2666 application_index_local.application = application;
2667 zbx_hashset_insert(applications_index, &application_index_local, sizeof(zbx_lld_application_index_t));
2668 }
2669 else
2670 {
2671 application = application_index->application;
2672
2673 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME))
2674 {
2675 buffer = zbx_strdup(NULL, application_prototype->name);
2676 substitute_discovery_macros(&buffer, jp_row, ZBX_MACRO_ANY, NULL, 0);
2677 zbx_lrtrim(buffer, ZBX_WHITESPACE);
2678
2679 if (0 != strcmp(application->name, buffer))
2680 {
2681 application->name_orig = application->name;
2682 application->name = buffer;
2683 application->flags |= ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME;
2684 }
2685 else
2686 zbx_free(buffer);
2687 }
2688 }
2689
2690 application->flags |= ZBX_FLAG_LLD_APPLICATION_DISCOVERED;
2691 }
2692
2693 /******************************************************************************
2694 * *
2695 * Function: lld_applications_make *
2696 * *
2697 * Purpose: makes new applications and marks old applications as discovered *
2698 * based on application prototypes and lld rows *
2699 * *
2700 * Parameters: application_prototypes - [IN] the application prototypes *
2701 * lld_rows - [IN] the lld rows *
2702 * applications - [IN/OUT] the applications *
2703 * applications_index - [OUT] the application index by *
2704 * prototype id and lld row *
2705 * *
2706 ******************************************************************************/
lld_applications_make(const zbx_vector_ptr_t * application_prototypes,const zbx_vector_ptr_t * lld_rows,zbx_vector_ptr_t * applications,zbx_hashset_t * applications_index)2707 static void lld_applications_make(const zbx_vector_ptr_t *application_prototypes,
2708 const zbx_vector_ptr_t *lld_rows, zbx_vector_ptr_t *applications, zbx_hashset_t *applications_index)
2709 {
2710 const char *__function_name = "lld_applications_make";
2711 int i, j;
2712 zbx_lld_application_t *application;
2713 zbx_lld_row_t *lld_row;
2714 zbx_lld_application_index_t application_index_local;
2715 char *buffer = NULL;
2716
2717 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2718
2719 /* index existing applications */
2720
2721 for (i = 0; i < applications->values_num; i++)
2722 {
2723 application = (zbx_lld_application_t *)applications->values[i];
2724
2725 for (j = 0; j < lld_rows->values_num; j++)
2726 {
2727 lld_row = (zbx_lld_row_t *)lld_rows->values[j];
2728
2729 buffer = zbx_strdup(buffer, application->name_proto);
2730 substitute_discovery_macros(&buffer, &lld_row->jp_row, ZBX_MACRO_ANY, NULL, 0);
2731 zbx_lrtrim(buffer, ZBX_WHITESPACE);
2732
2733 if (0 == strcmp(application->name, buffer))
2734 {
2735 application_index_local.application_prototypeid = application->application_prototypeid;
2736 application_index_local.lld_row = lld_row;
2737 application_index_local.application = application;
2738 zbx_hashset_insert(applications_index, &application_index_local,
2739 sizeof(application_index_local));
2740
2741 application->lld_row = lld_row;
2742 }
2743 }
2744 }
2745
2746 zbx_free(buffer);
2747
2748 /* make the applications */
2749 for (i = 0; i < application_prototypes->values_num; i++)
2750 {
2751 for (j = 0; j < lld_rows->values_num; j++)
2752 {
2753 lld_application_make(application_prototypes->values[i], lld_rows->values[j], applications,
2754 applications_index);
2755 }
2756 }
2757
2758 zbx_vector_ptr_sort(applications, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
2759
2760 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d applications", __function_name, applications->values_num);
2761 }
2762
2763 /******************************************************************************
2764 * *
2765 * Function: lld_applications_validate *
2766 * *
2767 * Purpose: validates the discovered and renamed applications *
2768 * *
2769 * Parameters: hostid - [IN] host id *
2770 * lld_ruleid - [IN] the discovery rule id *
2771 * applications - [IN/OUT] the applications *
2772 * applications_index - [OUT] the application index by *
2773 * prototype id and lld row *
2774 * error - [IN/OUT] the lld error message *
2775 * *
2776 ******************************************************************************/
lld_applications_validate(zbx_uint64_t hostid,zbx_uint64_t lld_ruleid,zbx_vector_ptr_t * applications,zbx_hashset_t * applications_index,char ** error)2777 static void lld_applications_validate(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *applications,
2778 zbx_hashset_t *applications_index, char **error)
2779 {
2780 const char *__function_name = "lld_applications_validate";
2781 int i, j, index;
2782 DB_RESULT result;
2783 DB_ROW row;
2784 zbx_lld_application_t *application, *new_application, application_local;
2785 char *sql = NULL;
2786 size_t sql_alloc = 0, sql_offset = 0;
2787 zbx_vector_str_t names_new, names_old;
2788 zbx_lld_application_index_t *application_index, application_index_local;
2789
2790 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
2791
2792 if (0 == applications->values_num)
2793 goto out;
2794
2795 zbx_vector_str_create(&names_new);
2796 zbx_vector_str_create(&names_old);
2797
2798 /* check for conflicting application names in the discovered applications */
2799
2800 for (i = 0; i < applications->values_num; i++)
2801 {
2802 application = (zbx_lld_application_t *)applications->values[i];
2803
2804 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
2805 continue;
2806
2807 if (0 != application->applicationid && 0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME))
2808 continue;
2809
2810 /* iterate in reverse order so existing applications would have more priority */
2811 /* than new applications which have 0 applicationid and therefore are located */
2812 /* at the beginning of applications vector which is sorted by applicationid */
2813 for (j = applications->values_num - 1; j > i; j--)
2814 {
2815 zbx_lld_application_t *application_compare = (zbx_lld_application_t *)applications->values[j];
2816
2817 if (0 != strcmp(application->name, application_compare->name))
2818 continue;
2819
2820 /* Applications with matching names are validated depending on their prototypes. */
2821 /* If they are discovered by different prototypes we must fail with appropriate */
2822 /* lld error. */
2823 /* Otherwise we 'merge' application by updating index of the validated */
2824 /* validated application to point at the application with the same name. */
2825 /* In both cases the validated application is flagged as non-discovered. */
2826 application->flags &= ~ZBX_FLAG_LLD_ITEM_DISCOVERED;
2827
2828 /* fail if application has different prototype */
2829 if (application->application_prototypeid != application_compare->application_prototypeid)
2830 {
2831 *error = zbx_strdcatf(*error, "Cannot %s application:"
2832 " application with the same name \"%s\" already exists.\n",
2833 (0 != application->applicationid ? "update" : "create"),
2834 application->name);
2835
2836 break;
2837 }
2838
2839 /* update application index to use the matching application */
2840
2841 application_index_local.application_prototypeid = application->application_prototypeid;
2842 application_index_local.lld_row = application->lld_row;
2843
2844 if (NULL == (application_index = zbx_hashset_search(applications_index,
2845 &application_index_local)))
2846 {
2847 THIS_SHOULD_NEVER_HAPPEN;
2848 break;
2849 }
2850
2851 application_index->application = application_compare;
2852 break;
2853 }
2854
2855 /* Prepare name lists to resolve naming conflicts with applications */
2856 /* discovered by other discovery rules: */
2857 /* names_new - to check if discovered/renamed application names */
2858 /* don't match existing applications discovered by */
2859 /* other discovery rules */
2860 /* names_old - to check if renamed applications were also */
2861 /* discovered by other discovery rules */
2862 if (i == j)
2863 {
2864 zbx_vector_str_append(&names_new, application->name);
2865
2866 if (NULL != application->name_orig)
2867 zbx_vector_str_append(&names_old, application->name_orig);
2868 }
2869 }
2870
2871 /* validate new/renamed application names against applications discovered */
2872 /* by other discovery rules */
2873
2874 if (0 != names_new.values_num)
2875 {
2876 zbx_vector_str_sort(&names_new, ZBX_DEFAULT_STR_COMPARE_FUNC);
2877
2878 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
2879 "select applicationid,name,flags"
2880 " from applications"
2881 " where hostid=" ZBX_FS_UI64
2882 " and",
2883 hostid);
2884 DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "name",
2885 (const char **)names_new.values, names_new.values_num);
2886
2887 result = DBselect("%s", sql);
2888
2889 application_local.flags = ZBX_FLAG_LLD_APPLICATION_DISCOVERED;
2890
2891 while (NULL != (row = DBfetch(result)))
2892 {
2893 application_local.name = row[1];
2894
2895 if (FAIL == (index = zbx_vector_ptr_search(applications, &application_local,
2896 lld_application_compare_name)))
2897 {
2898 THIS_SHOULD_NEVER_HAPPEN;
2899 continue;
2900 }
2901
2902 application = applications->values[index];
2903
2904 /* only discovered applications can be 'shared' between discovery rules */
2905 if (ZBX_FLAG_DISCOVERY_CREATED != atoi(row[2]))
2906 {
2907 /* conflicting application name, reset discovery flags */
2908 application->flags = ZBX_FLAG_LLD_APPLICATION_UNSET;
2909
2910 *error = zbx_strdcatf(*error, "Cannot create application:"
2911 " non-discovered application"
2912 " with the same name \"%s\" already exists.\n",
2913 application->name);
2914
2915 continue;
2916 }
2917
2918 if (0 != (application->flags & ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME))
2919 {
2920 /* During discovery process the application was renamed to an */
2921 /* application already discovered by another discovery rule. */
2922 /* In this case we must delete the old application and relink */
2923 /* its items to the application we have found. */
2924
2925 /* create a pseudo application to remove the renamed application */
2926
2927 new_application = (zbx_lld_application_t *)zbx_malloc(NULL,
2928 sizeof(zbx_lld_application_t));
2929
2930 memset(new_application, 0, sizeof(zbx_lld_application_t));
2931 new_application->applicationid = application->applicationid;
2932 new_application->flags = ZBX_FLAG_LLD_APPLICATION_REMOVE;
2933
2934 zbx_vector_ptr_append(applications, new_application);
2935
2936 /* update application flags so that instead of renaming it a new */
2937 /* discovery record is created */
2938
2939 application->application_discoveryid = 0;
2940 application->flags &= ~ZBX_FLAG_LLD_APPLICATION_UPDATE_NAME;
2941 application->flags |= ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY;
2942 }
2943
2944 /* reuse application created by another discovery rule */
2945 ZBX_STR2UINT64(application->applicationid, row[0]);
2946 }
2947 DBfree_result(result);
2948 }
2949
2950 /* if an application shared with other discovery rule has been renamed we must */
2951 /* create a new application with the new name instead of renaming the old one */
2952
2953 if (0 != names_old.values_num)
2954 {
2955 sql_offset = 0;
2956
2957 zbx_vector_str_sort(&names_old, ZBX_DEFAULT_STR_COMPARE_FUNC);
2958
2959 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
2960 "select a.name"
2961 " from applications a,application_discovery ad,application_prototype ap"
2962 " where a.applicationid=ad.applicationid"
2963 " and ad.application_prototypeid=ap.application_prototypeid"
2964 " and a.hostid=" ZBX_FS_UI64
2965 " and ap.itemid<>" ZBX_FS_UI64
2966 " and",
2967 hostid, lld_ruleid);
2968 DBadd_str_condition_alloc(&sql, &sql_alloc, &sql_offset, "a.name",
2969 (const char **)names_old.values, names_old.values_num);
2970
2971 result = DBselect("%s", sql);
2972
2973 application_local.flags = ZBX_FLAG_LLD_APPLICATION_DISCOVERED;
2974
2975 while (NULL != (row = DBfetch(result)))
2976 {
2977 application_local.name_orig = row[0];
2978
2979 if (FAIL == (index = zbx_vector_ptr_search(applications, &application_local,
2980 lld_application_compare_name_orig)))
2981 {
2982 THIS_SHOULD_NEVER_HAPPEN;
2983 continue;
2984 }
2985
2986 application = applications->values[index];
2987
2988 /* add a pseudo application to remove the application discovery record */
2989 /* of the shared application and current discovery rule */
2990 new_application = (zbx_lld_application_t *)zbx_malloc(NULL, sizeof(zbx_lld_application_t));
2991 memset(new_application, 0, sizeof(zbx_lld_application_t));
2992 new_application->applicationid = application->applicationid;
2993 new_application->application_prototypeid = application->application_prototypeid;
2994 new_application->application_discoveryid = application->application_discoveryid;
2995 new_application->flags = ZBX_FLAG_LLD_APPLICATION_REMOVE_DISCOVERY;
2996 zbx_vector_ptr_append(applications, new_application);
2997
2998 /* reset applicationid, application_discoveryid and flags */
2999 /* so a new application is created instead of renaming the shared one */
3000 application->applicationid = 0;
3001 application->application_discoveryid = 0;
3002 application->flags = ZBX_FLAG_LLD_APPLICATION_ADD_DISCOVERY |
3003 ZBX_FLAG_LLD_APPLICATION_DISCOVERED;
3004 }
3005 DBfree_result(result);
3006 }
3007
3008 zbx_vector_str_destroy(&names_old);
3009 zbx_vector_str_destroy(&names_new);
3010
3011 zbx_free(sql);
3012
3013 zbx_vector_ptr_sort(applications, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
3014 out:
3015 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
3016 }
3017
3018 /******************************************************************************
3019 * *
3020 * Function: lld_items_applications_get *
3021 * *
3022 * Purpose: gets item-application links for the lld rule *
3023 * *
3024 * Parameters: lld_rule - [IN] the lld rule *
3025 * items_applications - [OUT] the item-application links *
3026 * *
3027 ******************************************************************************/
lld_items_applications_get(zbx_uint64_t lld_ruleid,zbx_hashset_t * items_applications)3028 static void lld_items_applications_get(zbx_uint64_t lld_ruleid, zbx_hashset_t *items_applications)
3029 {
3030 const char *__function_name = "lld_items_applications_get";
3031 DB_RESULT result;
3032 DB_ROW row;
3033 zbx_lld_item_application_t item_application;
3034
3035 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
3036
3037 result = DBselect(
3038 "select ia.itemappid,ia.itemid,ia.applicationid"
3039 " from items_applications ia,item_discovery id1,item_discovery id2"
3040 " where id1.itemid=ia.itemid"
3041 " and id1.parent_itemid=id2.itemid"
3042 " and id2.parent_itemid=" ZBX_FS_UI64,
3043 lld_ruleid);
3044
3045 item_application.application_ref.application = NULL;
3046 item_application.item_ref.item = NULL;
3047
3048 while (NULL != (row = DBfetch(result)))
3049 {
3050 ZBX_STR2UINT64(item_application.itemappid, row[0]);
3051 ZBX_STR2UINT64(item_application.item_ref.itemid, row[1]);
3052 ZBX_STR2UINT64(item_application.application_ref.applicationid, row[2]);
3053 item_application.flags = ZBX_FLAG_LLD_ITEM_APPLICATION_UNSET;
3054
3055 zbx_hashset_insert(items_applications, &item_application, sizeof(zbx_lld_item_application_t));
3056 }
3057 DBfree_result(result);
3058
3059 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d links", __function_name, items_applications->num_data);
3060 }
3061
3062 /******************************************************************************
3063 * *
3064 * Function: lld_items_applications_make *
3065 * *
3066 * Purpose: makes new item-application links and marks existing links as *
3067 * discovered based on item_prototypes applications links *
3068 * *
3069 * Parameters: item_prototypes - [IN] the item prototypes *
3070 * items - [IN] the items *
3071 * applications - [IN] the applications *
3072 * applications_index - [IN] the application index by *
3073 * prototype id and lld row *
3074 * items_applications - [IN/OUT] the item-application links *
3075 * *
3076 ******************************************************************************/
lld_items_applications_make(const zbx_vector_ptr_t * item_prototypes,const zbx_vector_ptr_t * items,const zbx_vector_ptr_t * applications,zbx_hashset_t * applications_index,zbx_hashset_t * items_applications)3077 static void lld_items_applications_make(const zbx_vector_ptr_t *item_prototypes, const zbx_vector_ptr_t *items,
3078 const zbx_vector_ptr_t *applications, zbx_hashset_t *applications_index,
3079 zbx_hashset_t *items_applications)
3080 {
3081 const char *__function_name = "lld_items_applications_make";
3082 int i, j, index;
3083 zbx_lld_item_application_t *item_application, item_application_local;
3084 zbx_lld_application_t *application;
3085 zbx_lld_item_prototype_t *item_prototype;
3086 zbx_lld_item_t *item;
3087 zbx_lld_item_application_ref_t *itemapp_prototype;
3088 zbx_lld_application_index_t *application_index, application_index_local;
3089
3090 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
3091
3092 item_application_local.itemappid = 0;
3093 item_application_local.flags = ZBX_FLAG_LLD_ITEM_APPLICATION_DISCOVERED;
3094
3095 for (i = 0; i < items->values_num; i++)
3096 {
3097 item = items->values[i];
3098
3099 if (0 == (item->flags & ZBX_FLAG_LLD_ITEM_DISCOVERED))
3100 continue;
3101
3102 /* if item is discovered its prototype must be in item_prototypes vector */
3103 index = zbx_vector_ptr_bsearch(item_prototypes, &item->parent_itemid,
3104 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
3105 item_prototype = item_prototypes->values[index];
3106
3107 application_index_local.lld_row = item->lld_row;
3108
3109 if (0 == (item_application_local.item_ref.itemid = item->itemid))
3110 item_application_local.item_ref.item = item;
3111 else
3112 item_application_local.item_ref.item = NULL;
3113
3114 for (j = 0; j < item_prototype->applications.values_num; j++)
3115 {
3116 itemapp_prototype = item_prototype->applications.values[j];
3117
3118 if (NULL != itemapp_prototype->application_prototype)
3119 {
3120 application_index_local.application_prototypeid =
3121 itemapp_prototype->application_prototype->application_prototypeid;
3122
3123 if (NULL == (application_index = zbx_hashset_search(applications_index,
3124 &application_index_local)))
3125 {
3126 continue;
3127 }
3128
3129 application = application_index->application;
3130
3131 if (0 == (application->flags & ZBX_FLAG_LLD_APPLICATION_DISCOVERED))
3132 continue;
3133
3134 if (0 == (item_application_local.application_ref.applicationid =
3135 application->applicationid))
3136 {
3137 item_application_local.application_ref.application = application;
3138 }
3139 else
3140 item_application_local.application_ref.application = NULL;
3141 }
3142 else
3143 {
3144 item_application_local.application_ref.application = NULL;
3145 item_application_local.application_ref.applicationid = itemapp_prototype->applicationid;
3146 }
3147
3148 if (NULL == (item_application = zbx_hashset_search(items_applications,
3149 &item_application_local)))
3150 {
3151 item_application = zbx_hashset_insert(items_applications, &item_application_local,
3152 sizeof(zbx_lld_item_application_t));
3153 }
3154
3155 item_application->flags = ZBX_FLAG_LLD_ITEM_APPLICATION_DISCOVERED;
3156 }
3157 }
3158
3159 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d links", __function_name, items_applications->num_data);
3160 }
3161
3162 /******************************************************************************
3163 * *
3164 * Function: lld_item_prototypes_get *
3165 * *
3166 * Purpose: load discovery rule item prototypes *
3167 * *
3168 * Parameters: lld_ruleid - [IN] the discovery rule id *
3169 * item_prototypes - [OUT] the item prototypes *
3170 * *
3171 ******************************************************************************/
lld_item_prototypes_get(zbx_uint64_t lld_ruleid,zbx_vector_ptr_t * item_prototypes)3172 static void lld_item_prototypes_get(zbx_uint64_t lld_ruleid, zbx_vector_ptr_t *item_prototypes)
3173 {
3174 const char *__function_name = "lld_item_prototypes_get";
3175 DB_RESULT result;
3176 DB_ROW row;
3177 zbx_lld_item_prototype_t *item_prototype;
3178
3179 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
3180
3181 result = DBselect(
3182 "select i.itemid,i.name,i.key_,i.type,i.value_type,i.data_type,i.delay,i.delay_flex,"
3183 "i.history,i.trends,i.status,i.trapper_hosts,i.units,i.multiplier,i.delta,i.formula,"
3184 "i.logtimefmt,i.valuemapid,i.params,i.ipmi_sensor,i.snmp_community,i.snmp_oid,"
3185 "i.port,i.snmpv3_securityname,i.snmpv3_securitylevel,i.snmpv3_authprotocol,"
3186 "i.snmpv3_authpassphrase,i.snmpv3_privprotocol,i.snmpv3_privpassphrase,i.authtype,"
3187 "i.username,i.password,i.publickey,i.privatekey,i.description,i.interfaceid,"
3188 "i.snmpv3_contextname"
3189 " from items i,item_discovery id"
3190 " where i.itemid=id.itemid"
3191 " and id.parent_itemid=" ZBX_FS_UI64,
3192 lld_ruleid);
3193
3194 while (NULL != (row = DBfetch(result)))
3195 {
3196 item_prototype = (zbx_lld_item_prototype_t *)zbx_malloc(NULL, sizeof(zbx_lld_item_prototype_t));
3197
3198 ZBX_STR2UINT64(item_prototype->itemid, row[0]);
3199 item_prototype->name = zbx_strdup(NULL, row[1]);
3200 item_prototype->key = zbx_strdup(NULL, row[2]);
3201 ZBX_STR2UCHAR(item_prototype->type, row[3]);
3202 ZBX_STR2UCHAR(item_prototype->value_type, row[4]);
3203 ZBX_STR2UCHAR(item_prototype->data_type, row[5]);
3204 item_prototype->delay = atoi(row[6]);
3205 item_prototype->delay_flex = zbx_strdup(NULL, row[7]);
3206 item_prototype->history = atoi(row[8]);
3207 item_prototype->trends = atoi(row[9]);
3208 ZBX_STR2UCHAR(item_prototype->status, row[10]);
3209 item_prototype->trapper_hosts = zbx_strdup(NULL, row[11]);
3210 item_prototype->units = zbx_strdup(NULL, row[12]);
3211 ZBX_STR2UCHAR(item_prototype->multiplier, row[13]);
3212 ZBX_STR2UCHAR(item_prototype->delta, row[14]);
3213 item_prototype->formula = zbx_strdup(NULL, row[15]);
3214 item_prototype->logtimefmt = zbx_strdup(NULL, row[16]);
3215 ZBX_DBROW2UINT64(item_prototype->valuemapid, row[17]);
3216 item_prototype->params = zbx_strdup(NULL, row[18]);
3217 item_prototype->ipmi_sensor = zbx_strdup(NULL, row[19]);
3218 item_prototype->snmp_community = zbx_strdup(NULL, row[20]);
3219 item_prototype->snmp_oid = zbx_strdup(NULL, row[21]);
3220 item_prototype->port = zbx_strdup(NULL, row[22]);
3221 item_prototype->snmpv3_securityname = zbx_strdup(NULL, row[23]);
3222 ZBX_STR2UCHAR(item_prototype->snmpv3_securitylevel, row[24]);
3223 ZBX_STR2UCHAR(item_prototype->snmpv3_authprotocol, row[25]);
3224 item_prototype->snmpv3_authpassphrase = zbx_strdup(NULL, row[26]);
3225 ZBX_STR2UCHAR(item_prototype->snmpv3_privprotocol, row[27]);
3226 item_prototype->snmpv3_privpassphrase = zbx_strdup(NULL, row[28]);
3227 ZBX_STR2UCHAR(item_prototype->authtype, row[29]);
3228 item_prototype->username = zbx_strdup(NULL, row[30]);
3229 item_prototype->password = zbx_strdup(NULL, row[31]);
3230 item_prototype->publickey = zbx_strdup(NULL, row[32]);
3231 item_prototype->privatekey = zbx_strdup(NULL, row[33]);
3232 item_prototype->description = zbx_strdup(NULL, row[34]);
3233 ZBX_DBROW2UINT64(item_prototype->interfaceid, row[35]);
3234 item_prototype->snmpv3_contextname = zbx_strdup(NULL, row[36]);
3235
3236 zbx_vector_ptr_create(&item_prototype->lld_rows);
3237 zbx_vector_ptr_create(&item_prototype->applications);
3238
3239 zbx_vector_ptr_append(item_prototypes, item_prototype);
3240 }
3241 DBfree_result(result);
3242
3243 zbx_vector_ptr_sort(item_prototypes, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
3244
3245 zabbix_log(LOG_LEVEL_DEBUG, "End of %s():%d prototypes", __function_name, item_prototypes->values_num);
3246 }
3247
3248 /******************************************************************************
3249 * *
3250 * Function: lld_update_items *
3251 * *
3252 * Purpose: add or update discovered items *
3253 * *
3254 * Return value: SUCCEED - if items were successfully added/updated or *
3255 * adding/updating was not necessary *
3256 * FAIL - items cannot be added/updated *
3257 * *
3258 ******************************************************************************/
lld_update_items(zbx_uint64_t hostid,zbx_uint64_t lld_ruleid,const zbx_vector_ptr_t * lld_rows,char ** error,unsigned short lifetime,int lastcheck)3259 int lld_update_items(zbx_uint64_t hostid, zbx_uint64_t lld_ruleid, const zbx_vector_ptr_t *lld_rows, char **error,
3260 unsigned short lifetime, int lastcheck)
3261 {
3262 const char *__function_name = "lld_update_items";
3263
3264 zbx_vector_ptr_t applications, application_prototypes, items, item_prototypes;
3265 zbx_hashset_t applications_index, items_index, items_applications;
3266 int ret = SUCCEED, host_record_is_locked = 0;
3267
3268 zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);
3269
3270 zbx_vector_ptr_create(&item_prototypes);
3271
3272 lld_item_prototypes_get(lld_ruleid, &item_prototypes);
3273
3274 if (0 == item_prototypes.values_num)
3275 goto out;
3276
3277 zbx_vector_ptr_create(&application_prototypes);
3278
3279 lld_application_prototypes_get(lld_ruleid, &application_prototypes);
3280
3281 zbx_vector_ptr_create(&applications);
3282 zbx_hashset_create(&applications_index, application_prototypes.values_num * lld_rows->values_num,
3283 lld_application_index_hash_func, lld_application_index_compare_func);
3284
3285 zbx_vector_ptr_create(&items);
3286 zbx_hashset_create(&items_index, item_prototypes.values_num * lld_rows->values_num, lld_item_index_hash_func,
3287 lld_item_index_compare_func);
3288
3289 zbx_hashset_create(&items_applications, 100, lld_item_application_hash_func, lld_item_application_compare_func);
3290
3291 lld_applications_get(lld_ruleid, &applications);
3292 lld_applications_make(&application_prototypes, lld_rows, &applications, &applications_index);
3293 lld_applications_validate(hostid, lld_ruleid, &applications, &applications_index, error);
3294
3295 lld_item_application_prototypes_get(&item_prototypes, &application_prototypes);
3296
3297 lld_items_get(&item_prototypes, &items);
3298 lld_items_make(&item_prototypes, lld_rows, &items, &items_index, error);
3299 lld_items_validate(hostid, &items, error);
3300
3301 lld_items_applications_get(lld_ruleid, &items_applications);
3302 lld_items_applications_make(&item_prototypes, &items, &applications, &applications_index, &items_applications);
3303
3304 DBbegin();
3305
3306 if (SUCCEED == lld_items_save(hostid, &item_prototypes, &items, &host_record_is_locked) &&
3307 SUCCEED == lld_applications_save(hostid, &applications, &application_prototypes,
3308 &host_record_is_locked))
3309 {
3310 lld_items_applications_save(&items_applications, &items, &applications);
3311 DBcommit();
3312 }
3313 else
3314 {
3315 ret = FAIL;
3316 DBrollback();
3317 goto clean;
3318 }
3319
3320 lld_item_links_populate(&item_prototypes, lld_rows, &items_index);
3321 lld_remove_lost_items(&items, lifetime, lastcheck);
3322 lld_remove_lost_applications(lld_ruleid, &applications, lifetime, lastcheck);
3323 clean:
3324 zbx_hashset_destroy(&items_applications);
3325 zbx_hashset_destroy(&items_index);
3326
3327 zbx_vector_ptr_clear_ext(&items, (zbx_clean_func_t)lld_item_free);
3328 zbx_vector_ptr_destroy(&items);
3329
3330 zbx_hashset_destroy(&applications_index);
3331
3332 zbx_vector_ptr_clear_ext(&applications, (zbx_clean_func_t)lld_application_free);
3333 zbx_vector_ptr_destroy(&applications);
3334
3335 zbx_vector_ptr_clear_ext(&application_prototypes, (zbx_clean_func_t)lld_application_prototype_free);
3336 zbx_vector_ptr_destroy(&application_prototypes);
3337
3338 zbx_vector_ptr_clear_ext(&item_prototypes, (zbx_clean_func_t)lld_item_prototype_free);
3339 out:
3340 zbx_vector_ptr_destroy(&item_prototypes);
3341
3342 zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __function_name);
3343
3344 return ret;
3345 }
3346