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 "common.h"
21 #include "log.h"
22 #include "dbcache.h"
23 #include "zbxserver.h"
24 #include "mutexs.h"
25
26 #define ZBX_DBCONFIG_IMPL
27 #include "dbconfig.h"
28 #include "dbsync.h"
29
30 typedef struct
31 {
32 zbx_hashset_t strpool;
33 ZBX_DC_CONFIG *cache;
34 }
35 zbx_dbsync_env_t;
36
37 static zbx_dbsync_env_t dbsync_env;
38
39 /* string pool support */
40
41 #define REFCOUNT_FIELD_SIZE sizeof(zbx_uint32_t)
42
dbsync_strpool_hash_func(const void * data)43 static zbx_hash_t dbsync_strpool_hash_func(const void *data)
44 {
45 return ZBX_DEFAULT_STRING_HASH_FUNC((char *)data + REFCOUNT_FIELD_SIZE);
46 }
47
dbsync_strpool_compare_func(const void * d1,const void * d2)48 static int dbsync_strpool_compare_func(const void *d1, const void *d2)
49 {
50 return strcmp((char *)d1 + REFCOUNT_FIELD_SIZE, (char *)d2 + REFCOUNT_FIELD_SIZE);
51 }
52
dbsync_strdup(const char * str)53 static char *dbsync_strdup(const char *str)
54 {
55 void *ptr;
56
57 ptr = zbx_hashset_search(&dbsync_env.strpool, str - REFCOUNT_FIELD_SIZE);
58
59 if (NULL == ptr)
60 {
61 ptr = zbx_hashset_insert_ext(&dbsync_env.strpool, str - REFCOUNT_FIELD_SIZE,
62 REFCOUNT_FIELD_SIZE + strlen(str) + 1, REFCOUNT_FIELD_SIZE);
63
64 *(zbx_uint32_t *)ptr = 0;
65 }
66
67 (*(zbx_uint32_t *)ptr)++;
68
69 return (char *)ptr + REFCOUNT_FIELD_SIZE;
70 }
71
dbsync_strfree(char * str)72 static void dbsync_strfree(char *str)
73 {
74 if (NULL != str)
75 {
76 void *ptr = str - REFCOUNT_FIELD_SIZE;
77
78 if (0 == --(*(zbx_uint32_t *)ptr))
79 zbx_hashset_remove_direct(&dbsync_env.strpool, ptr);
80 }
81 }
82
83 /* macro valie validators */
84
85 /******************************************************************************
86 * *
87 * Function: dbsync_numeric_validator *
88 * *
89 * Purpose: validate numeric value *
90 * *
91 * Parameters: value - [IN] the value to validate *
92 * *
93 * Return value: SUCCEED - the value contains valid numeric value *
94 * FAIL - otherwise *
95 * *
96 ******************************************************************************/
dbsync_numeric_validator(const char * value)97 static int dbsync_numeric_validator(const char *value)
98 {
99 if (SUCCEED == is_double_suffix(value, ZBX_FLAG_DOUBLE_SUFFIX))
100 return SUCCEED;
101
102 return FAIL;
103 }
104
105 /******************************************************************************
106 * *
107 * Function: dbsync_compare_uint64 *
108 * *
109 * Purpose: compares 64 bit unsigned integer with a raw database value *
110 * *
111 ******************************************************************************/
dbsync_compare_uint64(const char * value_raw,zbx_uint64_t value)112 static int dbsync_compare_uint64(const char *value_raw, zbx_uint64_t value)
113 {
114 zbx_uint64_t value_ui64;
115
116 ZBX_DBROW2UINT64(value_ui64, value_raw);
117
118 return (value_ui64 == value ? SUCCEED : FAIL);
119 }
120
121 /******************************************************************************
122 * *
123 * Function: dbsync_compare_int *
124 * *
125 * Purpose: compares 32 bit signed integer with a raw database value *
126 * *
127 ******************************************************************************/
dbsync_compare_int(const char * value_raw,int value)128 static int dbsync_compare_int(const char *value_raw, int value)
129 {
130 return (atoi(value_raw) == value ? SUCCEED : FAIL);
131 }
132
133 /******************************************************************************
134 * *
135 * Function: dbsync_compare_uchar *
136 * *
137 * Purpose: compares unsigned character with a raw database value *
138 * *
139 ******************************************************************************/
140
dbsync_compare_uchar(const char * value_raw,unsigned char value)141 static int dbsync_compare_uchar(const char *value_raw, unsigned char value)
142 {
143 unsigned char value_uchar;
144
145 ZBX_STR2UCHAR(value_uchar, value_raw);
146 return (value_uchar == value ? SUCCEED : FAIL);
147 }
148
149 /******************************************************************************
150 * *
151 * Function: dbsync_compare_str *
152 * *
153 * Purpose: compares string with a raw database value *
154 * *
155 ******************************************************************************/
156
dbsync_compare_str(const char * value_raw,const char * value)157 static int dbsync_compare_str(const char *value_raw, const char *value)
158 {
159 return (0 == strcmp(value_raw, value) ? SUCCEED : FAIL);
160 }
161
162 /******************************************************************************
163 * *
164 * Function: dbsync_add_row *
165 * *
166 * Purpose: adds a new row to the changeset *
167 * *
168 * Parameter: sync - [IN] the changeset *
169 * rowid - [IN] the row identifier *
170 * tag - [IN] the row tag (see ZBX_DBSYNC_ROW_ defines) *
171 * row - [IN] the row contents (depending on configuration cache *
172 * removal logic for the specific object it can be *
173 * NULL when used with ZBX_DBSYNC_ROW_REMOVE tag) *
174 * *
175 ******************************************************************************/
dbsync_add_row(zbx_dbsync_t * sync,zbx_uint64_t rowid,unsigned char tag,const DB_ROW dbrow)176 static void dbsync_add_row(zbx_dbsync_t *sync, zbx_uint64_t rowid, unsigned char tag, const DB_ROW dbrow)
177 {
178 int i;
179 zbx_dbsync_row_t *row;
180
181 row = (zbx_dbsync_row_t *)zbx_malloc(NULL, sizeof(zbx_dbsync_row_t));
182 row->rowid = rowid;
183 row->tag = tag;
184
185 if (NULL != dbrow)
186 {
187 row->row = (char **)zbx_malloc(NULL, sizeof(char *) * sync->columns_num);
188
189 for (i = 0; i < sync->columns_num; i++)
190 row->row[i] = (NULL == dbrow[i] ? NULL : dbsync_strdup(dbrow[i]));
191 }
192 else
193 row->row = NULL;
194
195 zbx_vector_ptr_append(&sync->rows, row);
196
197 switch (tag)
198 {
199 case ZBX_DBSYNC_ROW_ADD:
200 sync->add_num++;
201 break;
202 case ZBX_DBSYNC_ROW_UPDATE:
203 sync->update_num++;
204 break;
205 case ZBX_DBSYNC_ROW_REMOVE:
206 sync->remove_num++;
207 break;
208 }
209 }
210
211 /******************************************************************************
212 * *
213 * Function: dbsync_prepare *
214 * *
215 * Purpose: prepares changeset *
216 * *
217 * Parameter: sync - [IN] the changeset *
218 * columns_num - [IN] the number of columns in the changeset *
219 * get_hostids_func - [IN] the callback function used to retrieve *
220 * associated hostids (can be NULL if *
221 * user macros are not resolved during *
222 * synchronization process) *
223 * *
224 ******************************************************************************/
dbsync_prepare(zbx_dbsync_t * sync,int columns_num,zbx_dbsync_preproc_row_func_t preproc_row_func)225 static void dbsync_prepare(zbx_dbsync_t *sync, int columns_num, zbx_dbsync_preproc_row_func_t preproc_row_func)
226 {
227 sync->columns_num = columns_num;
228 sync->preproc_row_func = preproc_row_func;
229
230 sync->row = (char **)zbx_malloc(NULL, sizeof(char *) * columns_num);
231 memset(sync->row, 0, sizeof(char *) * columns_num);
232 }
233
234 /******************************************************************************
235 * *
236 * Function: dbsync_check_row_macros *
237 * *
238 * Purpose: checks if the specified column in the row contains user macros *
239 * *
240 * Parameter: row - [IN] the row to check *
241 * column - [IN] the column index *
242 * *
243 * Comments: While not definite, this check is used to filter out rows before *
244 * doing more precise (and resource intense) checks. *
245 * *
246 ******************************************************************************/
dbsync_check_row_macros(char ** row,int column)247 static int dbsync_check_row_macros(char **row, int column)
248 {
249 if (NULL != strstr(row[column], "{$"))
250 return SUCCEED;
251
252 return FAIL;
253 }
254
255 /******************************************************************************
256 * *
257 * Function: dbsync_preproc_row *
258 * *
259 * Purpose: applies necessary pre-processing before row is compared/used *
260 * *
261 * Parameter: sync - [IN] the changeset *
262 * row - [IN/OUT] the data row *
263 * *
264 * Return value: the resulting row *
265 * *
266 ******************************************************************************/
dbsync_preproc_row(zbx_dbsync_t * sync,char ** row)267 static char **dbsync_preproc_row(zbx_dbsync_t *sync, char **row)
268 {
269 int i;
270
271 if (NULL == sync->preproc_row_func)
272 return row;
273
274 /* free the resources allocated by last preprocessing call */
275 zbx_vector_ptr_clear_ext(&sync->columns, zbx_ptr_free);
276
277 /* copy the original data */
278 memcpy(sync->row, row, sizeof(char *) * sync->columns_num);
279
280 sync->row = sync->preproc_row_func(sync->row);
281
282 for (i = 0; i < sync->columns_num; i++)
283 {
284 if (sync->row[i] != row[i])
285 zbx_vector_ptr_append(&sync->columns, sync->row[i]);
286 }
287
288 return sync->row;
289 }
290
291 /******************************************************************************
292 * *
293 * Function: zbx_dbsync_init_env *
294 * *
295 ******************************************************************************/
zbx_dbsync_init_env(ZBX_DC_CONFIG * cache)296 void zbx_dbsync_init_env(ZBX_DC_CONFIG *cache)
297 {
298 dbsync_env.cache = cache;
299 zbx_hashset_create(&dbsync_env.strpool, 100, dbsync_strpool_hash_func, dbsync_strpool_compare_func);
300 }
301
302 /******************************************************************************
303 * *
304 * Function: dbsync_env_release *
305 * *
306 ******************************************************************************/
zbx_dbsync_free_env(void)307 void zbx_dbsync_free_env(void)
308 {
309 zbx_hashset_destroy(&dbsync_env.strpool);
310 }
311
312 /******************************************************************************
313 * *
314 * Function: zbx_dbsync_init *
315 * *
316 * Purpose: initializes changeset *
317 * *
318 ******************************************************************************/
zbx_dbsync_init(zbx_dbsync_t * sync,unsigned char mode)319 void zbx_dbsync_init(zbx_dbsync_t *sync, unsigned char mode)
320 {
321 sync->columns_num = 0;
322 sync->mode = mode;
323
324 sync->add_num = 0;
325 sync->update_num = 0;
326 sync->remove_num = 0;
327
328 sync->row = NULL;
329 sync->preproc_row_func = NULL;
330 zbx_vector_ptr_create(&sync->columns);
331
332 if (ZBX_DBSYNC_UPDATE == sync->mode)
333 {
334 zbx_vector_ptr_create(&sync->rows);
335 sync->row_index = 0;
336 }
337 else
338 sync->dbresult = NULL;
339 }
340
341 /******************************************************************************
342 * *
343 * Function: zbx_dbsync_clear *
344 * *
345 * Purpose: frees resources allocated by changeset *
346 * *
347 ******************************************************************************/
zbx_dbsync_clear(zbx_dbsync_t * sync)348 void zbx_dbsync_clear(zbx_dbsync_t *sync)
349 {
350 /* free the resources allocated by row pre-processing */
351 zbx_vector_ptr_clear_ext(&sync->columns, zbx_ptr_free);
352 zbx_vector_ptr_destroy(&sync->columns);
353
354 zbx_free(sync->row);
355
356 if (ZBX_DBSYNC_UPDATE == sync->mode)
357 {
358 int i, j;
359 zbx_dbsync_row_t *row;
360
361 for (i = 0; i < sync->rows.values_num; i++)
362 {
363 row = (zbx_dbsync_row_t *)sync->rows.values[i];
364
365 if (NULL != row->row)
366 {
367 for (j = 0; j < sync->columns_num; j++)
368 dbsync_strfree(row->row[j]);
369
370 zbx_free(row->row);
371 }
372
373 zbx_free(row);
374 }
375
376 zbx_vector_ptr_destroy(&sync->rows);
377 }
378 else
379 {
380 DBfree_result(sync->dbresult);
381 sync->dbresult = NULL;
382 }
383 }
384
385 /******************************************************************************
386 * *
387 * Function: zbx_dbsync_next *
388 * *
389 * Purpose: gets the next row from the changeset *
390 * *
391 * Parameters: sync - [IN] the changeset *
392 * rowid - [OUT] the row identifier (required for row removal, *
393 * optional for new/updated rows) *
394 * row - [OUT] the row data *
395 * tag - [OUT] the row tag, identifying changes *
396 * (see ZBX_DBSYNC_ROW_* defines) *
397 * *
398 * Return value: SUCCEED - the next row was successfully retrieved *
399 * FAIL - no more data to retrieve *
400 * *
401 ******************************************************************************/
zbx_dbsync_next(zbx_dbsync_t * sync,zbx_uint64_t * rowid,char *** row,unsigned char * tag)402 int zbx_dbsync_next(zbx_dbsync_t *sync, zbx_uint64_t *rowid, char ***row, unsigned char *tag)
403 {
404 if (ZBX_DBSYNC_UPDATE == sync->mode)
405 {
406 zbx_dbsync_row_t *sync_row;
407
408 if (sync->row_index == sync->rows.values_num)
409 return FAIL;
410
411 sync_row = (zbx_dbsync_row_t *)sync->rows.values[sync->row_index++];
412 *rowid = sync_row->rowid;
413 *row = sync_row->row;
414 *tag = sync_row->tag;
415 }
416 else
417 {
418 char **dbrow;
419
420 if (NULL == (dbrow = DBfetch(sync->dbresult)))
421 {
422 *row = NULL;
423 return FAIL;
424 }
425
426 *row = dbsync_preproc_row(sync, dbrow);
427
428 *rowid = 0;
429 *tag = ZBX_DBSYNC_ROW_ADD;
430
431 sync->add_num++;
432 }
433
434 return SUCCEED;
435 }
436
437 /******************************************************************************
438 * *
439 * Function: zbx_dbsync_compare_config *
440 * *
441 * Purpose: compares config table with cached configuration data *
442 * *
443 * Parameter: cache - [IN] the configuration cache *
444 * sync - [OUT] the changeset *
445 * *
446 * Return value: SUCCEED - the changeset was successfully calculated *
447 * FAIL - otherwise *
448 * *
449 ******************************************************************************/
zbx_dbsync_compare_config(zbx_dbsync_t * sync)450 int zbx_dbsync_compare_config(zbx_dbsync_t *sync)
451 {
452 DB_RESULT result;
453
454 if (NULL == (result = DBselect("select refresh_unsupported,discovery_groupid,snmptrap_logging,"
455 "severity_name_0,severity_name_1,severity_name_2,"
456 "severity_name_3,severity_name_4,severity_name_5,"
457 "hk_events_mode,hk_events_trigger,hk_events_internal,"
458 "hk_events_discovery,hk_events_autoreg,hk_services_mode,"
459 "hk_services,hk_audit_mode,hk_audit,hk_sessions_mode,hk_sessions,"
460 "hk_history_mode,hk_history_global,hk_history,hk_trends_mode,"
461 "hk_trends_global,hk_trends,default_inventory_mode"
462 " from config"
463 " order by configid")))
464 {
465 return FAIL;
466 }
467
468 dbsync_prepare(sync, 27, NULL);
469
470 if (ZBX_DBSYNC_INIT == sync->mode)
471 {
472 sync->dbresult = result;
473 return SUCCEED;
474 }
475
476 DBfree_result(result);
477
478 /* global configuration will be always synchronized directly with database */
479 THIS_SHOULD_NEVER_HAPPEN;
480
481 return FAIL;
482 }
483
484 /******************************************************************************
485 * *
486 * Function: dbsync_compare_host *
487 * *
488 * Purpose: compares hosts table row with cached configuration data *
489 * *
490 * Parameter: cache - [IN] the configuration cache *
491 * host - [IN] the cached host *
492 * row - [IN] the database row *
493 * *
494 * Return value: SUCCEED - the row matches configuration data *
495 * FAIL - otherwise *
496 * *
497 ******************************************************************************/
dbsync_compare_host(ZBX_DC_HOST * host,const DB_ROW dbrow)498 static int dbsync_compare_host(ZBX_DC_HOST *host, const DB_ROW dbrow)
499 {
500 signed char ipmi_authtype;
501 unsigned char ipmi_privilege;
502 ZBX_DC_IPMIHOST *ipmihost;
503 ZBX_DC_PROXY *proxy;
504
505 if (FAIL == dbsync_compare_uint64(dbrow[1], host->proxy_hostid))
506 {
507 host->update_items = 1;
508 return FAIL;
509 }
510
511 if (FAIL == dbsync_compare_uchar(dbrow[22], host->status))
512 {
513 host->update_items = 1;
514 return FAIL;
515 }
516
517 host->update_items = 0;
518
519 if (FAIL == dbsync_compare_str(dbrow[2], host->host))
520 return FAIL;
521
522 if (FAIL == dbsync_compare_str(dbrow[23], host->name))
523 return FAIL;
524
525 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
526 if (FAIL == dbsync_compare_str(dbrow[31], host->tls_issuer))
527 return FAIL;
528
529 if (FAIL == dbsync_compare_str(dbrow[32], host->tls_subject))
530 return FAIL;
531
532 if ('\0' == *dbrow[33] || '\0' == *dbrow[34])
533 {
534 if (NULL != host->tls_dc_psk)
535 return FAIL;
536 }
537 else
538 {
539 if (NULL == host->tls_dc_psk)
540 return FAIL;
541
542 if (FAIL == dbsync_compare_str(dbrow[33], host->tls_dc_psk->tls_psk_identity))
543 return FAIL;
544
545 if (FAIL == dbsync_compare_str(dbrow[34], host->tls_dc_psk->tls_psk))
546 return FAIL;
547 }
548
549 #endif
550 if (FAIL == dbsync_compare_uchar(dbrow[29], host->tls_connect))
551 return FAIL;
552
553 if (FAIL == dbsync_compare_uchar(dbrow[30], host->tls_accept))
554 return FAIL;
555
556 /* IPMI hosts */
557
558 ipmi_authtype = (signed char)atoi(dbrow[3]);
559 ipmi_privilege = (unsigned char)atoi(dbrow[4]);
560
561 if (ZBX_IPMI_DEFAULT_AUTHTYPE != ipmi_authtype || ZBX_IPMI_DEFAULT_PRIVILEGE != ipmi_privilege ||
562 '\0' != *dbrow[5] || '\0' != *dbrow[6]) /* useipmi */
563 {
564 if (NULL == (ipmihost = (ZBX_DC_IPMIHOST *)zbx_hashset_search(&dbsync_env.cache->ipmihosts,
565 &host->hostid)))
566 {
567 return FAIL;
568 }
569
570 if (ipmihost->ipmi_authtype != ipmi_authtype)
571 return FAIL;
572
573 if (ipmihost->ipmi_privilege != ipmi_privilege)
574 return FAIL;
575
576 if (FAIL == dbsync_compare_str(dbrow[5], ipmihost->ipmi_username))
577 return FAIL;
578
579 if (FAIL == dbsync_compare_str(dbrow[6], ipmihost->ipmi_password))
580 return FAIL;
581 }
582 else if (NULL != zbx_hashset_search(&dbsync_env.cache->ipmihosts, &host->hostid))
583 return FAIL;
584
585 /* proxies */
586 if (NULL != (proxy = (ZBX_DC_PROXY *)zbx_hashset_search(&dbsync_env.cache->proxies, &host->hostid)))
587 {
588 if (FAIL == dbsync_compare_str(dbrow[31 + ZBX_HOST_TLS_OFFSET], proxy->proxy_address))
589 return FAIL;
590
591 if (FAIL == dbsync_compare_uchar(dbrow[32 + ZBX_HOST_TLS_OFFSET], proxy->auto_compress))
592 return FAIL;
593 }
594
595 return SUCCEED;
596 }
597
598 /******************************************************************************
599 * *
600 * Function: zbx_dbsync_compare_hosts *
601 * *
602 * Purpose: compares hosts table with cached configuration data *
603 * *
604 * Parameter: cache - [IN] the configuration cache *
605 * sync - [OUT] the changeset *
606 * *
607 * Return value: SUCCEED - the changeset was successfully calculated *
608 * FAIL - otherwise *
609 * *
610 ******************************************************************************/
zbx_dbsync_compare_hosts(zbx_dbsync_t * sync)611 int zbx_dbsync_compare_hosts(zbx_dbsync_t *sync)
612 {
613 DB_ROW dbrow;
614 DB_RESULT result;
615 zbx_hashset_t ids;
616 zbx_hashset_iter_t iter;
617 zbx_uint64_t rowid;
618 ZBX_DC_HOST *host;
619
620 #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
621 if (NULL == (result = DBselect(
622 "select hostid,proxy_hostid,host,ipmi_authtype,ipmi_privilege,ipmi_username,"
623 "ipmi_password,maintenance_status,maintenance_type,maintenance_from,"
624 "errors_from,available,disable_until,snmp_errors_from,"
625 "snmp_available,snmp_disable_until,ipmi_errors_from,ipmi_available,"
626 "ipmi_disable_until,jmx_errors_from,jmx_available,jmx_disable_until,"
627 "status,name,lastaccess,error,snmp_error,ipmi_error,jmx_error,tls_connect,tls_accept"
628 ",tls_issuer,tls_subject,tls_psk_identity,tls_psk,proxy_address,auto_compress,"
629 "maintenanceid"
630 " from hosts"
631 " where status in (%d,%d,%d,%d)"
632 " and flags<>%d",
633 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
634 HOST_STATUS_PROXY_ACTIVE, HOST_STATUS_PROXY_PASSIVE,
635 ZBX_FLAG_DISCOVERY_PROTOTYPE)))
636 {
637 return FAIL;
638 }
639
640 dbsync_prepare(sync, 38, NULL);
641 #else
642 if (NULL == (result = DBselect(
643 "select hostid,proxy_hostid,host,ipmi_authtype,ipmi_privilege,ipmi_username,"
644 "ipmi_password,maintenance_status,maintenance_type,maintenance_from,"
645 "errors_from,available,disable_until,snmp_errors_from,"
646 "snmp_available,snmp_disable_until,ipmi_errors_from,ipmi_available,"
647 "ipmi_disable_until,jmx_errors_from,jmx_available,jmx_disable_until,"
648 "status,name,lastaccess,error,snmp_error,ipmi_error,jmx_error,tls_connect,tls_accept,"
649 "proxy_address,auto_compress,maintenanceid"
650 " from hosts"
651 " where status in (%d,%d,%d,%d)"
652 " and flags<>%d",
653 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
654 HOST_STATUS_PROXY_ACTIVE, HOST_STATUS_PROXY_PASSIVE,
655 ZBX_FLAG_DISCOVERY_PROTOTYPE)))
656 {
657 return FAIL;
658 }
659
660 dbsync_prepare(sync, 34, NULL);
661 #endif
662
663 if (ZBX_DBSYNC_INIT == sync->mode)
664 {
665 sync->dbresult = result;
666 return SUCCEED;
667 }
668
669 zbx_hashset_create(&ids, dbsync_env.cache->hosts.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
670 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
671
672 while (NULL != (dbrow = DBfetch(result)))
673 {
674 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
675
676 ZBX_STR2UINT64(rowid, dbrow[0]);
677 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
678
679 if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&dbsync_env.cache->hosts, &rowid)))
680 tag = ZBX_DBSYNC_ROW_ADD;
681 else if (FAIL == dbsync_compare_host(host, dbrow))
682 tag = ZBX_DBSYNC_ROW_UPDATE;
683
684 if (ZBX_DBSYNC_ROW_NONE != tag)
685 dbsync_add_row(sync, rowid, tag, dbrow);
686 }
687
688 zbx_hashset_iter_reset(&dbsync_env.cache->hosts, &iter);
689 while (NULL != (host = (ZBX_DC_HOST *)zbx_hashset_iter_next(&iter)))
690 {
691 if (NULL == zbx_hashset_search(&ids, &host->hostid))
692 dbsync_add_row(sync, host->hostid, ZBX_DBSYNC_ROW_REMOVE, NULL);
693 }
694
695 zbx_hashset_destroy(&ids);
696 DBfree_result(result);
697
698 return SUCCEED;
699 }
700
701 /******************************************************************************
702 * *
703 * Function: dbsync_compare_host_inventory *
704 * *
705 * Purpose: compares host inventory table row with cached configuration data *
706 * *
707 * Parameter: hi - [IN] the cached host inventory data *
708 * row - [IN] the database row *
709 * *
710 * Return value: SUCCEED - the row matches configuration data *
711 * FAIL - otherwise *
712 * *
713 ******************************************************************************/
dbsync_compare_host_inventory(const ZBX_DC_HOST_INVENTORY * hi,const DB_ROW dbrow)714 static int dbsync_compare_host_inventory(const ZBX_DC_HOST_INVENTORY *hi, const DB_ROW dbrow)
715 {
716 int i;
717
718 if (SUCCEED != dbsync_compare_uchar(dbrow[1], hi->inventory_mode))
719 return FAIL;
720
721 for (i = 0; i < HOST_INVENTORY_FIELD_COUNT; i++)
722 {
723 if (FAIL == dbsync_compare_str(dbrow[i + 2], hi->values[i]))
724 return FAIL;
725 }
726
727 return SUCCEED;
728 }
729
730 /******************************************************************************
731 * *
732 * Function: zbx_dbsync_compare_host_inventory *
733 * *
734 * Purpose: compares host_inventory table with cached configuration data *
735 * *
736 * Parameter: cache - [IN] the configuration cache *
737 * sync - [OUT] the changeset *
738 * *
739 * Return value: SUCCEED - the changeset was successfully calculated *
740 * FAIL - otherwise *
741 * *
742 ******************************************************************************/
zbx_dbsync_compare_host_inventory(zbx_dbsync_t * sync)743 int zbx_dbsync_compare_host_inventory(zbx_dbsync_t *sync)
744 {
745 DB_ROW dbrow;
746 DB_RESULT result;
747 zbx_hashset_t ids;
748 zbx_hashset_iter_t iter;
749 zbx_uint64_t rowid;
750 ZBX_DC_HOST_INVENTORY *hi;
751 const char *sql;
752
753 sql = "select hostid,inventory_mode,type,type_full,name,alias,os,os_full,os_short,serialno_a,"
754 "serialno_b,tag,asset_tag,macaddress_a,macaddress_b,hardware,hardware_full,software,"
755 "software_full,software_app_a,software_app_b,software_app_c,software_app_d,"
756 "software_app_e,contact,location,location_lat,location_lon,notes,chassis,model,"
757 "hw_arch,vendor,contract_number,installer_name,deployment_status,url_a,url_b,"
758 "url_c,host_networks,host_netmask,host_router,oob_ip,oob_netmask,oob_router,"
759 "date_hw_purchase,date_hw_install,date_hw_expiry,date_hw_decomm,site_address_a,"
760 "site_address_b,site_address_c,site_city,site_state,site_country,site_zip,site_rack,"
761 "site_notes,poc_1_name,poc_1_email,poc_1_phone_a,poc_1_phone_b,poc_1_cell,"
762 "poc_1_screen,poc_1_notes,poc_2_name,poc_2_email,poc_2_phone_a,poc_2_phone_b,"
763 "poc_2_cell,poc_2_screen,poc_2_notes"
764 " from host_inventory";
765
766 if (NULL == (result = DBselect("%s", sql)))
767 return FAIL;
768
769 dbsync_prepare(sync, 72, NULL);
770
771 if (ZBX_DBSYNC_INIT == sync->mode)
772 {
773 sync->dbresult = result;
774 return SUCCEED;
775 }
776
777 zbx_hashset_create(&ids, dbsync_env.cache->host_inventories.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
778 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
779
780 while (NULL != (dbrow = DBfetch(result)))
781 {
782 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
783
784 ZBX_STR2UINT64(rowid, dbrow[0]);
785 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
786
787 if (NULL == (hi = (ZBX_DC_HOST_INVENTORY *)zbx_hashset_search(&dbsync_env.cache->host_inventories,
788 &rowid)))
789 {
790 tag = ZBX_DBSYNC_ROW_ADD;
791 }
792 else if (FAIL == dbsync_compare_host_inventory(hi, dbrow))
793 tag = ZBX_DBSYNC_ROW_UPDATE;
794
795 if (ZBX_DBSYNC_ROW_NONE != tag)
796 dbsync_add_row(sync, rowid, tag, dbrow);
797
798 }
799
800 zbx_hashset_iter_reset(&dbsync_env.cache->host_inventories, &iter);
801 while (NULL != (hi = (ZBX_DC_HOST_INVENTORY *)zbx_hashset_iter_next(&iter)))
802 {
803 if (NULL == zbx_hashset_search(&ids, &hi->hostid))
804 dbsync_add_row(sync, hi->hostid, ZBX_DBSYNC_ROW_REMOVE, NULL);
805 }
806
807 zbx_hashset_destroy(&ids);
808 DBfree_result(result);
809
810 return SUCCEED;
811 }
812
813 /******************************************************************************
814 * *
815 * Function: zbx_dbsync_compare_host_templates *
816 * *
817 * Purpose: compares hosts_templates table with cached configuration data *
818 * *
819 * Parameter: cache - [IN] the configuration cache *
820 * sync - [OUT] the changeset *
821 * *
822 * Return value: SUCCEED - the changeset was successfully calculated *
823 * FAIL - otherwise *
824 * *
825 ******************************************************************************/
zbx_dbsync_compare_host_templates(zbx_dbsync_t * sync)826 int zbx_dbsync_compare_host_templates(zbx_dbsync_t *sync)
827 {
828 DB_ROW dbrow;
829 DB_RESULT result;
830 zbx_hashset_iter_t iter;
831 ZBX_DC_HTMPL *htmpl;
832 zbx_hashset_t htmpls;
833 int i;
834 zbx_uint64_pair_t ht_local, *ht;
835 char hostid_s[MAX_ID_LEN + 1], templateid_s[MAX_ID_LEN + 1];
836 char *del_row[2] = {hostid_s, templateid_s};
837
838 if (NULL == (result = DBselect(
839 "select hostid,templateid"
840 " from hosts_templates"
841 " order by hostid")))
842 {
843 return FAIL;
844 }
845
846 dbsync_prepare(sync, 2, NULL);
847
848 if (ZBX_DBSYNC_INIT == sync->mode)
849 {
850 sync->dbresult = result;
851 return SUCCEED;
852 }
853
854 zbx_hashset_create(&htmpls, 100, ZBX_DEFAULT_UINT64_PAIR_HASH_FUNC, ZBX_DEFAULT_UINT64_PAIR_COMPARE_FUNC);
855
856 /* index all host->template links */
857 zbx_hashset_iter_reset(&dbsync_env.cache->htmpls, &iter);
858 while (NULL != (htmpl = (ZBX_DC_HTMPL *)zbx_hashset_iter_next(&iter)))
859 {
860 ht_local.first = htmpl->hostid;
861
862 for (i = 0; i < htmpl->templateids.values_num; i++)
863 {
864 ht_local.second = htmpl->templateids.values[i];
865 zbx_hashset_insert(&htmpls, &ht_local, sizeof(ht_local));
866 }
867 }
868
869 /* add new rows, remove existing rows from index */
870 while (NULL != (dbrow = DBfetch(result)))
871 {
872 ZBX_STR2UINT64(ht_local.first, dbrow[0]);
873 ZBX_STR2UINT64(ht_local.second, dbrow[1]);
874
875 if (NULL == (ht = (zbx_uint64_pair_t *)zbx_hashset_search(&htmpls, &ht_local)))
876 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_ADD, dbrow);
877 else
878 zbx_hashset_remove_direct(&htmpls, ht);
879 }
880
881 /* add removed rows */
882 zbx_hashset_iter_reset(&htmpls, &iter);
883 while (NULL != (ht = (zbx_uint64_pair_t *)zbx_hashset_iter_next(&iter)))
884 {
885 zbx_snprintf(hostid_s, sizeof(hostid_s), ZBX_FS_UI64, ht->first);
886 zbx_snprintf(templateid_s, sizeof(templateid_s), ZBX_FS_UI64, ht->second);
887 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_REMOVE, del_row);
888 }
889
890 DBfree_result(result);
891 zbx_hashset_destroy(&htmpls);
892
893 return SUCCEED;
894 }
895
896 /******************************************************************************
897 * *
898 * Function: dbsync_compare_global_macro *
899 * *
900 * Purpose: compares global macro table row with cached configuration data *
901 * *
902 * Parameter: gmacro - [IN] the cached global macro data *
903 * row - [IN] the database row *
904 * *
905 * Return value: SUCCEED - the row matches configuration data *
906 * FAIL - otherwise *
907 * *
908 ******************************************************************************/
dbsync_compare_global_macro(const ZBX_DC_GMACRO * gmacro,const DB_ROW dbrow)909 static int dbsync_compare_global_macro(const ZBX_DC_GMACRO *gmacro, const DB_ROW dbrow)
910 {
911 char *macro = NULL, *context = NULL;
912 int ret = FAIL;
913
914 if (FAIL == dbsync_compare_str(dbrow[2], gmacro->value))
915 return FAIL;
916
917 if (SUCCEED != zbx_user_macro_parse_dyn(dbrow[1], ¯o, &context, NULL))
918 return FAIL;
919
920 if (0 != strcmp(gmacro->macro, macro))
921 goto out;
922
923 if (NULL == context)
924 {
925 if (NULL != gmacro->context)
926 goto out;
927
928 ret = SUCCEED;
929 goto out;
930 }
931
932 if (NULL == gmacro->context)
933 goto out;
934
935 if (0 == strcmp(gmacro->context, context))
936 ret = SUCCEED;
937 out:
938 zbx_free(macro);
939 zbx_free(context);
940
941 return ret;
942 }
943
944 /******************************************************************************
945 * *
946 * Function: zbx_dbsync_compare_global_macros *
947 * *
948 * Purpose: compares global macros table with cached configuration data *
949 * *
950 * Parameter: cache - [IN] the configuration cache *
951 * sync - [OUT] the changeset *
952 * *
953 * Return value: SUCCEED - the changeset was successfully calculated *
954 * FAIL - otherwise *
955 * *
956 ******************************************************************************/
zbx_dbsync_compare_global_macros(zbx_dbsync_t * sync)957 int zbx_dbsync_compare_global_macros(zbx_dbsync_t *sync)
958 {
959 DB_ROW dbrow;
960 DB_RESULT result;
961 zbx_hashset_t ids;
962 zbx_hashset_iter_t iter;
963 zbx_uint64_t rowid;
964 ZBX_DC_GMACRO *macro;
965
966 if (NULL == (result = DBselect(
967 "select globalmacroid,macro,value"
968 " from globalmacro")))
969 {
970 return FAIL;
971 }
972
973 dbsync_prepare(sync, 3, NULL);
974
975 if (ZBX_DBSYNC_INIT == sync->mode)
976 {
977 sync->dbresult = result;
978 return SUCCEED;
979 }
980
981 zbx_hashset_create(&ids, dbsync_env.cache->gmacros.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
982 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
983
984 while (NULL != (dbrow = DBfetch(result)))
985 {
986 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
987
988 ZBX_STR2UINT64(rowid, dbrow[0]);
989 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
990
991 if (NULL == (macro = (ZBX_DC_GMACRO *)zbx_hashset_search(&dbsync_env.cache->gmacros, &rowid)))
992 tag = ZBX_DBSYNC_ROW_ADD;
993 else if (FAIL == dbsync_compare_global_macro(macro, dbrow))
994 tag = ZBX_DBSYNC_ROW_UPDATE;
995
996 if (ZBX_DBSYNC_ROW_NONE != tag)
997 dbsync_add_row(sync, rowid, tag, dbrow);
998 }
999
1000 zbx_hashset_iter_reset(&dbsync_env.cache->gmacros, &iter);
1001 while (NULL != (macro = (ZBX_DC_GMACRO *)zbx_hashset_iter_next(&iter)))
1002 {
1003 if (NULL == zbx_hashset_search(&ids, ¯o->globalmacroid))
1004 dbsync_add_row(sync, macro->globalmacroid, ZBX_DBSYNC_ROW_REMOVE, NULL);
1005 }
1006
1007 zbx_hashset_destroy(&ids);
1008 DBfree_result(result);
1009
1010 return SUCCEED;
1011 }
1012
1013 /******************************************************************************
1014 * *
1015 * Function: dbsync_compare_host_macro *
1016 * *
1017 * Purpose: compares host macro table row with cached configuration data *
1018 * *
1019 * Parameter: hmacro - [IN] the cached host macro data *
1020 * row - [IN] the database row *
1021 * *
1022 * Return value: SUCCEED - the row matches configuration data *
1023 * FAIL - otherwise *
1024 * *
1025 ******************************************************************************/
dbsync_compare_host_macro(const ZBX_DC_HMACRO * hmacro,const DB_ROW dbrow)1026 static int dbsync_compare_host_macro(const ZBX_DC_HMACRO *hmacro, const DB_ROW dbrow)
1027 {
1028 char *macro = NULL, *context = NULL;
1029 int ret = FAIL;
1030
1031 if (FAIL == dbsync_compare_str(dbrow[3], hmacro->value))
1032 return FAIL;
1033
1034 if (FAIL == dbsync_compare_uint64(dbrow[1], hmacro->hostid))
1035 return FAIL;
1036
1037 if (SUCCEED != zbx_user_macro_parse_dyn(dbrow[2], ¯o, &context, NULL))
1038 return FAIL;
1039
1040 if (0 != strcmp(hmacro->macro, macro))
1041 goto out;
1042
1043 if (NULL == context)
1044 {
1045 if (NULL != hmacro->context)
1046 goto out;
1047
1048 ret = SUCCEED;
1049 goto out;
1050 }
1051
1052 if (NULL == hmacro->context)
1053 goto out;
1054
1055 if (0 == strcmp(hmacro->context, context))
1056 ret = SUCCEED;
1057 out:
1058 zbx_free(macro);
1059 zbx_free(context);
1060
1061 return ret;
1062 }
1063
1064 /******************************************************************************
1065 * *
1066 * Function: zbx_dbsync_compare_host_macros *
1067 * *
1068 * Purpose: compares global macros table with cached configuration data *
1069 * *
1070 * Parameter: cache - [IN] the configuration cache *
1071 * sync - [OUT] the changeset *
1072 * *
1073 * Return value: SUCCEED - the changeset was successfully calculated *
1074 * FAIL - otherwise *
1075 * *
1076 ******************************************************************************/
zbx_dbsync_compare_host_macros(zbx_dbsync_t * sync)1077 int zbx_dbsync_compare_host_macros(zbx_dbsync_t *sync)
1078 {
1079 DB_ROW dbrow;
1080 DB_RESULT result;
1081 zbx_hashset_t ids;
1082 zbx_hashset_iter_t iter;
1083 zbx_uint64_t rowid;
1084 ZBX_DC_HMACRO *macro;
1085
1086 if (NULL == (result = DBselect(
1087 "select hostmacroid,hostid,macro,value"
1088 " from hostmacro")))
1089 {
1090 return FAIL;
1091 }
1092
1093 dbsync_prepare(sync, 4, NULL);
1094
1095 if (ZBX_DBSYNC_INIT == sync->mode)
1096 {
1097 sync->dbresult = result;
1098 return SUCCEED;
1099 }
1100
1101 zbx_hashset_create(&ids, dbsync_env.cache->hmacros.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
1102 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
1103
1104 while (NULL != (dbrow = DBfetch(result)))
1105 {
1106 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
1107
1108 ZBX_STR2UINT64(rowid, dbrow[0]);
1109 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
1110
1111 if (NULL == (macro = (ZBX_DC_HMACRO *)zbx_hashset_search(&dbsync_env.cache->hmacros, &rowid)))
1112 tag = ZBX_DBSYNC_ROW_ADD;
1113 else if (FAIL == dbsync_compare_host_macro(macro, dbrow))
1114 tag = ZBX_DBSYNC_ROW_UPDATE;
1115
1116 if (ZBX_DBSYNC_ROW_NONE != tag)
1117 dbsync_add_row(sync, rowid, tag, dbrow);
1118 }
1119
1120 zbx_hashset_iter_reset(&dbsync_env.cache->hmacros, &iter);
1121 while (NULL != (macro = (ZBX_DC_HMACRO *)zbx_hashset_iter_next(&iter)))
1122 {
1123 if (NULL == zbx_hashset_search(&ids, ¯o->hostmacroid))
1124 dbsync_add_row(sync, macro->hostmacroid, ZBX_DBSYNC_ROW_REMOVE, NULL);
1125 }
1126
1127 zbx_hashset_destroy(&ids);
1128 DBfree_result(result);
1129
1130 return SUCCEED;
1131 }
1132
1133 /******************************************************************************
1134 * *
1135 * Function: dbsync_compare_interface *
1136 * *
1137 * Purpose: compares interface table row with cached configuration data *
1138 * *
1139 * Parameter: interface - [IN] the cached interface data *
1140 * row - [IN] the database row *
1141 * *
1142 * Return value: SUCCEED - the row matches configuration data *
1143 * FAIL - otherwise *
1144 * *
1145 * Comments: User macros used in ip, dns fields will always make compare to *
1146 * fail. *
1147 * *
1148 ******************************************************************************/
dbsync_compare_interface(const ZBX_DC_INTERFACE * interface,const DB_ROW dbrow)1149 static int dbsync_compare_interface(const ZBX_DC_INTERFACE *interface, const DB_ROW dbrow)
1150 {
1151 if (FAIL == dbsync_compare_uint64(dbrow[1], interface->hostid))
1152 return FAIL;
1153
1154 if (FAIL == dbsync_compare_uchar(dbrow[2], interface->type))
1155 return FAIL;
1156
1157 if (FAIL == dbsync_compare_uchar(dbrow[3], interface->main))
1158 return FAIL;
1159
1160 if (FAIL == dbsync_compare_uchar(dbrow[4], interface->useip))
1161 return FAIL;
1162
1163 if (FAIL == dbsync_compare_uchar(dbrow[8], interface->bulk))
1164 return FAIL;
1165
1166 if (NULL != strstr(dbrow[5], "{$"))
1167 return FAIL;
1168
1169 if (FAIL == dbsync_compare_str(dbrow[5], interface->ip))
1170 return FAIL;
1171
1172 if (NULL != strstr(dbrow[6], "{$"))
1173 return FAIL;
1174
1175 if (FAIL == dbsync_compare_str(dbrow[6], interface->dns))
1176 return FAIL;
1177
1178 if (FAIL == dbsync_compare_str(dbrow[7], interface->port))
1179 return FAIL;
1180
1181 return SUCCEED;
1182 }
1183
1184 /******************************************************************************
1185 * *
1186 * Function: zbx_dbsync_compare_interfaces *
1187 * *
1188 * Purpose: compares interfaces table with cached configuration data *
1189 * *
1190 * Parameter: cache - [IN] the configuration cache *
1191 * sync - [OUT] the changeset *
1192 * *
1193 * Return value: SUCCEED - the changeset was successfully calculated *
1194 * FAIL - otherwise *
1195 * *
1196 ******************************************************************************/
zbx_dbsync_compare_interfaces(zbx_dbsync_t * sync)1197 int zbx_dbsync_compare_interfaces(zbx_dbsync_t *sync)
1198 {
1199 DB_ROW dbrow;
1200 DB_RESULT result;
1201 zbx_hashset_t ids;
1202 zbx_hashset_iter_t iter;
1203 zbx_uint64_t rowid;
1204 ZBX_DC_INTERFACE *interface;
1205
1206 if (NULL == (result = DBselect(
1207 "select interfaceid,hostid,type,main,useip,ip,dns,port,bulk"
1208 " from interface")))
1209 {
1210 return FAIL;
1211 }
1212
1213 dbsync_prepare(sync, 9, NULL);
1214
1215 if (ZBX_DBSYNC_INIT == sync->mode)
1216 {
1217 sync->dbresult = result;
1218 return SUCCEED;
1219 }
1220
1221 zbx_hashset_create(&ids, dbsync_env.cache->interfaces.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
1222 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
1223
1224 while (NULL != (dbrow = DBfetch(result)))
1225 {
1226 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
1227
1228 ZBX_STR2UINT64(rowid, dbrow[0]);
1229 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
1230
1231 if (NULL == (interface = (ZBX_DC_INTERFACE *)zbx_hashset_search(&dbsync_env.cache->interfaces, &rowid)))
1232 tag = ZBX_DBSYNC_ROW_ADD;
1233 else if (FAIL == dbsync_compare_interface(interface, dbrow))
1234 tag = ZBX_DBSYNC_ROW_UPDATE;
1235
1236 if (ZBX_DBSYNC_ROW_NONE != tag)
1237 dbsync_add_row(sync, rowid, tag, dbrow);
1238 }
1239
1240 zbx_hashset_iter_reset(&dbsync_env.cache->interfaces, &iter);
1241 while (NULL != (interface = (ZBX_DC_INTERFACE *)zbx_hashset_iter_next(&iter)))
1242 {
1243 if (NULL == zbx_hashset_search(&ids, &interface->interfaceid))
1244 dbsync_add_row(sync, interface->interfaceid, ZBX_DBSYNC_ROW_REMOVE, NULL);
1245 }
1246
1247 zbx_hashset_destroy(&ids);
1248 DBfree_result(result);
1249
1250 return SUCCEED;
1251 }
1252
1253 /******************************************************************************
1254 * *
1255 * Function: dbsync_compare_item *
1256 * *
1257 * Purpose: compares items table row with cached configuration data *
1258 * *
1259 * Parameter: cache - [IN] the configuration cache *
1260 * item - [IN] the cached item *
1261 * row - [IN] the database row *
1262 * *
1263 * Return value: SUCCEED - the row matches configuration data *
1264 * FAIL - otherwise *
1265 * *
1266 ******************************************************************************/
dbsync_compare_item(const ZBX_DC_ITEM * item,const DB_ROW dbrow)1267 static int dbsync_compare_item(const ZBX_DC_ITEM *item, const DB_ROW dbrow)
1268 {
1269 ZBX_DC_NUMITEM *numitem;
1270 ZBX_DC_SNMPITEM *snmpitem;
1271 ZBX_DC_IPMIITEM *ipmiitem;
1272 ZBX_DC_TRAPITEM *trapitem;
1273 ZBX_DC_LOGITEM *logitem;
1274 ZBX_DC_DBITEM *dbitem;
1275 ZBX_DC_SSHITEM *sshitem;
1276 ZBX_DC_TELNETITEM *telnetitem;
1277 ZBX_DC_SIMPLEITEM *simpleitem;
1278 ZBX_DC_JMXITEM *jmxitem;
1279 ZBX_DC_CALCITEM *calcitem;
1280 ZBX_DC_DEPENDENTITEM *depitem;
1281 ZBX_DC_HOST *host;
1282 ZBX_DC_HTTPITEM *httpitem;
1283 unsigned char value_type, type;
1284 int history_sec, trends_sec;
1285
1286 if (FAIL == dbsync_compare_uint64(dbrow[1], item->hostid))
1287 return FAIL;
1288
1289 if (NULL == (host = (ZBX_DC_HOST *)zbx_hashset_search(&dbsync_env.cache->hosts, &item->hostid)))
1290 return FAIL;
1291
1292 if (0 != host->update_items)
1293 return FAIL;
1294
1295 if (FAIL == dbsync_compare_uchar(dbrow[2], item->status))
1296 return FAIL;
1297
1298 ZBX_STR2UCHAR(type, dbrow[3]);
1299 if (item->type != type)
1300 return FAIL;
1301
1302 if (FAIL == dbsync_compare_str(dbrow[8], item->port))
1303 return FAIL;
1304
1305 if (FAIL == dbsync_compare_uchar(dbrow[24], item->flags))
1306 return FAIL;
1307
1308 if (FAIL == dbsync_compare_uint64(dbrow[25], item->interfaceid))
1309 return FAIL;
1310
1311 if (SUCCEED != is_time_suffix(dbrow[31], &history_sec, ZBX_LENGTH_UNLIMITED))
1312 history_sec = ZBX_HK_PERIOD_MAX;
1313
1314 if (0 != history_sec && ZBX_HK_OPTION_ENABLED == dbsync_env.cache->config->hk.history_global)
1315 history_sec = dbsync_env.cache->config->hk.history;
1316
1317 if (item->history != (0 != history_sec))
1318 return FAIL;
1319
1320 if (history_sec != item->history_sec)
1321 return FAIL;
1322
1323 if (FAIL == dbsync_compare_uchar(dbrow[33], item->inventory_link))
1324 return FAIL;
1325
1326 if (FAIL == dbsync_compare_uint64(dbrow[34], item->valuemapid))
1327 return FAIL;
1328
1329 ZBX_STR2UCHAR(value_type, dbrow[4]);
1330 if (item->value_type != value_type)
1331 return FAIL;
1332
1333 if (FAIL == dbsync_compare_str(dbrow[5], item->key))
1334 return FAIL;
1335
1336 if (FAIL == dbsync_compare_str(dbrow[14], item->delay))
1337 return FAIL;
1338
1339 numitem = (ZBX_DC_NUMITEM *)zbx_hashset_search(&dbsync_env.cache->numitems, &item->itemid);
1340 if (ITEM_VALUE_TYPE_FLOAT == value_type || ITEM_VALUE_TYPE_UINT64 == value_type)
1341 {
1342 if (NULL == numitem)
1343 return FAIL;
1344
1345 if (SUCCEED != is_time_suffix(dbrow[32], &trends_sec, ZBX_LENGTH_UNLIMITED))
1346 trends_sec = ZBX_HK_PERIOD_MAX;
1347
1348 if (0 != trends_sec && ZBX_HK_OPTION_ENABLED == dbsync_env.cache->config->hk.trends_global)
1349 trends_sec = dbsync_env.cache->config->hk.trends;
1350
1351 if (numitem->trends != (0 != trends_sec))
1352 return FAIL;
1353
1354 if (numitem->trends_sec != trends_sec)
1355 return FAIL;
1356
1357 if (FAIL == dbsync_compare_str(dbrow[35], numitem->units))
1358 return FAIL;
1359 }
1360 else if (NULL != numitem)
1361 return FAIL;
1362
1363 snmpitem = (ZBX_DC_SNMPITEM *)zbx_hashset_search(&dbsync_env.cache->snmpitems, &item->itemid);
1364 if (SUCCEED == is_snmp_type(type))
1365 {
1366 if (NULL == snmpitem)
1367 return FAIL;
1368
1369 if (FAIL == dbsync_compare_str(dbrow[6], snmpitem->snmp_community))
1370 return FAIL;
1371
1372 if (FAIL == dbsync_compare_str(dbrow[9], snmpitem->snmpv3_securityname))
1373 return FAIL;
1374
1375 if (FAIL == dbsync_compare_uchar(dbrow[10], snmpitem->snmpv3_securitylevel))
1376 return FAIL;
1377
1378 if (FAIL == dbsync_compare_str(dbrow[11], snmpitem->snmpv3_authpassphrase))
1379 return FAIL;
1380
1381 if (FAIL == dbsync_compare_str(dbrow[12], snmpitem->snmpv3_privpassphrase))
1382 return FAIL;
1383
1384 if (FAIL == dbsync_compare_uchar(dbrow[26], snmpitem->snmpv3_authprotocol))
1385 return FAIL;
1386
1387 if (FAIL == dbsync_compare_uchar(dbrow[27], snmpitem->snmpv3_privprotocol))
1388 return FAIL;
1389
1390 if (FAIL == dbsync_compare_str(dbrow[28], snmpitem->snmpv3_contextname))
1391 return FAIL;
1392
1393 if (FAIL == dbsync_compare_str(dbrow[7], snmpitem->snmp_oid))
1394 return FAIL;
1395 }
1396 else if (NULL != snmpitem)
1397 return FAIL;
1398
1399 ipmiitem = (ZBX_DC_IPMIITEM *)zbx_hashset_search(&dbsync_env.cache->ipmiitems, &item->itemid);
1400 if (ITEM_TYPE_IPMI == item->type)
1401 {
1402 if (NULL == ipmiitem)
1403 return FAIL;
1404
1405 if (FAIL == dbsync_compare_str(dbrow[13], ipmiitem->ipmi_sensor))
1406 return FAIL;
1407 }
1408 else if (NULL != ipmiitem)
1409 return FAIL;
1410
1411 trapitem = (ZBX_DC_TRAPITEM *)zbx_hashset_search(&dbsync_env.cache->trapitems, &item->itemid);
1412 if (ITEM_TYPE_TRAPPER == item->type && '\0' != *dbrow[15])
1413 {
1414 zbx_trim_str_list(dbrow[15], ',');
1415
1416 if (NULL == trapitem)
1417 return FAIL;
1418
1419 if (FAIL == dbsync_compare_str(dbrow[15], trapitem->trapper_hosts))
1420 return FAIL;
1421 }
1422 else if (NULL != trapitem)
1423 return FAIL;
1424
1425 logitem = (ZBX_DC_LOGITEM *)zbx_hashset_search(&dbsync_env.cache->logitems, &item->itemid);
1426 if (ITEM_VALUE_TYPE_LOG == item->value_type && '\0' != *dbrow[16])
1427 {
1428 if (NULL == logitem)
1429 return FAIL;
1430
1431 if (FAIL == dbsync_compare_str(dbrow[16], logitem->logtimefmt))
1432 return FAIL;
1433 }
1434 else if (NULL != logitem)
1435 return FAIL;
1436
1437 dbitem = (ZBX_DC_DBITEM *)zbx_hashset_search(&dbsync_env.cache->dbitems, &item->itemid);
1438 if (ITEM_TYPE_DB_MONITOR == item->type && '\0' != *dbrow[17])
1439 {
1440 if (NULL == dbitem)
1441 return FAIL;
1442
1443 if (FAIL == dbsync_compare_str(dbrow[17], dbitem->params))
1444 return FAIL;
1445
1446 if (FAIL == dbsync_compare_str(dbrow[20], dbitem->username))
1447 return FAIL;
1448
1449 if (FAIL == dbsync_compare_str(dbrow[21], dbitem->password))
1450 return FAIL;
1451 }
1452 else if (NULL != dbitem)
1453 return FAIL;
1454
1455 sshitem = (ZBX_DC_SSHITEM *)zbx_hashset_search(&dbsync_env.cache->sshitems, &item->itemid);
1456 if (ITEM_TYPE_SSH == item->type)
1457 {
1458 if (NULL == sshitem)
1459 return FAIL;
1460
1461 if (FAIL == dbsync_compare_uchar(dbrow[19], sshitem->authtype))
1462 return FAIL;
1463
1464 if (FAIL == dbsync_compare_str(dbrow[20], sshitem->username))
1465 return FAIL;
1466
1467 if (FAIL == dbsync_compare_str(dbrow[21], sshitem->password))
1468 return FAIL;
1469
1470 if (FAIL == dbsync_compare_str(dbrow[22], sshitem->publickey))
1471 return FAIL;
1472
1473 if (FAIL == dbsync_compare_str(dbrow[23], sshitem->privatekey))
1474 return FAIL;
1475
1476 if (FAIL == dbsync_compare_str(dbrow[17], sshitem->params))
1477 return FAIL;
1478 }
1479 else if (NULL != sshitem)
1480 return FAIL;
1481
1482 telnetitem = (ZBX_DC_TELNETITEM *)zbx_hashset_search(&dbsync_env.cache->telnetitems, &item->itemid);
1483 if (ITEM_TYPE_TELNET == item->type)
1484 {
1485 if (NULL == telnetitem)
1486 return FAIL;
1487
1488 if (FAIL == dbsync_compare_str(dbrow[20], telnetitem->username))
1489 return FAIL;
1490
1491 if (FAIL == dbsync_compare_str(dbrow[21], telnetitem->password))
1492 return FAIL;
1493
1494 if (FAIL == dbsync_compare_str(dbrow[17], telnetitem->params))
1495 return FAIL;
1496 }
1497 else if (NULL != telnetitem)
1498 return FAIL;
1499
1500 simpleitem = (ZBX_DC_SIMPLEITEM *)zbx_hashset_search(&dbsync_env.cache->simpleitems, &item->itemid);
1501 if (ITEM_TYPE_SIMPLE == item->type)
1502 {
1503 if (NULL == simpleitem)
1504 return FAIL;
1505
1506 if (FAIL == dbsync_compare_str(dbrow[20], simpleitem->username))
1507 return FAIL;
1508
1509 if (FAIL == dbsync_compare_str(dbrow[21], simpleitem->password))
1510 return FAIL;
1511 }
1512 else if (NULL != simpleitem)
1513 return FAIL;
1514
1515 jmxitem = (ZBX_DC_JMXITEM *)zbx_hashset_search(&dbsync_env.cache->jmxitems, &item->itemid);
1516 if (ITEM_TYPE_JMX == item->type)
1517 {
1518 if (NULL == jmxitem)
1519 return FAIL;
1520
1521 if (FAIL == dbsync_compare_str(dbrow[20], jmxitem->username))
1522 return FAIL;
1523
1524 if (FAIL == dbsync_compare_str(dbrow[21], jmxitem->password))
1525 return FAIL;
1526
1527 if (FAIL == dbsync_compare_str(dbrow[37], jmxitem->jmx_endpoint))
1528 return FAIL;
1529 }
1530 else if (NULL != jmxitem)
1531 return FAIL;
1532
1533 calcitem = (ZBX_DC_CALCITEM *)zbx_hashset_search(&dbsync_env.cache->calcitems, &item->itemid);
1534 if (ITEM_TYPE_CALCULATED == item->type)
1535 {
1536 if (NULL == calcitem)
1537 return FAIL;
1538
1539 if (FAIL == dbsync_compare_str(dbrow[17], calcitem->params))
1540 return FAIL;
1541 }
1542 else if (NULL != calcitem)
1543 return FAIL;
1544
1545 depitem = (ZBX_DC_DEPENDENTITEM *)zbx_hashset_search(&dbsync_env.cache->dependentitems, &item->itemid);
1546 if (ITEM_TYPE_DEPENDENT == item->type)
1547 {
1548 if (NULL == depitem)
1549 return FAIL;
1550
1551 if (FAIL == dbsync_compare_uint64(dbrow[38], depitem->master_itemid))
1552 return FAIL;
1553 }
1554 else if (NULL != depitem)
1555 return FAIL;
1556
1557 httpitem = (ZBX_DC_HTTPITEM *)zbx_hashset_search(&dbsync_env.cache->httpitems, &item->itemid);
1558 if (ITEM_TYPE_HTTPAGENT == item->type)
1559 {
1560 zbx_trim_str_list(dbrow[15], ',');
1561
1562 if (NULL == httpitem)
1563 return FAIL;
1564
1565 if (FAIL == dbsync_compare_str(dbrow[39], httpitem->timeout))
1566 return FAIL;
1567
1568 if (FAIL == dbsync_compare_str(dbrow[40], httpitem->url))
1569 return FAIL;
1570
1571 if (FAIL == dbsync_compare_str(dbrow[41], httpitem->query_fields))
1572 return FAIL;
1573
1574 if (FAIL == dbsync_compare_str(dbrow[42], httpitem->posts))
1575 return FAIL;
1576
1577 if (FAIL == dbsync_compare_str(dbrow[43], httpitem->status_codes))
1578 return FAIL;
1579
1580 if (FAIL == dbsync_compare_uchar(dbrow[44], httpitem->follow_redirects))
1581 return FAIL;
1582
1583 if (FAIL == dbsync_compare_uchar(dbrow[45], httpitem->post_type))
1584 return FAIL;
1585
1586 if (FAIL == dbsync_compare_str(dbrow[46], httpitem->http_proxy))
1587 return FAIL;
1588
1589 if (FAIL == dbsync_compare_str(dbrow[47], httpitem->headers))
1590 return FAIL;
1591
1592 if (FAIL == dbsync_compare_uchar(dbrow[48], httpitem->retrieve_mode))
1593 return FAIL;
1594
1595 if (FAIL == dbsync_compare_uchar(dbrow[49], httpitem->request_method))
1596 return FAIL;
1597
1598 if (FAIL == dbsync_compare_uchar(dbrow[50], httpitem->output_format))
1599 return FAIL;
1600
1601 if (FAIL == dbsync_compare_str(dbrow[51], httpitem->ssl_cert_file))
1602 return FAIL;
1603
1604 if (FAIL == dbsync_compare_str(dbrow[52], httpitem->ssl_key_file))
1605 return FAIL;
1606
1607 if (FAIL == dbsync_compare_str(dbrow[53], httpitem->ssl_key_password))
1608 return FAIL;
1609
1610 if (FAIL == dbsync_compare_uchar(dbrow[54], httpitem->verify_peer))
1611 return FAIL;
1612
1613 if (FAIL == dbsync_compare_uchar(dbrow[55], httpitem->verify_host))
1614 return FAIL;
1615
1616 if (FAIL == dbsync_compare_uchar(dbrow[19], httpitem->authtype))
1617 return FAIL;
1618
1619 if (FAIL == dbsync_compare_str(dbrow[20], httpitem->username))
1620 return FAIL;
1621
1622 if (FAIL == dbsync_compare_str(dbrow[21], httpitem->password))
1623 return FAIL;
1624
1625 if (FAIL == dbsync_compare_uchar(dbrow[56], httpitem->allow_traps))
1626 return FAIL;
1627
1628 if (FAIL == dbsync_compare_str(dbrow[15], httpitem->trapper_hosts))
1629 return FAIL;
1630 }
1631 else if (NULL != httpitem)
1632 return FAIL;
1633
1634 return SUCCEED;
1635 }
1636
1637 /******************************************************************************
1638 * *
1639 * Function: dbsync_item_preproc_row *
1640 * *
1641 * Purpose: applies necessary preprocessing before row is compared/used *
1642 * *
1643 * Parameter: row - [IN] the row to preprocess *
1644 * *
1645 * Return value: the preprocessed row *
1646 * *
1647 * Comments: The row preprocessing can be used to expand user macros in *
1648 * some columns. *
1649 * *
1650 ******************************************************************************/
dbsync_item_preproc_row(char ** row)1651 static char **dbsync_item_preproc_row(char **row)
1652 {
1653 #define ZBX_DBSYNC_ITEM_COLUMN_DELAY 0x01
1654 #define ZBX_DBSYNC_ITEM_COLUMN_HISTORY 0x02
1655 #define ZBX_DBSYNC_ITEM_COLUMN_TRENDS 0x04
1656
1657 zbx_uint64_t hostid;
1658 unsigned char flags = 0;
1659
1660 /* return the original row if user macros are not used in target columns */
1661
1662 if (SUCCEED == dbsync_check_row_macros(row, 14))
1663 flags |= ZBX_DBSYNC_ITEM_COLUMN_DELAY;
1664
1665 if (SUCCEED == dbsync_check_row_macros(row, 31))
1666 flags |= ZBX_DBSYNC_ITEM_COLUMN_HISTORY;
1667
1668 if (SUCCEED == dbsync_check_row_macros(row, 32))
1669 flags |= ZBX_DBSYNC_ITEM_COLUMN_TRENDS;
1670
1671 if (0 == flags)
1672 return row;
1673
1674 /* get associated host identifier */
1675 ZBX_STR2UINT64(hostid, row[1]);
1676
1677 /* expand user macros */
1678
1679 if (0 != (flags & ZBX_DBSYNC_ITEM_COLUMN_DELAY))
1680 row[14] = zbx_dc_expand_user_macros(row[14], &hostid, 1, NULL);
1681
1682 if (0 != (flags & ZBX_DBSYNC_ITEM_COLUMN_HISTORY))
1683 row[31] = zbx_dc_expand_user_macros(row[31], &hostid, 1, NULL);
1684
1685 if (0 != (flags & ZBX_DBSYNC_ITEM_COLUMN_TRENDS))
1686 row[32] = zbx_dc_expand_user_macros(row[32], &hostid, 1, NULL);
1687
1688 return row;
1689
1690 #undef ZBX_DBSYNC_ITEM_COLUMN_DELAY
1691 #undef ZBX_DBSYNC_ITEM_COLUMN_HISTORY
1692 #undef ZBX_DBSYNC_ITEM_COLUMN_TRENDS
1693 }
1694
1695 /******************************************************************************
1696 * *
1697 * Function: zbx_dbsync_compare_items *
1698 * *
1699 * Purpose: compares items table with cached configuration data *
1700 * *
1701 * Parameter: cache - [IN] the configuration cache *
1702 * sync - [OUT] the changeset *
1703 * *
1704 * Return value: SUCCEED - the changeset was successfully calculated *
1705 * FAIL - otherwise *
1706 * *
1707 ******************************************************************************/
zbx_dbsync_compare_items(zbx_dbsync_t * sync)1708 int zbx_dbsync_compare_items(zbx_dbsync_t *sync)
1709 {
1710 DB_ROW dbrow;
1711 DB_RESULT result;
1712 zbx_hashset_t ids;
1713 zbx_hashset_iter_t iter;
1714 zbx_uint64_t rowid;
1715 ZBX_DC_ITEM *item;
1716 char **row;
1717
1718 if (NULL == (result = DBselect(
1719 "select i.itemid,i.hostid,i.status,i.type,i.value_type,i.key_,"
1720 "i.snmp_community,i.snmp_oid,i.port,i.snmpv3_securityname,i.snmpv3_securitylevel,"
1721 "i.snmpv3_authpassphrase,i.snmpv3_privpassphrase,i.ipmi_sensor,i.delay,"
1722 "i.trapper_hosts,i.logtimefmt,i.params,i.state,i.authtype,i.username,i.password,"
1723 "i.publickey,i.privatekey,i.flags,i.interfaceid,i.snmpv3_authprotocol,"
1724 "i.snmpv3_privprotocol,i.snmpv3_contextname,i.lastlogsize,i.mtime,"
1725 "i.history,i.trends,i.inventory_link,i.valuemapid,i.units,i.error,i.jmx_endpoint,"
1726 "i.master_itemid,i.timeout,i.url,i.query_fields,i.posts,i.status_codes,"
1727 "i.follow_redirects,i.post_type,i.http_proxy,i.headers,i.retrieve_mode,"
1728 "i.request_method,i.output_format,i.ssl_cert_file,i.ssl_key_file,i.ssl_key_password,"
1729 "i.verify_peer,i.verify_host,i.allow_traps"
1730 " from items i,hosts h"
1731 " where i.hostid=h.hostid"
1732 " and h.status in (%d,%d)"
1733 " and i.flags<>%d",
1734 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
1735 ZBX_FLAG_DISCOVERY_PROTOTYPE)))
1736 {
1737 return FAIL;
1738 }
1739
1740 dbsync_prepare(sync, 57, dbsync_item_preproc_row);
1741
1742 if (ZBX_DBSYNC_INIT == sync->mode)
1743 {
1744 sync->dbresult = result;
1745 return SUCCEED;
1746 }
1747
1748 zbx_hashset_create(&ids, dbsync_env.cache->items.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
1749 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
1750
1751 while (NULL != (dbrow = DBfetch(result)))
1752 {
1753 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
1754
1755 ZBX_STR2UINT64(rowid, dbrow[0]);
1756 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
1757
1758 row = dbsync_preproc_row(sync, dbrow);
1759
1760 if (NULL == (item = (ZBX_DC_ITEM *)zbx_hashset_search(&dbsync_env.cache->items, &rowid)))
1761 tag = ZBX_DBSYNC_ROW_ADD;
1762 else if (FAIL == dbsync_compare_item(item, row))
1763 tag = ZBX_DBSYNC_ROW_UPDATE;
1764
1765 if (ZBX_DBSYNC_ROW_NONE != tag)
1766 dbsync_add_row(sync, rowid, tag, row);
1767 }
1768
1769 zbx_hashset_iter_reset(&dbsync_env.cache->items, &iter);
1770 while (NULL != (item = (ZBX_DC_ITEM *)zbx_hashset_iter_next(&iter)))
1771 {
1772 if (NULL == zbx_hashset_search(&ids, &item->itemid))
1773 dbsync_add_row(sync, item->itemid, ZBX_DBSYNC_ROW_REMOVE, NULL);
1774 }
1775
1776 zbx_hashset_destroy(&ids);
1777 DBfree_result(result);
1778
1779 return SUCCEED;
1780 }
1781
1782 /******************************************************************************
1783 * *
1784 * Function: dbsync_compare_trigger *
1785 * *
1786 * Purpose: compares triggers table row with cached configuration data *
1787 * *
1788 * Parameter: trigger - [IN] the cached trigger *
1789 * row - [IN] the database row *
1790 * *
1791 * Return value: SUCCEED - the row matches configuration data *
1792 * FAIL - otherwise *
1793 * *
1794 ******************************************************************************/
dbsync_compare_trigger(const ZBX_DC_TRIGGER * trigger,const DB_ROW dbrow)1795 static int dbsync_compare_trigger(const ZBX_DC_TRIGGER *trigger, const DB_ROW dbrow)
1796 {
1797 if (FAIL == dbsync_compare_str(dbrow[1], trigger->description))
1798 return FAIL;
1799
1800 if (FAIL == dbsync_compare_str(dbrow[2], trigger->expression))
1801 return FAIL;
1802
1803 if (FAIL == dbsync_compare_uchar(dbrow[4], trigger->priority))
1804 return FAIL;
1805
1806 if (FAIL == dbsync_compare_uchar(dbrow[5], trigger->type))
1807 return FAIL;
1808
1809 if (FAIL == dbsync_compare_uchar(dbrow[9], trigger->status))
1810 return FAIL;
1811
1812 if (FAIL == dbsync_compare_uchar(dbrow[10], trigger->recovery_mode))
1813 return FAIL;
1814
1815 if (FAIL == dbsync_compare_str(dbrow[11], trigger->recovery_expression))
1816 return FAIL;
1817
1818 if (FAIL == dbsync_compare_uchar(dbrow[12], trigger->correlation_mode))
1819 return FAIL;
1820
1821 if (FAIL == dbsync_compare_str(dbrow[13], trigger->correlation_tag))
1822 return FAIL;
1823
1824 return SUCCEED;
1825 }
1826
1827 #define ZBX_DBSYNC_TRIGGER_COLUMN_EXPRESSION 0x01
1828 #define ZBX_DBSYNC_TRIGGER_COLUMN_RECOVERY_EXPRESSION 0x02
1829
1830 /******************************************************************************
1831 * *
1832 * Function: dbsync_trigger_preproc_row *
1833 * *
1834 * Purpose: applies necessary preprocessing before row is compared/used *
1835 * *
1836 * Parameter: row - [IN] the row to preprocess *
1837 * *
1838 * Return value: the preprocessed row *
1839 * *
1840 * Comments: The row preprocessing can be used to expand user macros in *
1841 * some columns. *
1842 * *
1843 ******************************************************************************/
dbsync_trigger_preproc_row(char ** row)1844 static char **dbsync_trigger_preproc_row(char **row)
1845 {
1846 zbx_vector_uint64_t hostids, functionids;
1847 unsigned char flags = 0;
1848
1849 /* return the original row if user macros are not used in target columns */
1850
1851 if (SUCCEED == dbsync_check_row_macros(row, 2))
1852 flags |= ZBX_DBSYNC_TRIGGER_COLUMN_EXPRESSION;
1853
1854 if (SUCCEED == dbsync_check_row_macros(row, 11))
1855 flags |= ZBX_DBSYNC_TRIGGER_COLUMN_RECOVERY_EXPRESSION;
1856
1857 if (0 == flags)
1858 return row;
1859
1860 /* get associated host identifiers */
1861
1862 zbx_vector_uint64_create(&hostids);
1863 zbx_vector_uint64_create(&functionids);
1864
1865 get_functionids(&functionids, row[2]);
1866 get_functionids(&functionids, row[11]);
1867
1868 zbx_dc_get_hostids_by_functionids(functionids.values, functionids.values_num, &hostids);
1869
1870 /* expand user macros */
1871
1872 if (0 != (flags & ZBX_DBSYNC_TRIGGER_COLUMN_EXPRESSION))
1873 {
1874 row[2] = zbx_dc_expand_user_macros(row[2], hostids.values, hostids.values_num,
1875 dbsync_numeric_validator);
1876 }
1877
1878 if (0 != (flags & ZBX_DBSYNC_TRIGGER_COLUMN_RECOVERY_EXPRESSION))
1879 {
1880 row[11] = zbx_dc_expand_user_macros(row[11], hostids.values, hostids.values_num,
1881 dbsync_numeric_validator);
1882 }
1883
1884 zbx_vector_uint64_destroy(&functionids);
1885 zbx_vector_uint64_destroy(&hostids);
1886
1887 return row;
1888 }
1889
1890 /******************************************************************************
1891 * *
1892 * Function: zbx_dbsync_compare_triggers *
1893 * *
1894 * Purpose: compares triggers table with cached configuration data *
1895 * *
1896 * Parameter: cache - [IN] the configuration cache *
1897 * sync - [OUT] the changeset *
1898 * *
1899 * Return value: SUCCEED - the changeset was successfully calculated *
1900 * FAIL - otherwise *
1901 * *
1902 ******************************************************************************/
zbx_dbsync_compare_triggers(zbx_dbsync_t * sync)1903 int zbx_dbsync_compare_triggers(zbx_dbsync_t *sync)
1904 {
1905 DB_ROW dbrow;
1906 DB_RESULT result;
1907 zbx_hashset_t ids;
1908 zbx_hashset_iter_t iter;
1909 zbx_uint64_t rowid;
1910 ZBX_DC_TRIGGER *trigger;
1911 char **row;
1912
1913 if (NULL == (result = DBselect(
1914 "select distinct t.triggerid,t.description,t.expression,t.error,t.priority,t.type,t.value,"
1915 "t.state,t.lastchange,t.status,t.recovery_mode,t.recovery_expression,"
1916 "t.correlation_mode,t.correlation_tag"
1917 " from hosts h,items i,functions f,triggers t"
1918 " where h.hostid=i.hostid"
1919 " and i.itemid=f.itemid"
1920 " and f.triggerid=t.triggerid"
1921 " and h.status in (%d,%d)"
1922 " and t.flags<>%d",
1923 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
1924 ZBX_FLAG_DISCOVERY_PROTOTYPE)))
1925 {
1926 return FAIL;
1927 }
1928
1929 dbsync_prepare(sync, 14, dbsync_trigger_preproc_row);
1930
1931 if (ZBX_DBSYNC_INIT == sync->mode)
1932 {
1933 sync->dbresult = result;
1934 return SUCCEED;
1935 }
1936
1937 zbx_hashset_create(&ids, dbsync_env.cache->triggers.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
1938 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
1939
1940 while (NULL != (dbrow = DBfetch(result)))
1941 {
1942 ZBX_STR2UINT64(rowid, dbrow[0]);
1943 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
1944
1945 row = dbsync_preproc_row(sync, dbrow);
1946
1947 if (NULL == (trigger = (ZBX_DC_TRIGGER *)zbx_hashset_search(&dbsync_env.cache->triggers, &rowid)))
1948 {
1949 dbsync_add_row(sync, rowid, ZBX_DBSYNC_ROW_ADD, row);
1950 }
1951 else
1952 {
1953 if (FAIL == dbsync_compare_trigger(trigger, row))
1954 dbsync_add_row(sync, rowid, ZBX_DBSYNC_ROW_UPDATE, row);
1955 }
1956 }
1957
1958 zbx_hashset_iter_reset(&dbsync_env.cache->triggers, &iter);
1959 while (NULL != (trigger = (ZBX_DC_TRIGGER *)zbx_hashset_iter_next(&iter)))
1960 {
1961 if (NULL == zbx_hashset_search(&ids, &trigger->triggerid))
1962 dbsync_add_row(sync, trigger->triggerid, ZBX_DBSYNC_ROW_REMOVE, NULL);
1963 }
1964
1965 zbx_hashset_destroy(&ids);
1966 DBfree_result(result);
1967
1968 return SUCCEED;
1969 }
1970
1971 /******************************************************************************
1972 * *
1973 * Function: zbx_dbsync_compare_trigger_dependency *
1974 * *
1975 * Purpose: compares trigger_depends table with cached configuration data *
1976 * *
1977 * Parameter: cache - [IN] the configuration cache *
1978 * sync - [OUT] the changeset *
1979 * *
1980 * Return value: SUCCEED - the changeset was successfully calculated *
1981 * FAIL - otherwise *
1982 * *
1983 ******************************************************************************/
zbx_dbsync_compare_trigger_dependency(zbx_dbsync_t * sync)1984 int zbx_dbsync_compare_trigger_dependency(zbx_dbsync_t *sync)
1985 {
1986 DB_ROW dbrow;
1987 DB_RESULT result;
1988 zbx_hashset_t deps;
1989 zbx_hashset_iter_t iter;
1990 ZBX_DC_TRIGGER_DEPLIST *dep_down, *dep_up;
1991 zbx_uint64_pair_t *dep, dep_local;
1992 char down_s[MAX_ID_LEN + 1], up_s[MAX_ID_LEN + 1];
1993 char *del_row[2] = {down_s, up_s};
1994 int i;
1995
1996 if (NULL == (result = DBselect(
1997 "select distinct d.triggerid_down,d.triggerid_up"
1998 " from trigger_depends d,triggers t,hosts h,items i,functions f"
1999 " where t.triggerid=d.triggerid_down"
2000 " and t.flags<>%d"
2001 " and h.hostid=i.hostid"
2002 " and i.itemid=f.itemid"
2003 " and f.triggerid=d.triggerid_down"
2004 " and h.status in (%d,%d)",
2005 ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED)))
2006 {
2007 return FAIL;
2008 }
2009
2010 dbsync_prepare(sync, 2, NULL);
2011
2012 if (ZBX_DBSYNC_INIT == sync->mode)
2013 {
2014 sync->dbresult = result;
2015 return SUCCEED;
2016 }
2017
2018 zbx_hashset_create(&deps, 100, ZBX_DEFAULT_UINT64_PAIR_HASH_FUNC, ZBX_DEFAULT_UINT64_PAIR_COMPARE_FUNC);
2019
2020 /* index all host->template links */
2021 zbx_hashset_iter_reset(&dbsync_env.cache->trigdeps, &iter);
2022 while (NULL != (dep_down = (ZBX_DC_TRIGGER_DEPLIST *)zbx_hashset_iter_next(&iter)))
2023 {
2024 dep_local.first = dep_down->triggerid;
2025
2026 for (i = 0; i < dep_down->dependencies.values_num; i++)
2027 {
2028 dep_up = (ZBX_DC_TRIGGER_DEPLIST *)dep_down->dependencies.values[i];
2029 dep_local.second = dep_up->triggerid;
2030 zbx_hashset_insert(&deps, &dep_local, sizeof(dep_local));
2031 }
2032 }
2033
2034 /* add new rows, remove existing rows from index */
2035 while (NULL != (dbrow = DBfetch(result)))
2036 {
2037 ZBX_STR2UINT64(dep_local.first, dbrow[0]);
2038 ZBX_STR2UINT64(dep_local.second, dbrow[1]);
2039
2040 if (NULL == (dep = (zbx_uint64_pair_t *)zbx_hashset_search(&deps, &dep_local)))
2041 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_ADD, dbrow);
2042 else
2043 zbx_hashset_remove_direct(&deps, dep);
2044 }
2045
2046 /* add removed rows */
2047 zbx_hashset_iter_reset(&deps, &iter);
2048 while (NULL != (dep = (zbx_uint64_pair_t *)zbx_hashset_iter_next(&iter)))
2049 {
2050 zbx_snprintf(down_s, sizeof(down_s), ZBX_FS_UI64, dep->first);
2051 zbx_snprintf(up_s, sizeof(up_s), ZBX_FS_UI64, dep->second);
2052 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_REMOVE, del_row);
2053 }
2054
2055 DBfree_result(result);
2056 zbx_hashset_destroy(&deps);
2057
2058 return SUCCEED;
2059 }
2060
2061 /******************************************************************************
2062 * *
2063 * Function: dbsync_compare_function *
2064 * *
2065 * Purpose: compares functions table row with cached configuration data *
2066 * *
2067 * Parameter: function - [IN] the cached function *
2068 * row - [IN] the database row *
2069 * *
2070 * Return value: SUCCEED - the row matches configuration data *
2071 * FAIL - otherwise *
2072 * *
2073 ******************************************************************************/
dbsync_compare_function(const ZBX_DC_FUNCTION * function,const DB_ROW dbrow)2074 static int dbsync_compare_function(const ZBX_DC_FUNCTION *function, const DB_ROW dbrow)
2075 {
2076 if (FAIL == dbsync_compare_uint64(dbrow[0], function->itemid))
2077 return FAIL;
2078
2079 if (FAIL == dbsync_compare_uint64(dbrow[4], function->triggerid))
2080 return FAIL;
2081
2082 if (FAIL == dbsync_compare_str(dbrow[2], function->function))
2083 return FAIL;
2084
2085 if (FAIL == dbsync_compare_str(dbrow[3], function->parameter))
2086 return FAIL;
2087
2088 return SUCCEED;
2089 }
2090
2091 /******************************************************************************
2092 * *
2093 * Function: zbx_dbsync_compare_functions *
2094 * *
2095 * Purpose: compares functions table with cached configuration data *
2096 * *
2097 * Parameter: cache - [IN] the configuration cache *
2098 * sync - [OUT] the changeset *
2099 * *
2100 * Return value: SUCCEED - the changeset was successfully calculated *
2101 * FAIL - otherwise *
2102 * *
2103 ******************************************************************************/
zbx_dbsync_compare_functions(zbx_dbsync_t * sync)2104 int zbx_dbsync_compare_functions(zbx_dbsync_t *sync)
2105 {
2106 DB_ROW dbrow;
2107 DB_RESULT result;
2108 zbx_hashset_t ids;
2109 zbx_hashset_iter_t iter;
2110 zbx_uint64_t rowid;
2111 ZBX_DC_FUNCTION *function;
2112
2113 if (NULL == (result = DBselect(
2114 "select i.itemid,f.functionid,f.name,f.parameter,t.triggerid"
2115 " from hosts h,items i,functions f,triggers t"
2116 " where h.hostid=i.hostid"
2117 " and i.itemid=f.itemid"
2118 " and f.triggerid=t.triggerid"
2119 " and h.status in (%d,%d)"
2120 " and t.flags<>%d",
2121 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED,
2122 ZBX_FLAG_DISCOVERY_PROTOTYPE)))
2123 {
2124 return FAIL;
2125 }
2126
2127 dbsync_prepare(sync, 5, NULL);
2128
2129 if (ZBX_DBSYNC_INIT == sync->mode)
2130 {
2131 sync->dbresult = result;
2132 return SUCCEED;
2133 }
2134
2135 zbx_hashset_create(&ids, dbsync_env.cache->functions.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2136 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2137
2138 while (NULL != (dbrow = DBfetch(result)))
2139 {
2140 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2141
2142 ZBX_STR2UINT64(rowid, dbrow[1]);
2143 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2144
2145 if (NULL == (function = (ZBX_DC_FUNCTION *)zbx_hashset_search(&dbsync_env.cache->functions, &rowid)))
2146 tag = ZBX_DBSYNC_ROW_ADD;
2147 else if (FAIL == dbsync_compare_function(function, dbrow))
2148 tag = ZBX_DBSYNC_ROW_UPDATE;
2149
2150 if (ZBX_DBSYNC_ROW_NONE != tag)
2151 dbsync_add_row(sync, rowid, tag, dbrow);
2152 }
2153
2154 zbx_hashset_iter_reset(&dbsync_env.cache->functions, &iter);
2155 while (NULL != (function = (ZBX_DC_FUNCTION *)zbx_hashset_iter_next(&iter)))
2156 {
2157 if (NULL == zbx_hashset_search(&ids, &function->functionid))
2158 dbsync_add_row(sync, function->functionid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2159 }
2160
2161 zbx_hashset_destroy(&ids);
2162 DBfree_result(result);
2163
2164 return SUCCEED;
2165 }
2166
2167 /******************************************************************************
2168 * *
2169 * Function: dbsync_compare_expression *
2170 * *
2171 * Purpose: compares expressions table row with cached configuration data *
2172 * *
2173 * Parameter: expression - [IN] the cached expression *
2174 * row - [IN] the database row *
2175 * *
2176 * Return value: SUCCEED - the row matches configuration data *
2177 * FAIL - otherwise *
2178 * *
2179 ******************************************************************************/
dbsync_compare_expression(const ZBX_DC_EXPRESSION * expression,const DB_ROW dbrow)2180 static int dbsync_compare_expression(const ZBX_DC_EXPRESSION *expression, const DB_ROW dbrow)
2181 {
2182 if (FAIL == dbsync_compare_str(dbrow[0], expression->regexp))
2183 return FAIL;
2184
2185 if (FAIL == dbsync_compare_str(dbrow[2], expression->expression))
2186 return FAIL;
2187
2188 if (FAIL == dbsync_compare_uchar(dbrow[3], expression->type))
2189 return FAIL;
2190
2191 if (*dbrow[4] != expression->delimiter)
2192 return FAIL;
2193
2194 if (FAIL == dbsync_compare_uchar(dbrow[5], expression->case_sensitive))
2195 return FAIL;
2196
2197 return SUCCEED;
2198 }
2199
2200 /******************************************************************************
2201 * *
2202 * Function: zbx_dbsync_compare_exprssions *
2203 * *
2204 * Purpose: compares expressions, regexps tables with cached configuration *
2205 * data *
2206 * *
2207 * Parameter: cache - [IN] the configuration cache *
2208 * sync - [OUT] the changeset *
2209 * *
2210 * Return value: SUCCEED - the changeset was successfully calculated *
2211 * FAIL - otherwise *
2212 * *
2213 ******************************************************************************/
zbx_dbsync_compare_expressions(zbx_dbsync_t * sync)2214 int zbx_dbsync_compare_expressions(zbx_dbsync_t *sync)
2215 {
2216 DB_ROW dbrow;
2217 DB_RESULT result;
2218 zbx_hashset_t ids;
2219 zbx_hashset_iter_t iter;
2220 zbx_uint64_t rowid;
2221 ZBX_DC_EXPRESSION *expression;
2222
2223 if (NULL == (result = DBselect(
2224 "select r.name,e.expressionid,e.expression,e.expression_type,e.exp_delimiter,e.case_sensitive"
2225 " from regexps r,expressions e"
2226 " where r.regexpid=e.regexpid")))
2227 {
2228 return FAIL;
2229 }
2230
2231 dbsync_prepare(sync, 6, NULL);
2232
2233 if (ZBX_DBSYNC_INIT == sync->mode)
2234 {
2235 sync->dbresult = result;
2236 return SUCCEED;
2237 }
2238
2239 zbx_hashset_create(&ids, dbsync_env.cache->expressions.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2240 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2241
2242 while (NULL != (dbrow = DBfetch(result)))
2243 {
2244 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2245
2246 ZBX_STR2UINT64(rowid, dbrow[1]);
2247 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2248
2249 if (NULL == (expression = (ZBX_DC_EXPRESSION *)zbx_hashset_search(&dbsync_env.cache->expressions,
2250 &rowid)))
2251 {
2252 tag = ZBX_DBSYNC_ROW_ADD;
2253 }
2254 else if (FAIL == dbsync_compare_expression(expression, dbrow))
2255 tag = ZBX_DBSYNC_ROW_UPDATE;
2256
2257 if (ZBX_DBSYNC_ROW_NONE != tag)
2258 dbsync_add_row(sync, rowid, tag, dbrow);
2259 }
2260
2261 zbx_hashset_iter_reset(&dbsync_env.cache->expressions, &iter);
2262 while (NULL != (expression = (ZBX_DC_EXPRESSION *)zbx_hashset_iter_next(&iter)))
2263 {
2264 if (NULL == zbx_hashset_search(&ids, &expression->expressionid))
2265 dbsync_add_row(sync, expression->expressionid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2266 }
2267
2268 zbx_hashset_destroy(&ids);
2269 DBfree_result(result);
2270
2271 return SUCCEED;
2272 }
2273
2274 /******************************************************************************
2275 * *
2276 * Function: dbsync_compare_action *
2277 * *
2278 * Purpose: compares actions table row with cached configuration data *
2279 * *
2280 * Parameter: action - [IN] the cached action *
2281 * row - [IN] the database row *
2282 * *
2283 * Return value: SUCCEED - the row matches configuration data *
2284 * FAIL - otherwise *
2285 * *
2286 ******************************************************************************/
dbsync_compare_action(const zbx_dc_action_t * action,const DB_ROW dbrow)2287 static int dbsync_compare_action(const zbx_dc_action_t *action, const DB_ROW dbrow)
2288 {
2289
2290 if (FAIL == dbsync_compare_uchar(dbrow[1], action->eventsource))
2291 return FAIL;
2292
2293 if (FAIL == dbsync_compare_uchar(dbrow[2], action->evaltype))
2294 return FAIL;
2295
2296 if (FAIL == dbsync_compare_str(dbrow[3], action->formula))
2297 return FAIL;
2298
2299 return SUCCEED;
2300 }
2301
2302 /******************************************************************************
2303 * *
2304 * Function: zbx_dbsync_compare_actions *
2305 * *
2306 * Purpose: compares actions table with cached configuration data *
2307 * *
2308 * Parameter: sync - [OUT] the changeset *
2309 * *
2310 * Return value: SUCCEED - the changeset was successfully calculated *
2311 * FAIL - otherwise *
2312 * *
2313 ******************************************************************************/
zbx_dbsync_compare_actions(zbx_dbsync_t * sync)2314 int zbx_dbsync_compare_actions(zbx_dbsync_t *sync)
2315 {
2316 DB_ROW dbrow;
2317 DB_RESULT result;
2318 zbx_hashset_t ids;
2319 zbx_hashset_iter_t iter;
2320 zbx_uint64_t rowid;
2321 zbx_dc_action_t *action;
2322
2323 if (NULL == (result = DBselect(
2324 "select actionid,eventsource,evaltype,formula"
2325 " from actions"
2326 " where status=%d",
2327 ACTION_STATUS_ACTIVE)))
2328 {
2329 return FAIL;
2330 }
2331
2332 dbsync_prepare(sync, 4, NULL);
2333
2334 if (ZBX_DBSYNC_INIT == sync->mode)
2335 {
2336 sync->dbresult = result;
2337 return SUCCEED;
2338 }
2339
2340 zbx_hashset_create(&ids, dbsync_env.cache->actions.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2341 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2342
2343 while (NULL != (dbrow = DBfetch(result)))
2344 {
2345 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2346
2347 ZBX_STR2UINT64(rowid, dbrow[0]);
2348 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2349
2350 if (NULL == (action = (zbx_dc_action_t *)zbx_hashset_search(&dbsync_env.cache->actions, &rowid)))
2351 tag = ZBX_DBSYNC_ROW_ADD;
2352 else if (FAIL == dbsync_compare_action(action, dbrow))
2353 tag = ZBX_DBSYNC_ROW_UPDATE;
2354
2355 if (ZBX_DBSYNC_ROW_NONE != tag)
2356 dbsync_add_row(sync, rowid, tag, dbrow);
2357 }
2358
2359 zbx_hashset_iter_reset(&dbsync_env.cache->actions, &iter);
2360 while (NULL != (action = (zbx_dc_action_t *)zbx_hashset_iter_next(&iter)))
2361 {
2362 if (NULL == zbx_hashset_search(&ids, &action->actionid))
2363 dbsync_add_row(sync, action->actionid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2364 }
2365
2366 zbx_hashset_destroy(&ids);
2367 DBfree_result(result);
2368
2369 return SUCCEED;
2370 }
2371
2372 /******************************************************************************
2373 * *
2374 * Function: dbsync_compare_action_op *
2375 * *
2376 * Purpose: compares action operation class and flushes update row if *
2377 * necessary *
2378 * *
2379 * Parameter: sync - [OUT] the changeset *
2380 * actionid - [IN] the action identifier *
2381 * opflags - [IN] the action operation class flags *
2382 * *
2383 ******************************************************************************/
dbsync_compare_action_op(zbx_dbsync_t * sync,zbx_uint64_t actionid,unsigned char opflags)2384 static void dbsync_compare_action_op(zbx_dbsync_t *sync, zbx_uint64_t actionid, unsigned char opflags)
2385 {
2386 zbx_dc_action_t *action;
2387
2388 if (0 == actionid)
2389 return;
2390
2391 if (NULL == (action = (zbx_dc_action_t *)zbx_hashset_search(&dbsync_env.cache->actions, &actionid)) ||
2392 opflags != action->opflags)
2393 {
2394 char actionid_s[MAX_ID_LEN], opflags_s[MAX_ID_LEN];
2395 char *row[] = {actionid_s, opflags_s};
2396
2397 zbx_snprintf(actionid_s, sizeof(actionid_s), ZBX_FS_UI64, actionid);
2398 zbx_snprintf(opflags_s, sizeof(opflags_s), "%d", opflags);
2399
2400 dbsync_add_row(sync, actionid, ZBX_DBSYNC_ROW_UPDATE, (DB_ROW)row);
2401 }
2402 }
2403
2404 /******************************************************************************
2405 * *
2406 * Function: zbx_dbsync_compare_action_ops *
2407 * *
2408 * Purpose: compares actions by operation class *
2409 * *
2410 * Parameter: cache - [IN] the configuration cache *
2411 * sync - [OUT] the changeset *
2412 * *
2413 * Return value: SUCCEED - the changeset was successfully calculated *
2414 * FAIL - otherwise *
2415 * *
2416 ******************************************************************************/
zbx_dbsync_compare_action_ops(zbx_dbsync_t * sync)2417 int zbx_dbsync_compare_action_ops(zbx_dbsync_t *sync)
2418 {
2419 DB_ROW dbrow;
2420 DB_RESULT result;
2421 zbx_uint64_t rowid, actionid = 0;
2422 unsigned char opflags = ZBX_ACTION_OPCLASS_NONE;
2423
2424 if (NULL == (result = DBselect(
2425 "select a.actionid,o.recovery"
2426 " from actions a"
2427 " left join operations o"
2428 " on a.actionid=o.actionid"
2429 " where a.status=%d"
2430 " group by a.actionid,o.recovery"
2431 " order by a.actionid",
2432 ACTION_STATUS_ACTIVE)))
2433 {
2434 return FAIL;
2435 }
2436
2437 dbsync_prepare(sync, 2, NULL);
2438
2439 while (NULL != (dbrow = DBfetch(result)))
2440 {
2441 ZBX_STR2UINT64(rowid, dbrow[0]);
2442
2443 if (actionid != rowid)
2444 {
2445 dbsync_compare_action_op(sync, actionid, opflags);
2446 actionid = rowid;
2447 opflags = ZBX_ACTION_OPCLASS_NONE;
2448 }
2449
2450 if (SUCCEED == DBis_null(dbrow[1]))
2451 continue;
2452
2453 switch (atoi(dbrow[1]))
2454 {
2455 case 0:
2456 opflags |= ZBX_ACTION_OPCLASS_NORMAL;
2457 break;
2458 case 1:
2459 opflags |= ZBX_ACTION_OPCLASS_RECOVERY;
2460 break;
2461 case 2:
2462 opflags |= ZBX_ACTION_OPCLASS_ACKNOWLEDGE;
2463 break;
2464 }
2465 }
2466
2467 dbsync_compare_action_op(sync, actionid, opflags);
2468
2469 DBfree_result(result);
2470
2471 return SUCCEED;
2472 }
2473
2474
2475 /******************************************************************************
2476 * *
2477 * Function: dbsync_compare_action_condition *
2478 * *
2479 * Purpose: compares conditions table row with cached configuration data *
2480 * *
2481 * Parameter: condition - [IN] the cached action condition *
2482 * row - [IN] the database row *
2483 * *
2484 * Return value: SUCCEED - the row matches configuration data *
2485 * FAIL - otherwise *
2486 * *
2487 ******************************************************************************/
dbsync_compare_action_condition(const zbx_dc_action_condition_t * condition,const DB_ROW dbrow)2488 static int dbsync_compare_action_condition(const zbx_dc_action_condition_t *condition, const DB_ROW dbrow)
2489 {
2490 if (FAIL == dbsync_compare_uchar(dbrow[2], condition->conditiontype))
2491 return FAIL;
2492
2493 if (FAIL == dbsync_compare_uchar(dbrow[3], condition->op))
2494 return FAIL;
2495
2496 if (FAIL == dbsync_compare_str(dbrow[4], condition->value))
2497 return FAIL;
2498
2499 if (FAIL == dbsync_compare_str(dbrow[5], condition->value2))
2500 return FAIL;
2501
2502 return SUCCEED;
2503 }
2504
2505 /******************************************************************************
2506 * *
2507 * Function: zbx_dbsync_compare_action_conditions *
2508 * *
2509 * Purpose: compares conditions table with cached configuration data *
2510 * *
2511 * Parameter: cache - [IN] the configuration cache *
2512 * sync - [OUT] the changeset *
2513 * *
2514 * Return value: SUCCEED - the changeset was successfully calculated *
2515 * FAIL - otherwise *
2516 * *
2517 ******************************************************************************/
zbx_dbsync_compare_action_conditions(zbx_dbsync_t * sync)2518 int zbx_dbsync_compare_action_conditions(zbx_dbsync_t *sync)
2519 {
2520 DB_ROW dbrow;
2521 DB_RESULT result;
2522 zbx_hashset_t ids;
2523 zbx_hashset_iter_t iter;
2524 zbx_uint64_t rowid;
2525 zbx_dc_action_condition_t *condition;
2526
2527 if (NULL == (result = DBselect(
2528 "select c.conditionid,c.actionid,c.conditiontype,c.operator,c.value,c.value2"
2529 " from conditions c,actions a"
2530 " where c.actionid=a.actionid"
2531 " and a.status=%d",
2532 ACTION_STATUS_ACTIVE)))
2533 {
2534 return FAIL;
2535 }
2536
2537 dbsync_prepare(sync, 6, NULL);
2538
2539 if (ZBX_DBSYNC_INIT == sync->mode)
2540 {
2541 sync->dbresult = result;
2542 return SUCCEED;
2543 }
2544
2545 zbx_hashset_create(&ids, dbsync_env.cache->action_conditions.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2546 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2547
2548 while (NULL != (dbrow = DBfetch(result)))
2549 {
2550 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2551
2552 ZBX_STR2UINT64(rowid, dbrow[0]);
2553 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2554
2555 if (NULL == (condition = (zbx_dc_action_condition_t *)zbx_hashset_search(
2556 &dbsync_env.cache->action_conditions, &rowid)))
2557 {
2558 tag = ZBX_DBSYNC_ROW_ADD;
2559 }
2560 else if (FAIL == dbsync_compare_action_condition(condition, dbrow))
2561 tag = ZBX_DBSYNC_ROW_UPDATE;
2562
2563 if (ZBX_DBSYNC_ROW_NONE != tag)
2564 dbsync_add_row(sync, rowid, tag, dbrow);
2565 }
2566
2567 zbx_hashset_iter_reset(&dbsync_env.cache->action_conditions, &iter);
2568 while (NULL != (condition = (zbx_dc_action_condition_t *)zbx_hashset_iter_next(&iter)))
2569 {
2570 if (NULL == zbx_hashset_search(&ids, &condition->conditionid))
2571 dbsync_add_row(sync, condition->conditionid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2572 }
2573
2574 zbx_hashset_destroy(&ids);
2575 DBfree_result(result);
2576
2577 return SUCCEED;
2578 }
2579
2580 /******************************************************************************
2581 * *
2582 * Function: dbsync_compare_trigger_tag *
2583 * *
2584 * Purpose: compares trigger tags table row with cached configuration data *
2585 * *
2586 * Parameter: tag - [IN] the cached trigger tag *
2587 * row - [IN] the database row *
2588 * *
2589 * Return value: SUCCEED - the row matches configuration data *
2590 * FAIL - otherwise *
2591 * *
2592 ******************************************************************************/
dbsync_compare_trigger_tag(const zbx_dc_trigger_tag_t * tag,const DB_ROW dbrow)2593 static int dbsync_compare_trigger_tag(const zbx_dc_trigger_tag_t *tag, const DB_ROW dbrow)
2594 {
2595 if (FAIL == dbsync_compare_uint64(dbrow[1], tag->triggerid))
2596 return FAIL;
2597
2598 if (FAIL == dbsync_compare_str(dbrow[2], tag->tag))
2599 return FAIL;
2600
2601 if (FAIL == dbsync_compare_str(dbrow[3], tag->value))
2602 return FAIL;
2603
2604 return SUCCEED;
2605 }
2606
2607 /******************************************************************************
2608 * *
2609 * Function: zbx_dbsync_compare_trigger_tags *
2610 * *
2611 * Purpose: compares trigger tags table with cached configuration data *
2612 * *
2613 * Parameter: cache - [IN] the configuration cache *
2614 * sync - [OUT] the changeset *
2615 * *
2616 * Return value: SUCCEED - the changeset was successfully calculated *
2617 * FAIL - otherwise *
2618 * *
2619 ******************************************************************************/
zbx_dbsync_compare_trigger_tags(zbx_dbsync_t * sync)2620 int zbx_dbsync_compare_trigger_tags(zbx_dbsync_t *sync)
2621 {
2622 DB_ROW dbrow;
2623 DB_RESULT result;
2624 zbx_hashset_t ids;
2625 zbx_hashset_iter_t iter;
2626 zbx_uint64_t rowid;
2627 zbx_dc_trigger_tag_t *trigger_tag;
2628
2629 if (NULL == (result = DBselect(
2630 "select distinct tt.triggertagid,tt.triggerid,tt.tag,tt.value"
2631 " from trigger_tag tt,triggers t,hosts h,items i,functions f"
2632 " where t.triggerid=tt.triggerid"
2633 " and t.flags<>%d"
2634 " and h.hostid=i.hostid"
2635 " and i.itemid=f.itemid"
2636 " and f.triggerid=tt.triggerid"
2637 " and h.status in (%d,%d)",
2638 ZBX_FLAG_DISCOVERY_PROTOTYPE, HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED)))
2639 {
2640 return FAIL;
2641 }
2642
2643 dbsync_prepare(sync, 4, NULL);
2644
2645 if (ZBX_DBSYNC_INIT == sync->mode)
2646 {
2647 sync->dbresult = result;
2648 return SUCCEED;
2649 }
2650
2651 zbx_hashset_create(&ids, dbsync_env.cache->trigger_tags.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2652 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2653
2654 while (NULL != (dbrow = DBfetch(result)))
2655 {
2656 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2657
2658 ZBX_STR2UINT64(rowid, dbrow[0]);
2659 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2660
2661 if (NULL == (trigger_tag = (zbx_dc_trigger_tag_t *)zbx_hashset_search(&dbsync_env.cache->trigger_tags,
2662 &rowid)))
2663 {
2664 tag = ZBX_DBSYNC_ROW_ADD;
2665 }
2666 else if (FAIL == dbsync_compare_trigger_tag(trigger_tag, dbrow))
2667 tag = ZBX_DBSYNC_ROW_UPDATE;
2668
2669 if (ZBX_DBSYNC_ROW_NONE != tag)
2670 dbsync_add_row(sync, rowid, tag, dbrow);
2671 }
2672
2673 zbx_hashset_iter_reset(&dbsync_env.cache->trigger_tags, &iter);
2674 while (NULL != (trigger_tag = (zbx_dc_trigger_tag_t *)zbx_hashset_iter_next(&iter)))
2675 {
2676 if (NULL == zbx_hashset_search(&ids, &trigger_tag->triggertagid))
2677 dbsync_add_row(sync, trigger_tag->triggertagid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2678 }
2679
2680 zbx_hashset_destroy(&ids);
2681 DBfree_result(result);
2682
2683 return SUCCEED;
2684 }
2685
2686 /******************************************************************************
2687 * *
2688 * Function: dbsync_compare_correlation *
2689 * *
2690 * Purpose: compares correlation table row with cached configuration data *
2691 * *
2692 * Parameter: correlation - [IN] the cached correlation rule *
2693 * row - [IN] the database row *
2694 * *
2695 * Return value: SUCCEED - the row matches configuration data *
2696 * FAIL - otherwise *
2697 * *
2698 ******************************************************************************/
dbsync_compare_correlation(const zbx_dc_correlation_t * correlation,const DB_ROW dbrow)2699 static int dbsync_compare_correlation(const zbx_dc_correlation_t *correlation, const DB_ROW dbrow)
2700 {
2701 if (FAIL == dbsync_compare_str(dbrow[1], correlation->name))
2702 return FAIL;
2703
2704 if (FAIL == dbsync_compare_uchar(dbrow[2], correlation->evaltype))
2705 return FAIL;
2706
2707 if (FAIL == dbsync_compare_str(dbrow[3], correlation->formula))
2708 return FAIL;
2709
2710 return SUCCEED;
2711 }
2712
2713 /******************************************************************************
2714 * *
2715 * Function: zbx_dbsync_compare_correlations *
2716 * *
2717 * Purpose: compares correlation table with cached configuration data *
2718 * *
2719 * Parameter: cache - [IN] the configuration cache *
2720 * sync - [OUT] the changeset *
2721 * *
2722 * Return value: SUCCEED - the changeset was successfully calculated *
2723 * FAIL - otherwise *
2724 * *
2725 ******************************************************************************/
zbx_dbsync_compare_correlations(zbx_dbsync_t * sync)2726 int zbx_dbsync_compare_correlations(zbx_dbsync_t *sync)
2727 {
2728 DB_ROW dbrow;
2729 DB_RESULT result;
2730 zbx_hashset_t ids;
2731 zbx_hashset_iter_t iter;
2732 zbx_uint64_t rowid;
2733 zbx_dc_correlation_t *correlation;
2734
2735 if (NULL == (result = DBselect(
2736 "select correlationid,name,evaltype,formula"
2737 " from correlation"
2738 " where status=%d",
2739 ZBX_CORRELATION_ENABLED)))
2740 {
2741 return FAIL;
2742 }
2743
2744 dbsync_prepare(sync, 4, NULL);
2745
2746 if (ZBX_DBSYNC_INIT == sync->mode)
2747 {
2748 sync->dbresult = result;
2749 return SUCCEED;
2750 }
2751
2752 zbx_hashset_create(&ids, dbsync_env.cache->correlations.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2753 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2754
2755 while (NULL != (dbrow = DBfetch(result)))
2756 {
2757 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2758
2759 ZBX_STR2UINT64(rowid, dbrow[0]);
2760 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2761
2762 if (NULL == (correlation = (zbx_dc_correlation_t *)zbx_hashset_search(&dbsync_env.cache->correlations,
2763 &rowid)))
2764 {
2765 tag = ZBX_DBSYNC_ROW_ADD;
2766 }
2767 else if (FAIL == dbsync_compare_correlation(correlation, dbrow))
2768 tag = ZBX_DBSYNC_ROW_UPDATE;
2769
2770 if (ZBX_DBSYNC_ROW_NONE != tag)
2771 dbsync_add_row(sync, rowid, tag, dbrow);
2772 }
2773
2774 zbx_hashset_iter_reset(&dbsync_env.cache->correlations, &iter);
2775 while (NULL != (correlation = (zbx_dc_correlation_t *)zbx_hashset_iter_next(&iter)))
2776 {
2777 if (NULL == zbx_hashset_search(&ids, &correlation->correlationid))
2778 dbsync_add_row(sync, correlation->correlationid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2779 }
2780
2781 zbx_hashset_destroy(&ids);
2782 DBfree_result(result);
2783
2784 return SUCCEED;
2785 }
2786
2787 /******************************************************************************
2788 * *
2789 * Function: dbsync_compare_corr_condition *
2790 * *
2791 * Purpose: compares correlation condition tables dbrow with cached *
2792 * configuration data *
2793 * *
2794 * Parameter: corr_condition - [IN] the cached correlation condition *
2795 * row - [IN] the database row *
2796 * *
2797 * Return value: SUCCEED - the row matches configuration data *
2798 * FAIL - otherwise *
2799 * *
2800 ******************************************************************************/
dbsync_compare_corr_condition(const zbx_dc_corr_condition_t * corr_condition,const DB_ROW dbrow)2801 static int dbsync_compare_corr_condition(const zbx_dc_corr_condition_t *corr_condition, const DB_ROW dbrow)
2802 {
2803 if (FAIL == dbsync_compare_uint64(dbrow[1], corr_condition->correlationid))
2804 return FAIL;
2805
2806 if (FAIL == dbsync_compare_uchar(dbrow[2], corr_condition->type))
2807 return FAIL;
2808
2809 switch (corr_condition->type)
2810 {
2811 case ZBX_CORR_CONDITION_OLD_EVENT_TAG:
2812 /* break; is not missing here */
2813 case ZBX_CORR_CONDITION_NEW_EVENT_TAG:
2814 if (FAIL == dbsync_compare_str(dbrow[3], corr_condition->data.tag.tag))
2815 return FAIL;
2816 break;
2817 case ZBX_CORR_CONDITION_OLD_EVENT_TAG_VALUE:
2818 /* break; is not missing here */
2819 case ZBX_CORR_CONDITION_NEW_EVENT_TAG_VALUE:
2820 if (FAIL == dbsync_compare_str(dbrow[4], corr_condition->data.tag_value.tag))
2821 return FAIL;
2822 if (FAIL == dbsync_compare_str(dbrow[5], corr_condition->data.tag_value.value))
2823 return FAIL;
2824 if (FAIL == dbsync_compare_uchar(dbrow[6], corr_condition->data.tag_value.op))
2825 return FAIL;
2826 break;
2827 case ZBX_CORR_CONDITION_NEW_EVENT_HOSTGROUP:
2828 if (FAIL == dbsync_compare_uint64(dbrow[7], corr_condition->data.group.groupid))
2829 return FAIL;
2830 if (FAIL == dbsync_compare_uchar(dbrow[8], corr_condition->data.group.op))
2831 return FAIL;
2832 break;
2833 case ZBX_CORR_CONDITION_EVENT_TAG_PAIR:
2834 if (FAIL == dbsync_compare_str(dbrow[9], corr_condition->data.tag_pair.oldtag))
2835 return FAIL;
2836 if (FAIL == dbsync_compare_str(dbrow[10], corr_condition->data.tag_pair.newtag))
2837 return FAIL;
2838 break;
2839 }
2840 return SUCCEED;
2841 }
2842
2843 /******************************************************************************
2844 * *
2845 * Function: zbx_dbsync_compare_corr_conditions *
2846 * *
2847 * Purpose: compares correlation condition tables with cached configuration *
2848 * data *
2849 * *
2850 * Parameter: cache - [IN] the configuration cache *
2851 * sync - [OUT] the changeset *
2852 * *
2853 * Return value: SUCCEED - the changeset was successfully calculated *
2854 * FAIL - otherwise *
2855 * *
2856 ******************************************************************************/
zbx_dbsync_compare_corr_conditions(zbx_dbsync_t * sync)2857 int zbx_dbsync_compare_corr_conditions(zbx_dbsync_t *sync)
2858 {
2859 DB_ROW dbrow;
2860 DB_RESULT result;
2861 zbx_hashset_t ids;
2862 zbx_hashset_iter_t iter;
2863 zbx_uint64_t rowid;
2864 zbx_dc_corr_condition_t *corr_condition;
2865
2866 if (NULL == (result = DBselect(
2867 "select cc.corr_conditionid,cc.correlationid,cc.type,cct.tag,cctv.tag,cctv.value,cctv.operator,"
2868 " ccg.groupid,ccg.operator,cctp.oldtag,cctp.newtag"
2869 " from correlation c,corr_condition cc"
2870 " left join corr_condition_tag cct"
2871 " on cct.corr_conditionid=cc.corr_conditionid"
2872 " left join corr_condition_tagvalue cctv"
2873 " on cctv.corr_conditionid=cc.corr_conditionid"
2874 " left join corr_condition_group ccg"
2875 " on ccg.corr_conditionid=cc.corr_conditionid"
2876 " left join corr_condition_tagpair cctp"
2877 " on cctp.corr_conditionid=cc.corr_conditionid"
2878 " where c.correlationid=cc.correlationid"
2879 " and c.status=%d",
2880 ZBX_CORRELATION_ENABLED)))
2881 {
2882 return FAIL;
2883 }
2884
2885 dbsync_prepare(sync, 11, NULL);
2886
2887 if (ZBX_DBSYNC_INIT == sync->mode)
2888 {
2889 sync->dbresult = result;
2890 return SUCCEED;
2891 }
2892
2893 zbx_hashset_create(&ids, dbsync_env.cache->corr_conditions.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2894 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2895
2896 while (NULL != (dbrow = DBfetch(result)))
2897 {
2898 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
2899
2900 ZBX_STR2UINT64(rowid, dbrow[0]);
2901 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
2902
2903 if (NULL == (corr_condition = (zbx_dc_corr_condition_t *)zbx_hashset_search(
2904 &dbsync_env.cache->corr_conditions, &rowid)))
2905 {
2906 tag = ZBX_DBSYNC_ROW_ADD;
2907 }
2908 else if (FAIL == dbsync_compare_corr_condition(corr_condition, dbrow))
2909 tag = ZBX_DBSYNC_ROW_UPDATE;
2910
2911 if (ZBX_DBSYNC_ROW_NONE != tag)
2912 dbsync_add_row(sync, rowid, tag, dbrow);
2913 }
2914
2915 zbx_hashset_iter_reset(&dbsync_env.cache->corr_conditions, &iter);
2916 while (NULL != (corr_condition = (zbx_dc_corr_condition_t *)zbx_hashset_iter_next(&iter)))
2917 {
2918 if (NULL == zbx_hashset_search(&ids, &corr_condition->corr_conditionid))
2919 dbsync_add_row(sync, corr_condition->corr_conditionid, ZBX_DBSYNC_ROW_REMOVE, NULL);
2920 }
2921
2922 zbx_hashset_destroy(&ids);
2923 DBfree_result(result);
2924
2925 return SUCCEED;
2926 }
2927
2928
2929 /******************************************************************************
2930 * *
2931 * Function: dbsync_compare_corr_operation *
2932 * *
2933 * Purpose: compares correlation operation tables dbrow with cached *
2934 * configuration data *
2935 * *
2936 * Parameter: corr_operation - [IN] the cached correlation operation *
2937 * row - [IN] the database row *
2938 * *
2939 * Return value: SUCCEED - the row matches configuration data *
2940 * FAIL - otherwise *
2941 * *
2942 ******************************************************************************/
dbsync_compare_corr_operation(const zbx_dc_corr_operation_t * corr_operation,const DB_ROW dbrow)2943 static int dbsync_compare_corr_operation(const zbx_dc_corr_operation_t *corr_operation, const DB_ROW dbrow)
2944 {
2945 if (FAIL == dbsync_compare_uint64(dbrow[1], corr_operation->correlationid))
2946 return FAIL;
2947
2948 if (FAIL == dbsync_compare_uchar(dbrow[2], corr_operation->type))
2949 return FAIL;
2950
2951 return SUCCEED;
2952 }
2953
2954 /******************************************************************************
2955 * *
2956 * Function: zbx_dbsync_compare_corr_operations *
2957 * *
2958 * Purpose: compares correlation operation tables with cached configuration *
2959 * data *
2960 * *
2961 * Parameter: cache - [IN] the configuration cache *
2962 * sync - [OUT] the changeset *
2963 * *
2964 * Return value: SUCCEED - the changeset was successfully calculated *
2965 * FAIL - otherwise *
2966 * *
2967 ******************************************************************************/
zbx_dbsync_compare_corr_operations(zbx_dbsync_t * sync)2968 int zbx_dbsync_compare_corr_operations(zbx_dbsync_t *sync)
2969 {
2970 DB_ROW dbrow;
2971 DB_RESULT result;
2972 zbx_hashset_t ids;
2973 zbx_hashset_iter_t iter;
2974 zbx_uint64_t rowid;
2975 zbx_dc_corr_operation_t *corr_operation;
2976
2977 if (NULL == (result = DBselect(
2978 "select co.corr_operationid,co.correlationid,co.type"
2979 " from correlation c,corr_operation co"
2980 " where c.correlationid=co.correlationid"
2981 " and c.status=%d",
2982 ZBX_CORRELATION_ENABLED)))
2983 {
2984 return FAIL;
2985 }
2986
2987 dbsync_prepare(sync, 3, NULL);
2988
2989 if (ZBX_DBSYNC_INIT == sync->mode)
2990 {
2991 sync->dbresult = result;
2992 return SUCCEED;
2993 }
2994
2995 zbx_hashset_create(&ids, dbsync_env.cache->corr_operations.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
2996 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
2997
2998 while (NULL != (dbrow = DBfetch(result)))
2999 {
3000 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3001
3002 ZBX_STR2UINT64(rowid, dbrow[0]);
3003 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3004
3005 if (NULL == (corr_operation = (zbx_dc_corr_operation_t *)zbx_hashset_search(
3006 &dbsync_env.cache->corr_operations, &rowid)))
3007 {
3008 tag = ZBX_DBSYNC_ROW_ADD;
3009 }
3010 else if (FAIL == dbsync_compare_corr_operation(corr_operation, dbrow))
3011 tag = ZBX_DBSYNC_ROW_UPDATE;
3012
3013 if (ZBX_DBSYNC_ROW_NONE != tag)
3014 dbsync_add_row(sync, rowid, tag, dbrow);
3015 }
3016
3017 zbx_hashset_iter_reset(&dbsync_env.cache->corr_operations, &iter);
3018 while (NULL != (corr_operation = (zbx_dc_corr_operation_t *)zbx_hashset_iter_next(&iter)))
3019 {
3020 if (NULL == zbx_hashset_search(&ids, &corr_operation->corr_operationid))
3021 dbsync_add_row(sync, corr_operation->corr_operationid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3022 }
3023
3024 zbx_hashset_destroy(&ids);
3025 DBfree_result(result);
3026
3027 return SUCCEED;
3028 }
3029
3030 /******************************************************************************
3031 * *
3032 * Function: dbsync_compare_host_group *
3033 * *
3034 * Purpose: compares host group table row with cached configuration data *
3035 * *
3036 * Parameter: group - [IN] the cached host group *
3037 * row - [IN] the database row *
3038 * *
3039 * Return value: SUCCEED - the row matches configuration data *
3040 * FAIL - otherwise *
3041 * *
3042 ******************************************************************************/
dbsync_compare_host_group(const zbx_dc_hostgroup_t * group,const DB_ROW dbrow)3043 static int dbsync_compare_host_group(const zbx_dc_hostgroup_t *group, const DB_ROW dbrow)
3044 {
3045 if (FAIL == dbsync_compare_str(dbrow[1], group->name))
3046 return FAIL;
3047
3048 return SUCCEED;
3049 }
3050
3051 /******************************************************************************
3052 * *
3053 * Function: zbx_dbsync_compare_host_groups *
3054 * *
3055 * Purpose: compares host groups table with cached configuration data *
3056 * *
3057 * Parameter: cache - [IN] the configuration cache *
3058 * sync - [OUT] the changeset *
3059 * *
3060 * Return value: SUCCEED - the changeset was successfully calculated *
3061 * FAIL - otherwise *
3062 * *
3063 ******************************************************************************/
zbx_dbsync_compare_host_groups(zbx_dbsync_t * sync)3064 int zbx_dbsync_compare_host_groups(zbx_dbsync_t *sync)
3065 {
3066 DB_ROW dbrow;
3067 DB_RESULT result;
3068 zbx_hashset_t ids;
3069 zbx_hashset_iter_t iter;
3070 zbx_uint64_t rowid;
3071 zbx_dc_hostgroup_t *group;
3072
3073 if (NULL == (result = DBselect("select groupid,name from hstgrp")))
3074 return FAIL;
3075
3076 dbsync_prepare(sync, 2, NULL);
3077
3078 if (ZBX_DBSYNC_INIT == sync->mode)
3079 {
3080 sync->dbresult = result;
3081 return SUCCEED;
3082 }
3083
3084 zbx_hashset_create(&ids, dbsync_env.cache->hostgroups.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
3085 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
3086
3087 while (NULL != (dbrow = DBfetch(result)))
3088 {
3089 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3090
3091 ZBX_STR2UINT64(rowid, dbrow[0]);
3092 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3093
3094 if (NULL == (group = (zbx_dc_hostgroup_t *)zbx_hashset_search(&dbsync_env.cache->hostgroups, &rowid)))
3095 tag = ZBX_DBSYNC_ROW_ADD;
3096 else if (FAIL == dbsync_compare_host_group(group, dbrow))
3097 tag = ZBX_DBSYNC_ROW_UPDATE;
3098
3099 if (ZBX_DBSYNC_ROW_NONE != tag)
3100 dbsync_add_row(sync, rowid, tag, dbrow);
3101 }
3102
3103 zbx_hashset_iter_reset(&dbsync_env.cache->hostgroups, &iter);
3104 while (NULL != (group = (zbx_dc_hostgroup_t *)zbx_hashset_iter_next(&iter)))
3105 {
3106 if (NULL == zbx_hashset_search(&ids, &group->groupid))
3107 dbsync_add_row(sync, group->groupid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3108 }
3109
3110 zbx_hashset_destroy(&ids);
3111 DBfree_result(result);
3112
3113 return SUCCEED;
3114 }
3115
3116 /******************************************************************************
3117 * *
3118 * Function: dbsync_item_pp_preproc_row *
3119 * *
3120 * Purpose: applies necessary preprocessing before row is compared/used *
3121 * *
3122 * Parameter: row - [IN] the row to preprocess *
3123 * *
3124 * Return value: the preprocessed row of item_preproc table *
3125 * *
3126 * Comments: The row preprocessing can be used to expand user macros in *
3127 * some columns. *
3128 * *
3129 ******************************************************************************/
dbsync_item_pp_preproc_row(char ** row)3130 static char **dbsync_item_pp_preproc_row(char **row)
3131 {
3132 zbx_uint64_t hostid;
3133
3134 if (SUCCEED == dbsync_check_row_macros(row, 3))
3135 {
3136 /* get associated host identifier */
3137 ZBX_STR2UINT64(hostid, row[5]);
3138
3139 /* expand user macros */
3140 row[3] = zbx_dc_expand_user_macros(row[3], &hostid, 1, NULL);
3141 }
3142
3143 return row;
3144 }
3145
3146 /******************************************************************************
3147 * *
3148 * Function: dbsync_compare_item_preproc *
3149 * *
3150 * Purpose: compares item preproc table row with cached configuration data *
3151 * *
3152 * Parameter: group - [IN] the cached item preprocessing operation *
3153 * row - [IN] the database row *
3154 * *
3155 * Return value: SUCCEED - the row matches configuration data *
3156 * FAIL - otherwise *
3157 * *
3158 ******************************************************************************/
dbsync_compare_item_preproc(const zbx_dc_preproc_op_t * preproc,const DB_ROW dbrow)3159 static int dbsync_compare_item_preproc(const zbx_dc_preproc_op_t *preproc, const DB_ROW dbrow)
3160 {
3161 if (FAIL == dbsync_compare_uint64(dbrow[1], preproc->itemid))
3162 return FAIL;
3163
3164 if (FAIL == dbsync_compare_uchar(dbrow[2], preproc->type))
3165 return FAIL;
3166
3167 if (FAIL == dbsync_compare_str(dbrow[3], preproc->params))
3168 return FAIL;
3169
3170 if (FAIL == dbsync_compare_int(dbrow[4], preproc->step))
3171 return FAIL;
3172
3173 return SUCCEED;
3174 }
3175
3176 /******************************************************************************
3177 * *
3178 * Function: zbx_dbsync_compare_item_preprocessing *
3179 * *
3180 * Purpose: compares item preproc tables with cached configuration data *
3181 * *
3182 * Parameter: cache - [IN] the configuration cache *
3183 * sync - [OUT] the changeset *
3184 * *
3185 * Return value: SUCCEED - the changeset was successfully calculated *
3186 * FAIL - otherwise *
3187 * *
3188 ******************************************************************************/
zbx_dbsync_compare_item_preprocs(zbx_dbsync_t * sync)3189 int zbx_dbsync_compare_item_preprocs(zbx_dbsync_t *sync)
3190 {
3191 DB_ROW dbrow;
3192 DB_RESULT result;
3193 zbx_hashset_t ids;
3194 zbx_hashset_iter_t iter;
3195 zbx_uint64_t rowid;
3196 zbx_dc_preproc_op_t *preproc;
3197 char **row;
3198
3199 if (NULL == (result = DBselect(
3200 "select pp.item_preprocid,pp.itemid,pp.type,pp.params,pp.step,i.hostid"
3201 " from item_preproc pp,items i,hosts h"
3202 " where pp.itemid=i.itemid"
3203 " and i.hostid=h.hostid"
3204 " and h.status in (%d,%d)"
3205 " and i.flags<>%d"
3206 " order by pp.itemid",
3207 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE)))
3208 {
3209 return FAIL;
3210 }
3211
3212 dbsync_prepare(sync, 6, dbsync_item_pp_preproc_row);
3213
3214 if (ZBX_DBSYNC_INIT == sync->mode)
3215 {
3216 sync->dbresult = result;
3217 return SUCCEED;
3218 }
3219
3220 zbx_hashset_create(&ids, dbsync_env.cache->hostgroups.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
3221 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
3222
3223 while (NULL != (dbrow = DBfetch(result)))
3224 {
3225 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3226 ZBX_STR2UINT64(rowid, dbrow[0]);
3227 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3228
3229 row = dbsync_preproc_row(sync, dbrow);
3230
3231 if (NULL == (preproc = (zbx_dc_preproc_op_t *)zbx_hashset_search(&dbsync_env.cache->preprocops,
3232 &rowid)))
3233 {
3234 tag = ZBX_DBSYNC_ROW_ADD;
3235 }
3236 else if (FAIL == dbsync_compare_item_preproc(preproc, row))
3237 tag = ZBX_DBSYNC_ROW_UPDATE;
3238
3239 if (ZBX_DBSYNC_ROW_NONE != tag)
3240 dbsync_add_row(sync, rowid, tag, row);
3241 }
3242
3243 zbx_hashset_iter_reset(&dbsync_env.cache->preprocops, &iter);
3244 while (NULL != (preproc = (zbx_dc_preproc_op_t *)zbx_hashset_iter_next(&iter)))
3245 {
3246 if (NULL == zbx_hashset_search(&ids, &preproc->item_preprocid))
3247 dbsync_add_row(sync, preproc->item_preprocid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3248 }
3249
3250 zbx_hashset_destroy(&ids);
3251 DBfree_result(result);
3252
3253 return SUCCEED;
3254 }
3255
3256 /******************************************************************************
3257 * *
3258 * Function: dbsync_compare_maintenance *
3259 * *
3260 * Purpose: compares maintenance table row with cached configuration data *
3261 * *
3262 * Parameter: maintenance - [IN] the cached maintenance data *
3263 * row - [IN] the database row *
3264 * *
3265 * Return value: SUCCEED - the row matches configuration data *
3266 * FAIL - otherwise *
3267 * *
3268 ******************************************************************************/
dbsync_compare_maintenance(const zbx_dc_maintenance_t * maintenance,const DB_ROW dbrow)3269 static int dbsync_compare_maintenance(const zbx_dc_maintenance_t *maintenance, const DB_ROW dbrow)
3270 {
3271 if (FAIL == dbsync_compare_uchar(dbrow[1], maintenance->type))
3272 return FAIL;
3273
3274 if (FAIL == dbsync_compare_int(dbrow[2], maintenance->active_since))
3275 return FAIL;
3276
3277 if (FAIL == dbsync_compare_int(dbrow[3], maintenance->active_until))
3278 return FAIL;
3279
3280 if (FAIL == dbsync_compare_uchar(dbrow[4], maintenance->tags_evaltype))
3281 return FAIL;
3282
3283 return SUCCEED;
3284 }
3285
3286 /******************************************************************************
3287 * *
3288 * Function: zbx_dbsync_compare_maintenances *
3289 * *
3290 * Purpose: compares maintenances table with cached configuration data *
3291 * *
3292 * Parameter: cache - [IN] the configuration cache *
3293 * sync - [OUT] the changeset *
3294 * *
3295 * Return value: SUCCEED - the changeset was successfully calculated *
3296 * FAIL - otherwise *
3297 * *
3298 ******************************************************************************/
zbx_dbsync_compare_maintenances(zbx_dbsync_t * sync)3299 int zbx_dbsync_compare_maintenances(zbx_dbsync_t *sync)
3300 {
3301 DB_ROW dbrow;
3302 DB_RESULT result;
3303 zbx_hashset_t ids;
3304 zbx_hashset_iter_t iter;
3305 zbx_uint64_t rowid;
3306 zbx_dc_maintenance_t *maintenance;
3307
3308 if (NULL == (result = DBselect("select maintenanceid,maintenance_type,active_since,active_till,tags_evaltype"
3309 " from maintenances")))
3310 {
3311 return FAIL;
3312 }
3313
3314 dbsync_prepare(sync, 5, NULL);
3315
3316 if (ZBX_DBSYNC_INIT == sync->mode)
3317 {
3318 sync->dbresult = result;
3319 return SUCCEED;
3320 }
3321
3322 zbx_hashset_create(&ids, dbsync_env.cache->maintenances.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
3323 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
3324
3325 while (NULL != (dbrow = DBfetch(result)))
3326 {
3327 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3328
3329 ZBX_STR2UINT64(rowid, dbrow[0]);
3330 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3331
3332 maintenance = (zbx_dc_maintenance_t *)zbx_hashset_search(&dbsync_env.cache->maintenances, &rowid);
3333
3334 if (NULL == maintenance)
3335 tag = ZBX_DBSYNC_ROW_ADD;
3336 else if (FAIL == dbsync_compare_maintenance(maintenance, dbrow))
3337 tag = ZBX_DBSYNC_ROW_UPDATE;
3338
3339 if (ZBX_DBSYNC_ROW_NONE != tag)
3340 dbsync_add_row(sync, rowid, tag, dbrow);
3341 }
3342
3343 zbx_hashset_iter_reset(&dbsync_env.cache->maintenances, &iter);
3344 while (NULL != (maintenance = (zbx_dc_maintenance_t *)zbx_hashset_iter_next(&iter)))
3345 {
3346 if (NULL == zbx_hashset_search(&ids, &maintenance->maintenanceid))
3347 dbsync_add_row(sync, maintenance->maintenanceid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3348 }
3349
3350 zbx_hashset_destroy(&ids);
3351 DBfree_result(result);
3352
3353 return SUCCEED;
3354 }
3355
3356 /******************************************************************************
3357 * *
3358 * Function: dbsync_compare_maintenance_tag *
3359 * *
3360 * Purpose: compares maintenance_tag table row with cached configuration data *
3361 * *
3362 * Parameter: maintenance_tag - [IN] the cached maintenance tag *
3363 * row - [IN] the database row *
3364 * *
3365 * Return value: SUCCEED - the row matches configuration data *
3366 * FAIL - otherwise *
3367 * *
3368 ******************************************************************************/
dbsync_compare_maintenance_tag(const zbx_dc_maintenance_tag_t * maintenance_tag,const DB_ROW dbrow)3369 static int dbsync_compare_maintenance_tag(const zbx_dc_maintenance_tag_t *maintenance_tag, const DB_ROW dbrow)
3370 {
3371 if (FAIL == dbsync_compare_int(dbrow[2], maintenance_tag->op))
3372 return FAIL;
3373
3374 if (FAIL == dbsync_compare_str(dbrow[3], maintenance_tag->tag))
3375 return FAIL;
3376
3377 if (FAIL == dbsync_compare_str(dbrow[4], maintenance_tag->value))
3378 return FAIL;
3379
3380 return SUCCEED;
3381 }
3382
3383 /******************************************************************************
3384 * *
3385 * Function: zbx_dbsync_compare_maintenance_tags *
3386 * *
3387 * Purpose: compares maintenances table with cached configuration data *
3388 * *
3389 * Parameter: cache - [IN] the configuration cache *
3390 * sync - [OUT] the changeset *
3391 * *
3392 * Return value: SUCCEED - the changeset was successfully calculated *
3393 * FAIL - otherwise *
3394 * *
3395 ******************************************************************************/
zbx_dbsync_compare_maintenance_tags(zbx_dbsync_t * sync)3396 int zbx_dbsync_compare_maintenance_tags(zbx_dbsync_t *sync)
3397 {
3398 DB_ROW dbrow;
3399 DB_RESULT result;
3400 zbx_hashset_t ids;
3401 zbx_hashset_iter_t iter;
3402 zbx_uint64_t rowid;
3403 zbx_dc_maintenance_tag_t *maintenance_tag;
3404
3405 if (NULL == (result = DBselect("select maintenancetagid,maintenanceid,operator,tag,value"
3406 " from maintenance_tag")))
3407 {
3408 return FAIL;
3409 }
3410
3411 dbsync_prepare(sync, 5, NULL);
3412
3413 if (ZBX_DBSYNC_INIT == sync->mode)
3414 {
3415 sync->dbresult = result;
3416 return SUCCEED;
3417 }
3418
3419 zbx_hashset_create(&ids, dbsync_env.cache->maintenance_tags.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
3420 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
3421
3422 while (NULL != (dbrow = DBfetch(result)))
3423 {
3424 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3425
3426 ZBX_STR2UINT64(rowid, dbrow[0]);
3427 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3428
3429 maintenance_tag = (zbx_dc_maintenance_tag_t *)zbx_hashset_search(&dbsync_env.cache->maintenance_tags,
3430 &rowid);
3431
3432 if (NULL == maintenance_tag)
3433 tag = ZBX_DBSYNC_ROW_ADD;
3434 else if (FAIL == dbsync_compare_maintenance_tag(maintenance_tag, dbrow))
3435 tag = ZBX_DBSYNC_ROW_UPDATE;
3436
3437 if (ZBX_DBSYNC_ROW_NONE != tag)
3438 dbsync_add_row(sync, rowid, tag, dbrow);
3439 }
3440
3441 zbx_hashset_iter_reset(&dbsync_env.cache->maintenance_tags, &iter);
3442 while (NULL != (maintenance_tag = (zbx_dc_maintenance_tag_t *)zbx_hashset_iter_next(&iter)))
3443 {
3444 if (NULL == zbx_hashset_search(&ids, &maintenance_tag->maintenancetagid))
3445 dbsync_add_row(sync, maintenance_tag->maintenancetagid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3446 }
3447
3448 zbx_hashset_destroy(&ids);
3449 DBfree_result(result);
3450
3451 return SUCCEED;
3452 }
3453
3454 /******************************************************************************
3455 * *
3456 * Function: dbsync_compare_maintenance_period *
3457 * *
3458 * Purpose: compares maintenance_period table row with cached configuration *
3459 * dat *
3460 * *
3461 * Parameter: maintenance_period - [IN] the cached maintenance period *
3462 * row - [IN] the database row *
3463 * *
3464 * Return value: SUCCEED - the row matches configuration data *
3465 * FAIL - otherwise *
3466 * *
3467 ******************************************************************************/
dbsync_compare_maintenance_period(const zbx_dc_maintenance_period_t * period,const DB_ROW dbrow)3468 static int dbsync_compare_maintenance_period(const zbx_dc_maintenance_period_t *period, const DB_ROW dbrow)
3469 {
3470 if (FAIL == dbsync_compare_uchar(dbrow[1], period->type))
3471 return FAIL;
3472
3473 if (FAIL == dbsync_compare_int(dbrow[2], period->every))
3474 return FAIL;
3475
3476 if (FAIL == dbsync_compare_int(dbrow[3], period->month))
3477 return FAIL;
3478
3479 if (FAIL == dbsync_compare_int(dbrow[4], period->dayofweek))
3480 return FAIL;
3481
3482 if (FAIL == dbsync_compare_int(dbrow[5], period->day))
3483 return FAIL;
3484
3485 if (FAIL == dbsync_compare_int(dbrow[6], period->start_time))
3486 return FAIL;
3487
3488 if (FAIL == dbsync_compare_int(dbrow[7], period->period))
3489 return FAIL;
3490
3491 if (FAIL == dbsync_compare_int(dbrow[8], period->start_date))
3492 return FAIL;
3493
3494 return SUCCEED;
3495 }
3496
3497 /******************************************************************************
3498 * *
3499 * Function: zbx_dbsync_compare_maintenance_periods *
3500 * *
3501 * Purpose: compares timeperiods table with cached configuration data *
3502 * *
3503 * Parameter: cache - [IN] the configuration cache *
3504 * sync - [OUT] the changeset *
3505 * *
3506 * Return value: SUCCEED - the changeset was successfully calculated *
3507 * FAIL - otherwise *
3508 * *
3509 ******************************************************************************/
zbx_dbsync_compare_maintenance_periods(zbx_dbsync_t * sync)3510 int zbx_dbsync_compare_maintenance_periods(zbx_dbsync_t *sync)
3511 {
3512 DB_ROW dbrow;
3513 DB_RESULT result;
3514 zbx_hashset_t ids;
3515 zbx_hashset_iter_t iter;
3516 zbx_uint64_t rowid;
3517 zbx_dc_maintenance_period_t *period;
3518
3519 if (NULL == (result = DBselect("select t.timeperiodid,t.timeperiod_type,t.every,t.month,t.dayofweek,t.day,"
3520 "t.start_time,t.period,t.start_date,m.maintenanceid"
3521 " from maintenances_windows m,timeperiods t"
3522 " where t.timeperiodid=m.timeperiodid")))
3523 {
3524 return FAIL;
3525 }
3526
3527 dbsync_prepare(sync, 10, NULL);
3528
3529 if (ZBX_DBSYNC_INIT == sync->mode)
3530 {
3531 sync->dbresult = result;
3532 return SUCCEED;
3533 }
3534
3535 zbx_hashset_create(&ids, dbsync_env.cache->maintenance_periods.num_data, ZBX_DEFAULT_UINT64_HASH_FUNC,
3536 ZBX_DEFAULT_UINT64_COMPARE_FUNC);
3537
3538 while (NULL != (dbrow = DBfetch(result)))
3539 {
3540 unsigned char tag = ZBX_DBSYNC_ROW_NONE;
3541
3542 ZBX_STR2UINT64(rowid, dbrow[0]);
3543 zbx_hashset_insert(&ids, &rowid, sizeof(rowid));
3544
3545 period = (zbx_dc_maintenance_period_t *)zbx_hashset_search(&dbsync_env.cache->maintenance_periods,
3546 &rowid);
3547
3548 if (NULL == period)
3549 tag = ZBX_DBSYNC_ROW_ADD;
3550 else if (FAIL == dbsync_compare_maintenance_period(period, dbrow))
3551 tag = ZBX_DBSYNC_ROW_UPDATE;
3552
3553 if (ZBX_DBSYNC_ROW_NONE != tag)
3554 dbsync_add_row(sync, rowid, tag, dbrow);
3555 }
3556
3557 zbx_hashset_iter_reset(&dbsync_env.cache->maintenance_periods, &iter);
3558 while (NULL != (period = (zbx_dc_maintenance_period_t *)zbx_hashset_iter_next(&iter)))
3559 {
3560 if (NULL == zbx_hashset_search(&ids, &period->timeperiodid))
3561 dbsync_add_row(sync, period->timeperiodid, ZBX_DBSYNC_ROW_REMOVE, NULL);
3562 }
3563
3564 zbx_hashset_destroy(&ids);
3565 DBfree_result(result);
3566
3567 return SUCCEED;
3568 }
3569
3570 /******************************************************************************
3571 * *
3572 * Function: zbx_dbsync_compare_maintenance_groups *
3573 * *
3574 * Purpose: compares maintenances_groups table with cached configuration data *
3575 * *
3576 * Parameter: cache - [IN] the configuration cache *
3577 * sync - [OUT] the changeset *
3578 * *
3579 * Return value: SUCCEED - the changeset was successfully calculated *
3580 * FAIL - otherwise *
3581 * *
3582 ******************************************************************************/
zbx_dbsync_compare_maintenance_groups(zbx_dbsync_t * sync)3583 int zbx_dbsync_compare_maintenance_groups(zbx_dbsync_t *sync)
3584 {
3585 DB_ROW dbrow;
3586 DB_RESULT result;
3587 zbx_hashset_iter_t iter;
3588 zbx_dc_maintenance_t *maintenance;
3589 zbx_hashset_t mgroups;
3590 int i;
3591 zbx_uint64_pair_t mg_local, *mg;
3592 char maintenanceid_s[MAX_ID_LEN + 1], groupid_s[MAX_ID_LEN + 1];
3593 char *del_row[2] = {maintenanceid_s, groupid_s};
3594
3595 if (NULL == (result = DBselect("select maintenanceid,groupid from maintenances_groups order by maintenanceid")))
3596 return FAIL;
3597
3598 dbsync_prepare(sync, 2, NULL);
3599
3600 if (ZBX_DBSYNC_INIT == sync->mode)
3601 {
3602 sync->dbresult = result;
3603 return SUCCEED;
3604 }
3605
3606 zbx_hashset_create(&mgroups, 100, ZBX_DEFAULT_UINT64_PAIR_HASH_FUNC, ZBX_DEFAULT_UINT64_PAIR_COMPARE_FUNC);
3607
3608 /* index all maintenance->group links */
3609 zbx_hashset_iter_reset(&dbsync_env.cache->maintenances, &iter);
3610 while (NULL != (maintenance = (zbx_dc_maintenance_t *)zbx_hashset_iter_next(&iter)))
3611 {
3612 mg_local.first = maintenance->maintenanceid;
3613
3614 for (i = 0; i < maintenance->groupids.values_num; i++)
3615 {
3616 mg_local.second = maintenance->groupids.values[i];
3617 zbx_hashset_insert(&mgroups, &mg_local, sizeof(mg_local));
3618 }
3619 }
3620
3621 /* add new rows, remove existing rows from index */
3622 while (NULL != (dbrow = DBfetch(result)))
3623 {
3624 ZBX_STR2UINT64(mg_local.first, dbrow[0]);
3625 ZBX_STR2UINT64(mg_local.second, dbrow[1]);
3626
3627 if (NULL == (mg = (zbx_uint64_pair_t *)zbx_hashset_search(&mgroups, &mg_local)))
3628 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_ADD, dbrow);
3629 else
3630 zbx_hashset_remove_direct(&mgroups, mg);
3631 }
3632
3633 /* add removed rows */
3634 zbx_hashset_iter_reset(&mgroups, &iter);
3635 while (NULL != (mg = (zbx_uint64_pair_t *)zbx_hashset_iter_next(&iter)))
3636 {
3637 zbx_snprintf(maintenanceid_s, sizeof(maintenanceid_s), ZBX_FS_UI64, mg->first);
3638 zbx_snprintf(groupid_s, sizeof(groupid_s), ZBX_FS_UI64, mg->second);
3639 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_REMOVE, del_row);
3640 }
3641
3642 DBfree_result(result);
3643 zbx_hashset_destroy(&mgroups);
3644
3645 return SUCCEED;
3646 }
3647
3648 /******************************************************************************
3649 * *
3650 * Function: zbx_dbsync_compare_maintenance_hosts *
3651 * *
3652 * Purpose: compares maintenances_hosts table with cached configuration data *
3653 * *
3654 * Parameter: cache - [IN] the configuration cache *
3655 * sync - [OUT] the changeset *
3656 * *
3657 * Return value: SUCCEED - the changeset was successfully calculated *
3658 * FAIL - otherwise *
3659 * *
3660 ******************************************************************************/
zbx_dbsync_compare_maintenance_hosts(zbx_dbsync_t * sync)3661 int zbx_dbsync_compare_maintenance_hosts(zbx_dbsync_t *sync)
3662 {
3663 DB_ROW dbrow;
3664 DB_RESULT result;
3665 zbx_hashset_iter_t iter;
3666 zbx_dc_maintenance_t *maintenance;
3667 zbx_hashset_t mhosts;
3668 int i;
3669 zbx_uint64_pair_t mh_local, *mh;
3670 char maintenanceid_s[MAX_ID_LEN + 1], hostid_s[MAX_ID_LEN + 1];
3671 char *del_row[2] = {maintenanceid_s, hostid_s};
3672
3673 if (NULL == (result = DBselect("select maintenanceid,hostid from maintenances_hosts order by maintenanceid")))
3674 return FAIL;
3675
3676 dbsync_prepare(sync, 2, NULL);
3677
3678 if (ZBX_DBSYNC_INIT == sync->mode)
3679 {
3680 sync->dbresult = result;
3681 return SUCCEED;
3682 }
3683
3684 zbx_hashset_create(&mhosts, 100, ZBX_DEFAULT_UINT64_PAIR_HASH_FUNC, ZBX_DEFAULT_UINT64_PAIR_COMPARE_FUNC);
3685
3686 /* index all maintenance->host links */
3687 zbx_hashset_iter_reset(&dbsync_env.cache->maintenances, &iter);
3688 while (NULL != (maintenance = (zbx_dc_maintenance_t *)zbx_hashset_iter_next(&iter)))
3689 {
3690 mh_local.first = maintenance->maintenanceid;
3691
3692 for (i = 0; i < maintenance->hostids.values_num; i++)
3693 {
3694 mh_local.second = maintenance->hostids.values[i];
3695 zbx_hashset_insert(&mhosts, &mh_local, sizeof(mh_local));
3696 }
3697 }
3698
3699 /* add new rows, remove existing rows from index */
3700 while (NULL != (dbrow = DBfetch(result)))
3701 {
3702 ZBX_STR2UINT64(mh_local.first, dbrow[0]);
3703 ZBX_STR2UINT64(mh_local.second, dbrow[1]);
3704
3705 if (NULL == (mh = (zbx_uint64_pair_t *)zbx_hashset_search(&mhosts, &mh_local)))
3706 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_ADD, dbrow);
3707 else
3708 zbx_hashset_remove_direct(&mhosts, mh);
3709 }
3710
3711 /* add removed rows */
3712 zbx_hashset_iter_reset(&mhosts, &iter);
3713 while (NULL != (mh = (zbx_uint64_pair_t *)zbx_hashset_iter_next(&iter)))
3714 {
3715 zbx_snprintf(maintenanceid_s, sizeof(maintenanceid_s), ZBX_FS_UI64, mh->first);
3716 zbx_snprintf(hostid_s, sizeof(hostid_s), ZBX_FS_UI64, mh->second);
3717 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_REMOVE, del_row);
3718 }
3719
3720 DBfree_result(result);
3721 zbx_hashset_destroy(&mhosts);
3722
3723 return SUCCEED;
3724 }
3725
3726 /******************************************************************************
3727 * *
3728 * Function: zbx_dbsync_compare_host_group_hosts *
3729 * *
3730 * Purpose: compares hosts_groups table with cached configuration data *
3731 * *
3732 * Parameter: cache - [IN] the configuration cache *
3733 * sync - [OUT] the changeset *
3734 * *
3735 * Return value: SUCCEED - the changeset was successfully calculated *
3736 * FAIL - otherwise *
3737 * *
3738 ******************************************************************************/
zbx_dbsync_compare_host_group_hosts(zbx_dbsync_t * sync)3739 int zbx_dbsync_compare_host_group_hosts(zbx_dbsync_t *sync)
3740 {
3741 DB_ROW dbrow;
3742 DB_RESULT result;
3743 zbx_hashset_iter_t iter, iter_hosts;
3744 zbx_dc_hostgroup_t *group;
3745 zbx_hashset_t groups;
3746 zbx_uint64_t *phostid;
3747 zbx_uint64_pair_t gh_local, *gh;
3748 char groupid_s[MAX_ID_LEN + 1], hostid_s[MAX_ID_LEN + 1];
3749 char *del_row[2] = {groupid_s, hostid_s};
3750
3751 if (NULL == (result = DBselect(
3752 "select hg.groupid,hg.hostid"
3753 " from hosts_groups hg,hosts h"
3754 " where hg.hostid=h.hostid"
3755 " and h.status in (%d,%d)"
3756 " and h.flags<>%d"
3757 " order by hg.groupid",
3758 HOST_STATUS_MONITORED, HOST_STATUS_NOT_MONITORED, ZBX_FLAG_DISCOVERY_PROTOTYPE)))
3759 {
3760 return FAIL;
3761 }
3762
3763 dbsync_prepare(sync, 2, NULL);
3764
3765 if (ZBX_DBSYNC_INIT == sync->mode)
3766 {
3767 sync->dbresult = result;
3768 return SUCCEED;
3769 }
3770
3771 zbx_hashset_create(&groups, 100, ZBX_DEFAULT_UINT64_PAIR_HASH_FUNC, ZBX_DEFAULT_UINT64_PAIR_COMPARE_FUNC);
3772
3773 /* index all group->host links */
3774 zbx_hashset_iter_reset(&dbsync_env.cache->hostgroups, &iter);
3775 while (NULL != (group = (zbx_dc_hostgroup_t *)zbx_hashset_iter_next(&iter)))
3776 {
3777 gh_local.first = group->groupid;
3778
3779 zbx_hashset_iter_reset(&group->hostids, &iter_hosts);
3780 while (NULL != (phostid = (zbx_uint64_t *)zbx_hashset_iter_next(&iter_hosts)))
3781 {
3782 gh_local.second = *phostid;
3783 zbx_hashset_insert(&groups, &gh_local, sizeof(gh_local));
3784 }
3785 }
3786
3787 /* add new rows, remove existing rows from index */
3788 while (NULL != (dbrow = DBfetch(result)))
3789 {
3790 ZBX_STR2UINT64(gh_local.first, dbrow[0]);
3791 ZBX_STR2UINT64(gh_local.second, dbrow[1]);
3792
3793 if (NULL == (gh = (zbx_uint64_pair_t *)zbx_hashset_search(&groups, &gh_local)))
3794 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_ADD, dbrow);
3795 else
3796 zbx_hashset_remove_direct(&groups, gh);
3797 }
3798
3799 /* add removed rows */
3800 zbx_hashset_iter_reset(&groups, &iter);
3801 while (NULL != (gh = (zbx_uint64_pair_t *)zbx_hashset_iter_next(&iter)))
3802 {
3803 zbx_snprintf(groupid_s, sizeof(groupid_s), ZBX_FS_UI64, gh->first);
3804 zbx_snprintf(hostid_s, sizeof(hostid_s), ZBX_FS_UI64, gh->second);
3805 dbsync_add_row(sync, 0, ZBX_DBSYNC_ROW_REMOVE, del_row);
3806 }
3807
3808 DBfree_result(result);
3809 zbx_hashset_destroy(&groups);
3810
3811 return SUCCEED;
3812 }
3813