From 9c6b410b42c4e7689c7bedc7722b762d515967cc Mon Sep 17 00:00:00 2001 From: Dmitrijs Goloscapovs Date: Mon, 23 Oct 2023 11:05:57 +0300 Subject: [PATCH] .......PS. [ZBX-23559] fixed SLI dropping when maintenance is set with pre-existing problem --- include/common.h | 1 + include/db.h | 2 + include/service_protocol.h | 2 +- include/zbxrtc.h | 4 +- include/zbxservice.h | 18 +-- src/libs/zbxrtc/rtc_client.c | 11 +- src/libs/zbxrtc/rtc_service.c | 7 +- src/libs/zbxservice/service_protocol.c | 8 +- src/zabbix_proxy/proxy.c | 2 +- src/zabbix_proxy/proxyconfig/proxyconfig.c | 6 +- src/zabbix_server/dbconfig/dbconfig.c | 2 +- src/zabbix_server/events.c | 4 +- src/zabbix_server/server.c | 8 +- src/zabbix_server/service/service_manager.c | 124 +++++++++++++++++++- src/zabbix_server/timer/timer.c | 56 ++++++++- tests/zabbix_server/service/Makefile.am | 4 +- tests/zabbix_server/service/mock_service.c | 13 ++ 17 files changed, 240 insertions(+), 32 deletions(-) diff --git a/include/common.h b/include/common.h index bc51dd218de..f85ca49f350 100644 --- a/include/common.h +++ b/include/common.h @@ -1012,6 +1012,7 @@ zbx_task_t; /* runtime control notifications, must be less than 10000 */ #define ZBX_RTC_CONFIG_SYNC_NOTIFY 9999 +#define ZBX_RTC_SERVICE_SYNC_NOTIFY 9998 #define ZBX_IPC_RTC_MAX 9999 diff --git a/include/db.h b/include/db.h index 15cd325fb72..543632a0925 100644 --- a/include/db.h +++ b/include/db.h @@ -802,6 +802,8 @@ typedef struct int severity; zbx_vector_ptr_t tags; + unsigned char suppressed; + int mtime; } zbx_event_t; diff --git a/include/service_protocol.h b/include/service_protocol.h index 532bd960655..c95086fb833 100644 --- a/include/service_protocol.h +++ b/include/service_protocol.h @@ -30,7 +30,7 @@ typedef struct zbx_event_severity_t; void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *data_offset, zbx_uint64_t eventid, - int clock, int ns, int value, int severity, const zbx_vector_ptr_t *tags); + int clock, int ns, int value, int severity, const zbx_vector_ptr_t *tags, unsigned char suppressed); void zbx_service_deserialize(const unsigned char *data, zbx_uint32_t size, zbx_vector_ptr_t *events); void zbx_service_serialize_problem_tags(unsigned char **data, size_t *data_alloc, size_t *data_offset, zbx_uint64_t eventid, const zbx_vector_tags_t *tags); diff --git a/include/zbxrtc.h b/include/zbxrtc.h index 7a2dcc927ef..eda8c227e2b 100644 --- a/include/zbxrtc.h +++ b/include/zbxrtc.h @@ -52,14 +52,14 @@ zbx_rtc_t; /* provider API */ int zbx_rtc_init(zbx_rtc_t *rtc ,char **error); void zbx_rtc_dispatch(zbx_rtc_t *rtc, zbx_ipc_client_t *client, zbx_ipc_message_t *message); -int zbx_rtc_wait_config_sync(zbx_rtc_t *rtc); +int zbx_rtc_wait_for_sync_finish(zbx_rtc_t *rtc); void zbx_rtc_shutdown_subs(zbx_rtc_t *rtc); void zbx_rtc_reset(zbx_rtc_t *rtc); /* client API */ int zbx_rtc_process(const char *option, char **error); int zbx_rtc_open(zbx_ipc_async_socket_t *asocket, int timeout, char **error); -void zbx_rtc_notify_config_sync(zbx_ipc_async_socket_t *rtc); +void zbx_rtc_notify_finished_sync(zbx_ipc_async_socket_t *rtc, zbx_uint32_t code, const char *process_name); void zbx_rtc_subscribe(zbx_ipc_async_socket_t *rtc, unsigned char proc_type, int proc_num); int zbx_rtc_wait(zbx_ipc_async_socket_t *rtc, zbx_uint32_t *cmd, unsigned char **data, int timeout); diff --git a/include/zbxservice.h b/include/zbxservice.h index 1e3932cf010..b76b0f4939d 100644 --- a/include/zbxservice.h +++ b/include/zbxservice.h @@ -26,14 +26,16 @@ ZBX_PTR_VECTOR_DECL(service, DB_SERVICE *) -#define ZBX_IPC_SERVICE_SERVICE "service" -#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS 1 -#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS_TAGS 2 -#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS_DELETE 3 -#define ZBX_IPC_SERVICE_SERVICE_ROOTCAUSE 4 -#define ZBX_IPC_SERVICE_SERVICE_PARENT_LIST 5 -#define ZBX_IPC_SERVICE_EVENT_SEVERITIES 6 -#define ZBX_IPC_SERVICE_RELOAD_CACHE 7 +#define ZBX_IPC_SERVICE_SERVICE "service" +#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS 1 +#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS_TAGS 2 +#define ZBX_IPC_SERVICE_SERVICE_PROBLEMS_DELETE 3 +#define ZBX_IPC_SERVICE_SERVICE_ROOTCAUSE 4 +#define ZBX_IPC_SERVICE_SERVICE_PARENT_LIST 5 +#define ZBX_IPC_SERVICE_EVENT_SEVERITIES 6 +#define ZBX_IPC_SERVICE_RELOAD_CACHE 7 +#define ZBX_IPC_SERVICE_SERVICE_EVENTS_SUPPRESS 8 +#define ZBX_IPC_SERVICE_SERVICE_EVENTS_UNSUPPRESS 9 void zbx_service_flush(zbx_uint32_t code, unsigned char *data, zbx_uint32_t size); void zbx_service_send(zbx_uint32_t code, unsigned char *data, zbx_uint32_t size, zbx_ipc_message_t *response); diff --git a/src/libs/zbxrtc/rtc_client.c b/src/libs/zbxrtc/rtc_client.c index 0cced2054e4..04f2205c617 100644 --- a/src/libs/zbxrtc/rtc_client.c +++ b/src/libs/zbxrtc/rtc_client.c @@ -257,22 +257,23 @@ int zbx_rtc_open(zbx_ipc_async_socket_t *asocket, int timeout, char **error) /****************************************************************************** * * - * Purpose: notify RTC service about finishing initial configuration sync * + * Purpose: notify RTC service about finishing initial sync * * * * Parameters: rtc - [OUT] the RTC notification subscription socket * + * code - [IN] the RTC code to be sent * * * ******************************************************************************/ -void zbx_rtc_notify_config_sync(zbx_ipc_async_socket_t *rtc) +void zbx_rtc_notify_finished_sync(zbx_ipc_async_socket_t *rtc, zbx_uint32_t code, const char *process_name) { - if (FAIL == zbx_ipc_async_socket_send(rtc, ZBX_RTC_CONFIG_SYNC_NOTIFY, NULL, 0)) + if (FAIL == zbx_ipc_async_socket_send(rtc, code, NULL, 0)) { - zabbix_log(LOG_LEVEL_CRIT, "cannot send configuration syncer notification"); + zabbix_log(LOG_LEVEL_CRIT, "cannot send %s notification", process_name); exit(EXIT_FAILURE); } if (FAIL == zbx_ipc_async_socket_flush(rtc, CONFIG_TIMEOUT)) { - zabbix_log(LOG_LEVEL_CRIT, "cannot flush configuration syncer notification"); + zabbix_log(LOG_LEVEL_CRIT, "cannot flush %s notification", process_name); exit(EXIT_FAILURE); } } diff --git a/src/libs/zbxrtc/rtc_service.c b/src/libs/zbxrtc/rtc_service.c index d87cc4e9e0d..a25a791c45d 100644 --- a/src/libs/zbxrtc/rtc_service.c +++ b/src/libs/zbxrtc/rtc_service.c @@ -383,11 +383,11 @@ void zbx_rtc_dispatch(zbx_rtc_t *rtc, zbx_ipc_client_t *client, zbx_ipc_message_ /****************************************************************************** * * - * Purpose: wait for configuration sync notification while optionally * - * dispatching runtime control commands * + * Purpose: wait for sync notification while optionally dispatching runtime * + * control commands * * * ******************************************************************************/ -int zbx_rtc_wait_config_sync(zbx_rtc_t *rtc) +int zbx_rtc_wait_for_sync_finish(zbx_rtc_t *rtc) { zbx_timespec_t rtc_timeout = {1, 0}; int sync = 0; @@ -404,6 +404,7 @@ int zbx_rtc_wait_config_sync(zbx_rtc_t *rtc) switch (message->code) { case ZBX_RTC_CONFIG_SYNC_NOTIFY: + case ZBX_RTC_SERVICE_SYNC_NOTIFY: sync = 1; break; case ZBX_RTC_LOG_LEVEL_DECREASE: diff --git a/src/libs/zbxservice/service_protocol.c b/src/libs/zbxservice/service_protocol.c index 22743d5063b..1881fe555cf 100644 --- a/src/libs/zbxservice/service_protocol.c +++ b/src/libs/zbxservice/service_protocol.c @@ -24,7 +24,7 @@ #include "db.h" void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *data_offset, zbx_uint64_t eventid, - int clock, int ns, int value, int severity, const zbx_vector_ptr_t *tags) + int clock, int ns, int value, int severity, const zbx_vector_ptr_t *tags, unsigned char suppressed) { zbx_uint32_t data_len = 0, *len = NULL; int i; @@ -36,6 +36,7 @@ void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *dat zbx_serialize_prepare_value(data_len, value); zbx_serialize_prepare_value(data_len, severity); zbx_serialize_prepare_value(data_len, tags->values_num); + zbx_serialize_prepare_value(data_len, suppressed); if (0 != tags->values_num) { @@ -78,6 +79,8 @@ void zbx_service_serialize(unsigned char **data, size_t *data_alloc, size_t *dat ptr += zbx_serialize_str(ptr, tag->value, len[i * 2 + 1]); } + ptr += zbx_serialize_value(ptr, suppressed); + zbx_free(len); } @@ -117,6 +120,9 @@ void zbx_service_deserialize(const unsigned char *data, zbx_uint32_t size, zbx_v zbx_vector_ptr_append(&event->tags, tag); } } + + data += zbx_deserialize_value(data, &event->suppressed); + event->mtime = 0; } } diff --git a/src/zabbix_proxy/proxy.c b/src/zabbix_proxy/proxy.c index 41d3c162e61..175a195b11b 100644 --- a/src/zabbix_proxy/proxy.c +++ b/src/zabbix_proxy/proxy.c @@ -1319,7 +1319,7 @@ int MAIN_ZABBIX_ENTRY(int flags) { case ZBX_PROCESS_TYPE_CONFSYNCER: zbx_thread_start(proxyconfig_thread, &thread_args, &threads[i]); - if (FAIL == zbx_rtc_wait_config_sync(&rtc)) + if (FAIL == zbx_rtc_wait_for_sync_finish(&rtc)) goto out; break; case ZBX_PROCESS_TYPE_TRAPPER: diff --git a/src/zabbix_proxy/proxyconfig/proxyconfig.c b/src/zabbix_proxy/proxyconfig/proxyconfig.c index a02b4ec8e0c..2ae9329abe8 100644 --- a/src/zabbix_proxy/proxyconfig/proxyconfig.c +++ b/src/zabbix_proxy/proxyconfig/proxyconfig.c @@ -173,7 +173,7 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args) zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); DCsync_configuration(ZBX_DBSYNC_INIT); - zbx_rtc_notify_config_sync(&rtc); + zbx_rtc_notify_finished_sync(&rtc, ZBX_RTC_CONFIG_SYNC_NOTIFY, get_process_type_string(process_type)); sleeptime = (ZBX_PROGRAM_TYPE_PROXY_PASSIVE == program_type ? ZBX_IPC_WAIT_FOREVER : 0); @@ -204,7 +204,9 @@ ZBX_THREAD_ENTRY(proxyconfig_thread, args) DCsync_configuration(ZBX_DBSYNC_UPDATE); DCupdate_interfaces_availability(); - zbx_rtc_notify_config_sync(&rtc); + + zbx_rtc_notify_finished_sync(&rtc, ZBX_RTC_CONFIG_SYNC_NOTIFY, + get_process_type_string(process_type)); zbx_setproctitle("%s [synced config in " ZBX_FS_DBL " sec]", get_process_type_string(process_type), zbx_time() - sec); diff --git a/src/zabbix_server/dbconfig/dbconfig.c b/src/zabbix_server/dbconfig/dbconfig.c index 8e22139e824..e71bb095b4d 100644 --- a/src/zabbix_server/dbconfig/dbconfig.c +++ b/src/zabbix_server/dbconfig/dbconfig.c @@ -65,7 +65,7 @@ ZBX_THREAD_ENTRY(dbconfig_thread, args) zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), (sec = zbx_time() - sec), CONFIG_CONFSYNCER_FREQUENCY); - zbx_rtc_notify_config_sync(&rtc); + zbx_rtc_notify_finished_sync(&rtc, ZBX_RTC_CONFIG_SYNC_NOTIFY, get_process_type_string(process_type)); nextcheck = (int)time(NULL) + CONFIG_CONFSYNCER_FREQUENCY; diff --git a/src/zabbix_server/events.c b/src/zabbix_server/events.c index 0659c45701b..aa538920eb6 100644 --- a/src/zabbix_server/events.c +++ b/src/zabbix_server/events.c @@ -1878,7 +1878,7 @@ void zbx_events_update_itservices(void) zbx_service_serialize(&data, &data_alloc, &data_offset, recovery->eventid, recovery->r_event->clock, recovery->r_event->ns, recovery->r_event->value, recovery->r_event->severity, - &recovery->r_event->tags); + &recovery->r_event->tags, 0); recovery->r_event->tags.values_num = values_num; } @@ -1894,7 +1894,7 @@ void zbx_events_update_itservices(void) continue; zbx_service_serialize(&data, &data_alloc, &data_offset, event->eventid, event->clock, event->ns, - event->value, event->severity, &event->tags); + event->value, event->severity, &event->tags, event->suppressed); } if (NULL == data) diff --git a/src/zabbix_server/server.c b/src/zabbix_server/server.c index 3ae87d02238..c91e764cb2b 100644 --- a/src/zabbix_server/server.c +++ b/src/zabbix_server/server.c @@ -1293,7 +1293,13 @@ static int server_startup(zbx_socket_t *listen_sock, int *ha_stat, int *ha_failo break; case ZBX_PROCESS_TYPE_CONFSYNCER: zbx_thread_start(dbconfig_thread, &thread_args, &threads[i]); - if (FAIL == (ret = zbx_rtc_wait_config_sync(rtc))) + + /* wait for service manager startup */ + if (FAIL == (ret = zbx_rtc_wait_for_sync_finish(rtc))) + goto out; + + /* wait for configuration sync */ + if (FAIL == (ret = zbx_rtc_wait_for_sync_finish(rtc))) goto out; if (SUCCEED != (ret = zbx_ha_get_status(ha_stat, ha_failover, &error))) diff --git a/src/zabbix_server/service/service_manager.c b/src/zabbix_server/service/service_manager.c index db88317ba23..aa78ed0ddfc 100644 --- a/src/zabbix_server/service/service_manager.c +++ b/src/zabbix_server/service/service_manager.c @@ -25,6 +25,7 @@ #include "service_protocol.h" #include "service_actions.h" #include "zbxserialize.h" +#include "zbxrtc.h" extern ZBX_THREAD_LOCAL unsigned char process_type; extern unsigned char program_type; @@ -83,6 +84,7 @@ typedef struct zbx_vector_ptr_t service_problems_recovered; #define ZBX_FLAG_SERVICE_UPDATE __UINT64_C(0x00) #define ZBX_FLAG_SERVICE_RECALCULATE __UINT64_C(0x01) +#define ZBX_FLAG_SERVICE_RECALCULATE_SUPPRESS __UINT64_C(0x04) int flags; } zbx_services_diff_t; @@ -256,6 +258,8 @@ static void db_get_events(zbx_hashset_t *problem_events) event->ns = atoi(row[5]); event->value = TRIGGER_VALUE_PROBLEM; event->severity = atoi(row[2]); + event->mtime = 0; + event->suppressed = 0; zbx_vector_ptr_create(&event->tags); zbx_hashset_insert(problem_events, &event, sizeof(zbx_event_t *)); } @@ -272,6 +276,22 @@ static void db_get_events(zbx_hashset_t *problem_events) } DBfree_result(result); + result = DBselect("select distinct(eventid) from event_suppress"); + while (NULL != (row = DBfetch(result))) + { + zbx_event_t event_local, *event_p, **ptr; + + ZBX_STR2UINT64(event_local.eventid, row[0]); + event_p = &event_local; + + if (NULL != (ptr = zbx_hashset_search(problem_events, &event_p))) + { + event_p = *ptr; + event_p->suppressed = 1; + } + } + DBfree_result(result); + zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } @@ -318,7 +338,9 @@ static void remove_service_problem(zbx_service_t *service, int index, zbx_hashse zbx_vector_ptr_remove_noorder(&service_problem_index->services, i); if (0 == service_problem_index->services.values_num) + { zbx_hashset_remove_direct(service_problems_index, service_problem_index); + } } } @@ -2486,6 +2508,7 @@ static void db_update_services(zbx_service_manager_t *manager) zbx_hashset_create(&service_updates, 100, service_update_hash_func, service_update_compare_func); zbx_hashset_iter_reset(&manager->service_diffs, &iter); + while (NULL != (service_diff = (zbx_services_diff_t *)zbx_hashset_iter_next(&iter))) { zbx_service_t service_local = {.serviceid = service_diff->serviceid}, *service; @@ -2500,7 +2523,8 @@ static void db_update_services(zbx_service_manager_t *manager) continue; } - if (service_diff->flags & ZBX_FLAG_SERVICE_RECALCULATE) + if ((service_diff->flags & ZBX_FLAG_SERVICE_RECALCULATE) && + (0 == (service_diff->flags & ZBX_FLAG_SERVICE_RECALCULATE_SUPPRESS))) { for (i = 0; i < service->service_problems.values_num; i++) { @@ -2561,13 +2585,33 @@ static void db_update_services(zbx_service_manager_t *manager) for (i = 0; i < service->service_problems.values_num; i++) { zbx_service_problem_t *service_problem; + zbx_event_t *event, event_local, **ptr; service_problem = (zbx_service_problem_t *)service->service_problems.values[i]; + event_local.eventid = service_problem->eventid; + event = &event_local; + + if (NULL != (ptr = zbx_hashset_search(&manager->problem_events, &event))) + { + event = *ptr; + if (1 == event->suppressed) + continue; + } if (service_problem->severity > status) { status = service_problem->severity; - ts = service_problem->ts; + + if (0 == (service_diff->flags & ZBX_FLAG_SERVICE_RECALCULATE_SUPPRESS)) + { + if (NULL != ptr && 0 != event->mtime) + { + ts.sec = event->mtime; + ts.ns = 0; + } + else + ts = service_problem->ts; + } } } @@ -2651,6 +2695,7 @@ static void recover_services_problem(zbx_service_manager_t *service_manager, con service_problem->eventid = event->eventid; service_problem->serviceid = service_diff->serviceid; service_problem->severity = event->severity; + service_problem->ts.sec = event->clock; service_problem->ts.ns = event->ns; @@ -2696,6 +2741,64 @@ static void process_deleted_problems(zbx_vector_uint64_t *eventids, zbx_service_ zabbix_log(LOG_LEVEL_DEBUG, "End of %s()", __func__); } +static void process_problem_suppression(zbx_vector_uint64_t *eventids, zbx_service_manager_t *service_manager, + int suppressed) +{ + int i; + + for (i = 0; i < eventids->values_num; i++) + { + zbx_event_t event_local, *event = &event_local, **pevent; + zbx_service_problem_index_t *pi, pi_local; + zbx_services_diff_t *services_diff, services_diff_local; + + event_local.eventid = eventids->values[i]; + + if (NULL == (pevent = (zbx_event_t **)zbx_hashset_search(&service_manager->problem_events, &event))) + { + continue; + } + + (*pevent)->suppressed = suppressed; + (*pevent)->mtime = (int)time(NULL); + + pi_local.eventid = eventids->values[i]; + + if (NULL == (pi = zbx_hashset_search(&service_manager->service_problems_index, &pi_local))) + { + continue; + } + + for (int j = 0; j < pi->services.values_num; j++) + { + zbx_service_t *service = (zbx_service_t *)pi->services.values[j]; + services_diff_local.serviceid = service->serviceid; + + if (NULL == (services_diff = zbx_hashset_search(&service_manager->service_diffs, + &services_diff_local))) + { + zbx_vector_ptr_create(&services_diff_local.service_problems); + zbx_vector_ptr_create(&services_diff_local.service_problems_recovered); + + services_diff_local.flags |= (ZBX_FLAG_SERVICE_RECALCULATE | + ZBX_FLAG_SERVICE_RECALCULATE_SUPPRESS); + + zbx_hashset_insert(&service_manager->service_diffs, &services_diff_local, + sizeof(services_diff_local)); + } + else + { + services_diff->flags = (ZBX_FLAG_SERVICE_RECALCULATE | + ZBX_FLAG_SERVICE_RECALCULATE_SUPPRESS); + } + } + + } + + db_update_services(service_manager); + zbx_hashset_clear(&service_manager->service_diffs); +} + static void process_problem_tags(zbx_vector_ptr_t *events, zbx_service_manager_t *service_manager) { int i, j; @@ -2988,7 +3091,7 @@ static void process_event_severities(const zbx_ipc_message_t *message, zbx_servi { zbx_event_severity_t *es = (zbx_event_severity_t *)event_severities.values[i]; zbx_event_t event_local = {.eventid = es->eventid}, *event = &event_local, **pevent; - zbx_service_problem_index_t *pi, pi_local; + zbx_service_problem_index_t *pi, pi_local; /* update event severity in problem cache */ @@ -3012,6 +3115,7 @@ static void process_event_severities(const zbx_ipc_message_t *message, zbx_servi } db_update_services(service_manager); + zbx_hashset_clear(&service_manager->service_diffs); out: zbx_vector_ptr_clear_ext(&event_severities, zbx_ptr_free); zbx_vector_ptr_destroy(&event_severities); @@ -3261,6 +3365,7 @@ ZBX_THREAD_ENTRY(service_manager_thread, args) zbx_service_manager_t service_manager; zbx_timespec_t timeout = {1, 0}; int service_cache_reload_requested = 0; + zbx_ipc_async_socket_t rtc; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ @@ -3274,6 +3379,8 @@ ZBX_THREAD_ENTRY(service_manager_thread, args) update_selfmon_counter(ZBX_PROCESS_STATE_BUSY); + zbx_rtc_subscribe(&rtc, process_type, process_num); + zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num); DBconnect(ZBX_DB_CONNECT_NORMAL); @@ -3345,6 +3452,9 @@ ZBX_THREAD_ENTRY(service_manager_thread, args) { sync_service_problems(&service_manager.services, &service_manager.service_problems_index); + + zbx_rtc_notify_finished_sync(&rtc, ZBX_RTC_SERVICE_SYNC_NOTIFY, + get_process_type_string(process_type)); } } while (ZBX_DB_DOWN == DBcommit()); @@ -3399,6 +3509,14 @@ ZBX_THREAD_ENTRY(service_manager_thread, args) process_deleted_problems(&eventids, &service_manager); problems_delete_num += events.values_num; break; + case ZBX_IPC_SERVICE_SERVICE_EVENTS_UNSUPPRESS: + zbx_service_deserialize_ids(message->data, message->size, &eventids); + process_problem_suppression(&eventids, &service_manager, 0); + break; + case ZBX_IPC_SERVICE_SERVICE_EVENTS_SUPPRESS: + zbx_service_deserialize_ids(message->data, message->size, &eventids); + process_problem_suppression(&eventids, &service_manager, 1); + break; case ZBX_IPC_SERVICE_SERVICE_ROOTCAUSE: process_rootcause(message, &service_manager, client); break; diff --git a/src/zabbix_server/timer/timer.c b/src/zabbix_server/timer/timer.c index 17cf36a9757..96c7420ecbd 100644 --- a/src/zabbix_server/timer/timer.c +++ b/src/zabbix_server/timer/timer.c @@ -23,6 +23,7 @@ #include "dbcache.h" #include "daemon.h" #include "zbxself.h" +#include "service_protocol.h" #define ZBX_TIMER_DELAY SEC_PER_MIN @@ -159,6 +160,26 @@ static void db_update_host_maintenances(const zbx_vector_ptr_t *updates) zbx_free(sql); } +static void service_send_suppression_data(const zbx_vector_uint64_t *eventids, int suppressed) +{ + unsigned char *data = NULL; + size_t data_alloc = 0, data_offset = 0; + int i; + + for (i = 0; i < eventids->values_num; i++) + zbx_service_serialize_id(&data, &data_alloc, &data_offset, eventids->values[i]); + + if (NULL == data) + return; + + if (suppressed == 0) + zbx_service_flush(ZBX_IPC_SERVICE_SERVICE_EVENTS_UNSUPPRESS, data, (zbx_uint32_t)data_offset); + else + zbx_service_flush(ZBX_IPC_SERVICE_SERVICE_EVENTS_SUPPRESS, data, (zbx_uint32_t)data_offset); + zbx_free(data); +} + + /****************************************************************************** * * * Purpose: remove expired event_suppress records * @@ -166,9 +187,30 @@ static void db_update_host_maintenances(const zbx_vector_ptr_t *updates) ******************************************************************************/ static void db_remove_expired_event_suppress_data(int now) { + zbx_vector_uint64_t eventids; + DB_ROW row; + DB_RESULT result; + + zbx_vector_uint64_create(&eventids); + + result = DBselect("select eventid from event_suppress where suppress_until<%d", now); + + while (NULL != (row = DBfetch(result))) + { + zbx_uint64_t eventid; + ZBX_STR2UINT64(eventid, row[0]); + + zbx_vector_uint64_append(&eventids, eventid); + } + DBfree_result(result); + DBbegin(); DBexecute("delete from event_suppress where suppress_until<%d", now); DBcommit(); + + service_send_suppression_data(&eventids, 0); + + zbx_vector_uint64_destroy(&eventids); } /****************************************************************************** @@ -351,11 +393,13 @@ static void db_get_query_events(zbx_vector_ptr_t *event_queries, zbx_vector_ptr_ static void db_update_event_suppress_data(int *suppressed_num) { zbx_vector_ptr_t event_queries, event_data; + zbx_vector_uint64_t s_eventids; *suppressed_num = 0; zbx_vector_ptr_create(&event_queries); zbx_vector_ptr_create(&event_data); + zbx_vector_uint64_create(&s_eventids); db_get_query_events(&event_queries, &event_data); @@ -368,7 +412,7 @@ static void db_update_event_suppress_data(int *suppressed_num) zbx_event_suppress_query_t *query; zbx_event_suppress_data_t *data; zbx_vector_uint64_pair_t del_event_maintenances; - zbx_vector_uint64_t maintenanceids; + zbx_vector_uint64_t maintenanceids, eventids; zbx_uint64_pair_t pair; zbx_vector_uint64_create(&maintenanceids); @@ -463,10 +507,12 @@ static void db_update_event_suppress_data(int *suppressed_num) (int)query->maintenances.values[k].second); (*suppressed_num)++; + zbx_vector_uint64_append(&s_eventids, query->eventid); } } } + zbx_vector_uint64_create(&eventids); for (i = 0; i < del_event_maintenances.values_num; i++) { zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, @@ -475,10 +521,14 @@ static void db_update_event_suppress_data(int *suppressed_num) " and maintenanceid=" ZBX_FS_UI64 ";\n", del_event_maintenances.values[i].first, del_event_maintenances.values[i].second); + zbx_vector_uint64_append(&eventids, del_event_maintenances.values[i].first); if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset)) goto cleanup; } + service_send_suppression_data(&eventids, 0); + + zbx_vector_uint64_destroy(&eventids); DBend_multiple_update(&sql, &sql_alloc, &sql_offset); @@ -498,6 +548,8 @@ cleanup: zbx_vector_uint64_pair_destroy(&del_event_maintenances); zbx_vector_uint64_destroy(&maintenanceids); + + service_send_suppression_data(&s_eventids, 1); } zbx_vector_ptr_clear_ext(&event_data, (zbx_clean_func_t)event_suppress_data_free); @@ -505,6 +557,8 @@ cleanup: zbx_vector_ptr_clear_ext(&event_queries, (zbx_clean_func_t)zbx_event_suppress_query_free); zbx_vector_ptr_destroy(&event_queries); + + zbx_vector_uint64_destroy(&s_eventids); } /****************************************************************************** diff --git a/tests/zabbix_server/service/Makefile.am b/tests/zabbix_server/service/Makefile.am index fbc5be6517b..b02a3b73839 100644 --- a/tests/zabbix_server/service/Makefile.am +++ b/tests/zabbix_server/service/Makefile.am @@ -64,7 +64,9 @@ SERVICE_WRAP_FUNCS = \ -Wl,--wrap=zbx_clean_events \ -Wl,--wrap=zbx_interface_availability_is_set \ -Wl,--wrap=zbx_tsdb_recalc_time_period \ - -Wl,--wrap=zbx_config_get + -Wl,--wrap=zbx_config_get \ + -Wl,--wrap=zbx_rtc_subscribe \ + -Wl,--wrap=zbx_rtc_notify_finished_sync # service_get_rootcause_eventids diff --git a/tests/zabbix_server/service/mock_service.c b/tests/zabbix_server/service/mock_service.c index c5d22f1d081..58d33e77d70 100644 --- a/tests/zabbix_server/service/mock_service.c +++ b/tests/zabbix_server/service/mock_service.c @@ -396,4 +396,17 @@ int __wrap_zbx_interface_availability_is_set(const void *ia) return FAIL; } +void __wrap_zbx_rtc_subscribe(void *rtc, unsigned char proc_type, int proc_num) +{ + ZBX_UNUSED(rtc); + ZBX_UNUSED(proc_type); + ZBX_UNUSED(proc_num); +} + +void __wrap_zbx_rtc_notify_finished_sync(void *rtc, zbx_uint32_t code, const char *process_name) +{ + ZBX_UNUSED(rtc); + ZBX_UNUSED(code); + ZBX_UNUSED(process_name); +} -- 2.30.2