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
22 #include "cfg.h"
23 #include "pid.h"
24 #include "db.h"
25 #include "log.h"
26 #include "dbcache.h"
27 #include "zbxserver.h"
28 #include "daemon.h"
29 #include "zbxself.h"
30 #include "db.h"
31
32 #include "timer.h"
33
34 #define ZBX_TIMER_DELAY SEC_PER_MIN
35
36 #define ZBX_EVENT_BATCH_SIZE 1000
37
38 extern unsigned char process_type, program_type;
39 extern int server_num, process_num;
40 extern int CONFIG_TIMER_FORKS;
41
42 /* addition data for event maintenance calculations to pair with zbx_event_suppress_query_t */
43 typedef struct
44 {
45 zbx_uint64_t eventid;
46 zbx_vector_uint64_pair_t maintenances;
47 }
48 zbx_event_suppress_data_t;
49
50 /******************************************************************************
51 * *
52 * Function: log_host_maintenance_update *
53 * *
54 * Purpose: log host maintenance changes *
55 * *
56 ******************************************************************************/
log_host_maintenance_update(const zbx_host_maintenance_diff_t * diff)57 static void log_host_maintenance_update(const zbx_host_maintenance_diff_t* diff)
58 {
59 char *msg = NULL;
60 size_t msg_alloc = 0, msg_offset = 0;
61 int maintenance_off = 0;
62
63 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_STATUS))
64 {
65 if (HOST_MAINTENANCE_STATUS_ON == diff->maintenance_status)
66 {
67 zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "putting host (" ZBX_FS_UI64 ") into",
68 diff->hostid);
69 }
70 else
71 {
72 maintenance_off = 1;
73 zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "taking host (" ZBX_FS_UI64 ") out of",
74 diff->hostid);
75 }
76 }
77 else
78 zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "changing host (" ZBX_FS_UI64 ")", diff->hostid);
79
80 zbx_strcpy_alloc(&msg, &msg_alloc, &msg_offset, " maintenance");
81
82 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCEID) && 0 != diff->maintenanceid)
83 zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, "(" ZBX_FS_UI64 ")", diff->maintenanceid);
84
85
86 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_TYPE) && 0 == maintenance_off)
87 {
88 const char *description[] = {"with data collection", "without data collection"};
89
90 zbx_snprintf_alloc(&msg, &msg_alloc, &msg_offset, " %s", description[diff->maintenance_type]);
91 }
92
93 zabbix_log(LOG_LEVEL_DEBUG, "%s", msg);
94 zbx_free(msg);
95 }
96
97 /******************************************************************************
98 * *
99 * Function: db_update_host_maintenances *
100 * *
101 * Purpose: update host maintenance properties in database *
102 * *
103 ******************************************************************************/
db_update_host_maintenances(const zbx_vector_ptr_t * updates)104 static void db_update_host_maintenances(const zbx_vector_ptr_t *updates)
105 {
106 int i;
107 const zbx_host_maintenance_diff_t *diff;
108 char *sql = NULL;
109 size_t sql_alloc = 0, sql_offset = 0;
110
111 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
112
113 for (i = 0; i < updates->values_num; i++)
114 {
115 char delim = ' ';
116
117 diff = (const zbx_host_maintenance_diff_t *)updates->values[i];
118
119 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, "update hosts set");
120
121 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCEID))
122 {
123 if (0 != diff->maintenanceid)
124 {
125 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cmaintenanceid=" ZBX_FS_UI64, delim,
126 diff->maintenanceid);
127 }
128 else
129 {
130 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cmaintenanceid=null", delim);
131 }
132
133 delim = ',';
134 }
135
136 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_TYPE))
137 {
138 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cmaintenance_type=%u", delim,
139 diff->maintenance_type);
140 delim = ',';
141 }
142
143 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_STATUS))
144 {
145 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cmaintenance_status=%u", delim,
146 diff->maintenance_status);
147 delim = ',';
148 }
149
150 if (0 != (diff->flags & ZBX_FLAG_HOST_MAINTENANCE_UPDATE_MAINTENANCE_FROM))
151 {
152 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, "%cmaintenance_from=%d", delim,
153 diff->maintenance_from);
154 }
155
156 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, " where hostid=" ZBX_FS_UI64 ";\n", diff->hostid);
157
158 if (SUCCEED != DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
159 break;
160
161 if (SUCCEED == ZBX_CHECK_LOG_LEVEL(LOG_LEVEL_DEBUG))
162 log_host_maintenance_update(diff);
163 }
164
165 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
166
167 if (16 < sql_offset)
168 DBexecute("%s", sql);
169
170 zbx_free(sql);
171 }
172
173 /******************************************************************************
174 * *
175 * Function: db_remove_expired_event_suppress_data *
176 * *
177 * Purpose: remove expired event_suppress records *
178 * *
179 ******************************************************************************/
db_remove_expired_event_suppress_data(int now)180 static void db_remove_expired_event_suppress_data(int now)
181 {
182 DBbegin();
183 DBexecute("delete from event_suppress where suppress_until<%d", now);
184 DBcommit();
185 }
186
187 /******************************************************************************
188 * *
189 * Function: event_suppress_data_free *
190 * *
191 * Purpose: free event suppress data structure *
192 * *
193 ******************************************************************************/
event_suppress_data_free(zbx_event_suppress_data_t * data)194 static void event_suppress_data_free(zbx_event_suppress_data_t *data)
195 {
196 zbx_vector_uint64_pair_destroy(&data->maintenances);
197 zbx_free(data);
198 }
199
200 /******************************************************************************
201 * *
202 * Function: event_queries_fetch *
203 * *
204 * Purpose: fetch events that need to be queried for maintenance *
205 * *
206 ******************************************************************************/
event_queries_fetch(DB_RESULT result,zbx_vector_ptr_t * event_queries)207 static void event_queries_fetch(DB_RESULT result, zbx_vector_ptr_t *event_queries)
208 {
209 DB_ROW row;
210 zbx_uint64_t eventid;
211 zbx_event_suppress_query_t *query = NULL;
212
213 while (NULL != (row = DBfetch(result)))
214 {
215 ZBX_STR2UINT64(eventid, row[0]);
216
217 if (NULL == query || eventid != query->eventid)
218 {
219 query = (zbx_event_suppress_query_t *)zbx_malloc(NULL, sizeof(zbx_event_suppress_query_t));
220
221 query->eventid = eventid;
222 ZBX_STR2UINT64(query->triggerid, row[1]);
223 ZBX_DBROW2UINT64(query->r_eventid, row[2]);
224 zbx_vector_uint64_create(&query->functionids);
225 zbx_vector_ptr_create(&query->tags);
226 zbx_vector_uint64_pair_create(&query->maintenances);
227 zbx_vector_ptr_append(event_queries, query);
228 }
229
230 if (FAIL == DBis_null(row[3]))
231 {
232 zbx_tag_t *tag;
233
234 tag = (zbx_tag_t *)zbx_malloc(NULL, sizeof(zbx_tag_t));
235 tag->tag = zbx_strdup(NULL, row[3]);
236 tag->value = zbx_strdup(NULL, row[4]);
237 zbx_vector_ptr_append(&query->tags, tag);
238
239 }
240 }
241 }
242
243 /******************************************************************************
244 * *
245 * Function: db_get_query_events *
246 * *
247 * Purpose: get open, recently resolved and resolved problems with suppress *
248 * data from database and prepare event query, event data structures *
249 * *
250 ******************************************************************************/
db_get_query_events(zbx_vector_ptr_t * event_queries,zbx_vector_ptr_t * event_data)251 static void db_get_query_events(zbx_vector_ptr_t *event_queries, zbx_vector_ptr_t *event_data)
252 {
253 DB_ROW row;
254 DB_RESULT result;
255 zbx_event_suppress_data_t *data = NULL;
256 zbx_uint64_t eventid;
257 zbx_uint64_pair_t pair;
258 zbx_vector_uint64_t eventids;
259 int read_tags;
260 const char *tag_fields, *tag_join;
261
262 if (SUCCEED == (read_tags = zbx_dc_maintenance_has_tags()))
263 {
264 tag_fields = "t.tag,t.value";
265 tag_join = " left join problem_tag t on p.eventid=t.eventid";
266 }
267 else
268 {
269 tag_fields = "null,null";
270 tag_join = "";
271 }
272
273 /* get open or recently closed problems */
274 result = DBselect("select p.eventid,p.objectid,p.r_eventid,%s"
275 " from problem p"
276 "%s"
277 " where p.source=%d"
278 " and p.object=%d"
279 " and " ZBX_SQL_MOD(p.eventid, %d) "=%d"
280 " order by p.eventid",
281 tag_fields, tag_join,
282 EVENT_SOURCE_TRIGGERS, EVENT_OBJECT_TRIGGER, CONFIG_TIMER_FORKS, process_num - 1);
283
284 event_queries_fetch(result, event_queries);
285 DBfree_result(result);
286
287 /* get event suppress data */
288
289 zbx_vector_uint64_create(&eventids);
290
291 result = DBselect("select eventid,maintenanceid,suppress_until"
292 " from event_suppress"
293 " where " ZBX_SQL_MOD(eventid, %d) "=%d"
294 " order by eventid",
295 CONFIG_TIMER_FORKS, process_num - 1);
296
297 while (NULL != (row = DBfetch(result)))
298 {
299 ZBX_STR2UINT64(eventid, row[0]);
300
301 if (FAIL == zbx_vector_ptr_bsearch(event_queries, &eventid, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC))
302 zbx_vector_uint64_append(&eventids, eventid);
303
304 if (NULL == data || data->eventid != eventid)
305 {
306 data = (zbx_event_suppress_data_t *)zbx_malloc(NULL, sizeof(zbx_event_suppress_data_t));
307 data->eventid = eventid;
308 zbx_vector_uint64_pair_create(&data->maintenances);
309 zbx_vector_ptr_append(event_data, data);
310 }
311
312 ZBX_DBROW2UINT64(pair.first, row[1]);
313 pair.second = atoi(row[2]);
314 zbx_vector_uint64_pair_append(&data->maintenances, pair);
315 }
316 DBfree_result(result);
317
318 /* get missing event data */
319
320 if (0 != eventids.values_num)
321 {
322 int i;
323
324 if (SUCCEED == read_tags)
325 {
326 tag_fields = "t.tag,t.value";
327 tag_join = " left join event_tag t on e.eventid=t.eventid";
328 }
329
330 zbx_vector_uint64_uniq(&eventids, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
331
332 for (i = 0; i < eventids.values_num; i += ZBX_EVENT_BATCH_SIZE)
333 {
334 char *sql = NULL;
335 size_t sql_alloc = 0, sql_offset = 0;
336
337 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
338 "select e.eventid,e.objectid,er.r_eventid,%s"
339 " from events e"
340 " left join event_recovery er"
341 " on e.eventid=er.eventid"
342 "%s"
343 " where",
344 tag_fields, tag_join);
345 DBadd_condition_alloc(&sql, &sql_alloc, &sql_offset, "e.eventid",
346 eventids.values + i, MIN(eventids.values_num - i, ZBX_EVENT_BATCH_SIZE));
347 zbx_strcpy_alloc(&sql, &sql_alloc, &sql_offset, " order by e.eventid");
348
349 result = DBselect("%s", sql);
350 zbx_free(sql);
351
352 event_queries_fetch(result, event_queries);
353 DBfree_result(result);
354 }
355
356 zbx_vector_ptr_sort(event_queries, ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC);
357 }
358
359 zbx_vector_uint64_destroy(&eventids);
360 }
361
362 /******************************************************************************
363 * *
364 * Function: db_update_event_suppress_data *
365 * *
366 * Purpose: create/update event suppress data to reflect latest maintenance *
367 * changes in cache *
368 * *
369 * Parameters: suppressed_num - [OUT] the number of suppressed events *
370 * *
371 ******************************************************************************/
db_update_event_suppress_data(int * suppressed_num)372 static void db_update_event_suppress_data(int *suppressed_num)
373 {
374 zbx_vector_ptr_t event_queries, event_data;
375
376 *suppressed_num = 0;
377
378 zbx_vector_ptr_create(&event_queries);
379 zbx_vector_ptr_create(&event_data);
380
381 db_get_query_events(&event_queries, &event_data);
382
383 if (0 != event_queries.values_num)
384 {
385 zbx_db_insert_t db_insert;
386 char *sql = NULL;
387 size_t sql_alloc = 0, sql_offset = 0;
388 int i, j, k;
389 zbx_event_suppress_query_t *query;
390 zbx_event_suppress_data_t *data;
391 zbx_vector_uint64_pair_t del_event_maintenances;
392 zbx_vector_uint64_t maintenanceids;
393 zbx_uint64_pair_t pair;
394
395 zbx_vector_uint64_create(&maintenanceids);
396 zbx_vector_uint64_pair_create(&del_event_maintenances);
397
398 zbx_dc_get_running_maintenanceids(&maintenanceids);
399
400 DBbegin();
401
402 if (0 != maintenanceids.values_num && SUCCEED == zbx_db_lock_maintenanceids(&maintenanceids))
403 zbx_dc_get_event_maintenances(&event_queries, &maintenanceids);
404
405 zbx_db_insert_prepare(&db_insert, "event_suppress", "event_suppressid", "eventid", "maintenanceid",
406 "suppress_until", NULL);
407 DBbegin_multiple_update(&sql, &sql_alloc, &sql_offset);
408
409 for (i = 0; i < event_queries.values_num; i++)
410 {
411 query = (zbx_event_suppress_query_t *)event_queries.values[i];
412 zbx_vector_uint64_pair_sort(&query->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
413
414 k = 0;
415
416 if (FAIL != (j = zbx_vector_ptr_bsearch(&event_data, &query->eventid,
417 ZBX_DEFAULT_UINT64_PTR_COMPARE_FUNC)))
418 {
419 data = (zbx_event_suppress_data_t *)event_data.values[j];
420 zbx_vector_uint64_pair_sort(&data->maintenances, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
421
422 j = 0;
423
424 while (j < data->maintenances.values_num && k < query->maintenances.values_num)
425 {
426 if (data->maintenances.values[j].first < query->maintenances.values[k].first)
427 {
428 pair.first = query->eventid;
429 pair.second = data->maintenances.values[j].first;
430 zbx_vector_uint64_pair_append(&del_event_maintenances, pair);
431
432 j++;
433 continue;
434 }
435
436 if (data->maintenances.values[j].first > query->maintenances.values[k].first)
437 {
438 if (0 == query->r_eventid)
439 {
440 zbx_db_insert_add_values(&db_insert, __UINT64_C(0),
441 query->eventid,
442 query->maintenances.values[k].first,
443 (int)query->maintenances.values[k].second);
444
445 (*suppressed_num)++;
446 }
447
448 k++;
449 continue;
450 }
451
452 if (data->maintenances.values[j].second != query->maintenances.values[k].second)
453 {
454 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
455 "update event_suppress"
456 " set suppress_until=%d"
457 " where eventid=" ZBX_FS_UI64
458 " and maintenanceid=" ZBX_FS_UI64 ";\n",
459 (int)query->maintenances.values[k].second,
460 query->eventid,
461 query->maintenances.values[k].first);
462
463 if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
464 goto cleanup;
465 }
466 j++;
467 k++;
468 }
469
470 for (;j < data->maintenances.values_num; j++)
471 {
472 pair.first = query->eventid;
473 pair.second = data->maintenances.values[j].first;
474 zbx_vector_uint64_pair_append(&del_event_maintenances, pair);
475 }
476 }
477
478 if (0 == query->r_eventid)
479 {
480 for (;k < query->maintenances.values_num; k++)
481 {
482 zbx_db_insert_add_values(&db_insert, __UINT64_C(0), query->eventid,
483 query->maintenances.values[k].first,
484 (int)query->maintenances.values[k].second);
485
486 (*suppressed_num)++;
487 }
488 }
489 }
490
491 for (i = 0; i < del_event_maintenances.values_num; i++)
492 {
493 zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
494 "delete from event_suppress"
495 " where eventid=" ZBX_FS_UI64
496 " and maintenanceid=" ZBX_FS_UI64 ";\n",
497 del_event_maintenances.values[i].first,
498 del_event_maintenances.values[i].second);
499
500 if (FAIL == DBexecute_overflowed_sql(&sql, &sql_alloc, &sql_offset))
501 goto cleanup;
502 }
503
504 DBend_multiple_update(&sql, &sql_alloc, &sql_offset);
505
506 if (16 < sql_offset)
507 {
508 if (ZBX_DB_OK > DBexecute("%s", sql))
509 goto cleanup;
510 }
511
512 zbx_db_insert_autoincrement(&db_insert, "event_suppressid");
513 zbx_db_insert_execute(&db_insert);
514 cleanup:
515 DBcommit();
516
517 zbx_db_insert_clean(&db_insert);
518 zbx_free(sql);
519
520 zbx_vector_uint64_pair_destroy(&del_event_maintenances);
521 zbx_vector_uint64_destroy(&maintenanceids);
522 }
523
524 zbx_vector_ptr_clear_ext(&event_data, (zbx_clean_func_t)event_suppress_data_free);
525 zbx_vector_ptr_destroy(&event_data);
526
527 zbx_vector_ptr_clear_ext(&event_queries, (zbx_clean_func_t)zbx_event_suppress_query_free);
528 zbx_vector_ptr_destroy(&event_queries);
529 }
530
531 /******************************************************************************
532 * *
533 * Function: db_update_host_maintenances *
534 * *
535 * Purpose: update host maintenance parameters in cache and database *
536 * *
537 ******************************************************************************/
update_host_maintenances(void)538 static int update_host_maintenances(void)
539 {
540 zbx_vector_uint64_t maintenanceids;
541 zbx_vector_ptr_t updates;
542 int hosts_num = 0;
543 int tnx_error;
544
545 zbx_vector_uint64_create(&maintenanceids);
546 zbx_vector_ptr_create(&updates);
547 zbx_vector_ptr_reserve(&updates, 100);
548
549 do
550 {
551 DBbegin();
552
553 if (SUCCEED == zbx_dc_get_running_maintenanceids(&maintenanceids))
554 zbx_db_lock_maintenanceids(&maintenanceids);
555
556 /* host maintenance update must be called even with no maintenances running */
557 /* to reset host maintenance status if necessary */
558 zbx_dc_get_host_maintenance_updates(&maintenanceids, &updates);
559
560 if (0 != updates.values_num)
561 db_update_host_maintenances(&updates);
562
563 if (ZBX_DB_OK == (tnx_error = DBcommit()) && 0 != (hosts_num = updates.values_num))
564 zbx_dc_flush_host_maintenance_updates(&updates);
565
566 zbx_vector_ptr_clear_ext(&updates, (zbx_clean_func_t)zbx_ptr_free);
567 zbx_vector_uint64_clear(&maintenanceids);
568 }
569 while (ZBX_DB_DOWN == tnx_error);
570
571 zbx_vector_ptr_destroy(&updates);
572 zbx_vector_uint64_destroy(&maintenanceids);
573
574 return hosts_num;
575 }
576
577 /******************************************************************************
578 * *
579 * Function: timer_thread *
580 * *
581 * Purpose: periodically processes maintenance *
582 * *
583 ******************************************************************************/
ZBX_THREAD_ENTRY(timer_thread,args)584 ZBX_THREAD_ENTRY(timer_thread, args)
585 {
586 double sec;
587 int maintenance_time = 0, update_time = 0, idle = 1, events_num, hosts_num, update;
588 char *info = NULL;
589 size_t info_alloc = 0, info_offset = 0;
590
591 process_type = ((zbx_thread_args_t *)args)->process_type;
592 server_num = ((zbx_thread_args_t *)args)->server_num;
593 process_num = ((zbx_thread_args_t *)args)->process_num;
594
595 zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type),
596 server_num, get_process_type_string(process_type), process_num);
597
598 update_selfmon_counter(ZBX_PROCESS_STATE_BUSY);
599
600 zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num);
601 zbx_strcpy_alloc(&info, &info_alloc, &info_offset, "started");
602
603 DBconnect(ZBX_DB_CONNECT_NORMAL);
604
605 while (ZBX_IS_RUNNING())
606 {
607 sec = zbx_time();
608 zbx_update_env(sec);
609
610 if (1 == process_num)
611 {
612 /* start update process only when all timers have finished their updates */
613 if (sec - maintenance_time >= ZBX_TIMER_DELAY && FAIL == zbx_dc_maintenance_check_update_flags())
614 {
615 zbx_setproctitle("%s #%d [%s, processing maintenances]",
616 get_process_type_string(process_type), process_num, info);
617
618 update = zbx_dc_update_maintenances();
619
620 /* force maintenance updates at server startup */
621 if (0 == maintenance_time)
622 update = SUCCEED;
623
624 /* update hosts if there are modified (stopped, started, changed) maintenances */
625 if (SUCCEED == update)
626 hosts_num = update_host_maintenances();
627 else
628 hosts_num = 0;
629
630 db_remove_expired_event_suppress_data((int)sec);
631
632 if (SUCCEED == update)
633 {
634 zbx_dc_maintenance_set_update_flags();
635 db_update_event_suppress_data(&events_num);
636 zbx_dc_maintenance_reset_update_flag(process_num);
637 }
638 else
639 events_num = 0;
640
641 info_offset = 0;
642 zbx_snprintf_alloc(&info, &info_alloc, &info_offset,
643 "updated %d hosts, suppressed %d events in " ZBX_FS_DBL " sec",
644 hosts_num, events_num, zbx_time() - sec);
645
646 update_time = (int)sec;
647 }
648 }
649 else if (SUCCEED == zbx_dc_maintenance_check_update_flag(process_num))
650 {
651 zbx_setproctitle("%s #%d [%s, processing maintenances]", get_process_type_string(process_type),
652 process_num, info);
653
654 db_update_event_suppress_data(&events_num);
655
656 info_offset = 0;
657 zbx_snprintf_alloc(&info, &info_alloc, &info_offset, "suppressed %d events in " ZBX_FS_DBL
658 " sec", events_num, zbx_time() - sec);
659
660 update_time = (int)sec;
661 zbx_dc_maintenance_reset_update_flag(process_num);
662 }
663
664 if (maintenance_time != update_time)
665 {
666 update_time -= update_time % 60;
667 maintenance_time = update_time;
668
669 if (0 > (idle = ZBX_TIMER_DELAY - (zbx_time() - maintenance_time)))
670 idle = 0;
671
672 zbx_setproctitle("%s #%d [%s, idle %d sec]",
673 get_process_type_string(process_type), process_num, info, idle);
674 }
675
676 if (0 != idle)
677 zbx_sleep_loop(1);
678
679 idle = 1;
680 }
681
682 zbx_setproctitle("%s #%d [terminated]", get_process_type_string(process_type), process_num);
683
684 while (1)
685 zbx_sleep(SEC_PER_MIN);
686 }
687