void child_trapper_main(zbx_process_t p, zbx_sock_t *s) { struct sigaction phan; zabbix_log( LOG_LEVEL_DEBUG, "In child_trapper_main()"); phan.sa_handler = child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = 0; sigaction(SIGALRM, &phan, NULL); zbx_process = p; DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("trapper [waiting for connection]"); if (SUCCEED == zbx_tcp_accept(s)) { zbx_setproctitle("trapper [processing data]"); process_trapper_child(s); zbx_tcp_unaccept(s); } else zabbix_log(LOG_LEVEL_WARNING, "Trapper failed to accept connection"); } DBclose(); }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ void main_watchdog_loop() { int now, nextsync = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_watchdog_loop()"); /* disable writing to database in zabbix_syslog() */ CONFIG_ENABLE_LOG = 0; zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; } DBclose(); zbx_sleep_loop(DB_PING_FREQUENCY); } }
/****************************************************************************** * * * Function: main_snmptrapper_loop * * * * Purpose: SNMP trap reader's entry point * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ void main_snmptrapper_loop() { const char *__function_name = "main_snmptrapper_loop"; zabbix_log(LOG_LEVEL_DEBUG, "In %s() trapfile:'%s'", __function_name, CONFIG_SNMPTRAP_FILE); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); DBget_lastsize(); for (;;) { zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); while (SUCCEED == get_latest_data()) read_traps(); zbx_sleep_loop(1); } if (-1 != trap_fd) close(trap_fd); }
void main_poller_loop(unsigned char poller_type) { int nextcheck, sleeptime, processed; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_poller_loop() process_type:'%s' process_num:%d", get_process_type_string(process_type), process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [getting values]", get_process_type_string(process_type)); sec = zbx_time(); processed = get_values(poller_type); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while updating %d values", get_process_type_string(process_type), process_num, sec, processed); nextcheck = DCconfig_get_poller_nextcheck(poller_type); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_httppoller_loop * * * * Purpose: main loop of processing of httptests * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_httppoller_loop() { int now, nextcheck, sleeptime; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_httppoller_loop() process_num:%d", process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [getting values]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_httptests(process_num, now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while updating HTTP tests", get_process_type_string(process_type), process_num, sec); nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_discoverer_loop * * * * Purpose: periodically try to find new hosts and services * * * * Author: Alexei Vladishev * * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_discoverer_loop() { int now, nextcheck, sleeptime; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_discoverer_loop() process_num:%d", process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [performing discovery]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_discovery(now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing rules", get_process_type_string(process_type), process_num, sec); nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, DISCOVERER_DELAY); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_pinger_loop * * * * Purpose: periodically perform ICMP pings * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_pinger_loop(void) { int nextcheck, sleeptime; double sec; static icmpitem_t *items = NULL; static int items_alloc = 4; int items_count = 0, itc; if (NULL == items) items = zbx_malloc(items, sizeof(icmpitem_t) * items_alloc); for (;;) { zbx_setproctitle("%s #%d [getting values]", get_process_type_string(process_type), process_num); sec = zbx_time(); get_pinger_hosts(&items, &items_alloc, &items_count); process_pinger_hosts(items, items_count); sec = zbx_time() - sec; itc = items_count; free_hosts(&items, &items_count); nextcheck = DCconfig_get_poller_nextcheck(ZBX_POLLER_TYPE_PINGER); sleeptime = calculate_sleeptime(nextcheck, POLLER_DELAY); zbx_setproctitle("%s #%d [got %d values in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, itc, sec, sleeptime); zbx_sleep_loop(sleeptime); } }
void main_housekeeper_loop(void) { int records, start, sleeptime; double sec; for (;;) { start = time(NULL); zabbix_log(LOG_LEVEL_WARNING, "executing housekeeper"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_setproctitle("%s [removing old history]", get_process_type_string(process_type)); sec = zbx_time(); records = housekeeping_history(start); sec = zbx_time() - sec; DBclose(); sleeptime = CONFIG_HOUSEKEEPING_FREQUENCY * SEC_PER_HOUR - (time(NULL) - start); zabbix_log(LOG_LEVEL_WARNING, "%s [deleted %d records in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, sleeptime); zbx_setproctitle("%s [deleted %d records in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, sleeptime); zbx_sleep_loop(sleeptime); } }
/****************************************************************************** * * * Function: main_escalator_loop * * * * Purpose: periodically check table escalations and generate alerts * * * * Parameters: * * * * Return value: * * * * Author: Aleksander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ int main_escalator_loop() { int now/*, nextcheck, sleeptime*/; double sec; struct sigaction phan; zabbix_log(LOG_LEVEL_DEBUG, "In main_escalator_loop()"); /* phan.sa_handler = child_signal_handler;*/ phan.sa_sigaction = child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = SA_SIGINFO; sigaction(SIGALRM, &phan, NULL); zbx_setproctitle("escalator [connecting to the database]"); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { now = time(NULL); sec = zbx_time(); zbx_setproctitle("escalator [processing escalations]"); process_escalations(now); sec = zbx_time() - sec; /* nextcheck = get_minnextcheck(); if (FAIL == nextcheck) sleeptime = CONFIG_ESCALATOR_FREQUENCY; else { sleeptime = nextcheck - time(NULL); if (sleeptime < 0) sleeptime = 0; else if (sleeptime > CONFIG_ESCALATOR_FREQUENCY) sleeptime = CONFIG_ESCALATOR_FREQUENCY; }*/ zabbix_log(LOG_LEVEL_DEBUG, "Escalator spent " ZBX_FS_DBL " seconds while processing escalation items." " Nextcheck after %d sec.", sec, CONFIG_ESCALATOR_FREQUENCY); zbx_setproctitle("escalator [sleeping for %d seconds]", CONFIG_ESCALATOR_FREQUENCY); sleep(CONFIG_ESCALATOR_FREQUENCY); /* if (sleeptime > 0) { zbx_setproctitle("escalator [sleeping for %d seconds]", sleeptime); sleep(sleeptime); }*/ } /* Never reached */ DBclose(); }
void main_trapper_loop(zbx_sock_t *s) { const char *__function_name = "main_trapper_loop"; zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [waiting for connection]", get_process_type_string(process_type)); update_selfmon_counter(ZBX_PROCESS_STATE_IDLE); if (SUCCEED == zbx_tcp_accept(s)) { update_selfmon_counter(ZBX_PROCESS_STATE_BUSY); zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); process_trapper_child(s); zbx_tcp_unaccept(s); } else zabbix_log(LOG_LEVEL_WARNING, "Trapper failed to accept connection"); } }
/****************************************************************************** * * * Function: main_escalator_loop * * * * Purpose: periodically check table escalations and generate alerts * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_escalator_loop() { int now; double sec; zabbix_log(LOG_LEVEL_DEBUG, "In main_escalator_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [processing escalations]", get_process_type_string(process_type)); now = time(NULL); sec = zbx_time(); process_escalations(now); sec = zbx_time() - sec; zabbix_log(LOG_LEVEL_DEBUG, "%s #%d spent " ZBX_FS_DBL " seconds while processing escalations", get_process_type_string(process_type), process_num, sec); zbx_sleep_loop(CONFIG_ESCALATOR_FREQUENCY); } }
/****************************************************************************** * * * Function: main_nodewatcher_loop * * * * Purpose: periodically calculates checksum of config data * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_nodewatcher_loop() { int start, end; int lastrun = 0; zabbix_log(LOG_LEVEL_DEBUG, "In main_nodewatcher_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [exchanging data]", get_process_type_string(process_type)); start = time(NULL); zabbix_log(LOG_LEVEL_DEBUG, "Starting sync with nodes"); if (lastrun + 120 < start) { process_nodes(); lastrun = start; } /* send new history data to master node */ main_historysender(); end = time(NULL); zbx_sleep_loop(10 - (end - start)); } }
/****************************************************************************** * * * Function: main_dbconfig_loop * * * * Purpose: periodically synchronises database data with memory cache * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_dbconfig_loop(void) { double sec = 0.0; zbx_setproctitle("%s [waiting %d sec for processes]", get_process_type_string(process_type), CONFIG_CONFSYNCER_FREQUENCY); /* the initial configuration sync is done by server before worker processes are forked */ zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, syncing configuration]", get_process_type_string(process_type), sec); sec = zbx_time(); DCsync_configuration(); sec = zbx_time() - sec; zbx_setproctitle("%s [synced configuration in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, CONFIG_CONFSYNCER_FREQUENCY); zbx_sleep_loop(CONFIG_CONFSYNCER_FREQUENCY); } }
ZBX_THREAD_ENTRY(trapper_thread, args) { double sec = 0.0; zbx_socket_t s; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); memcpy(&s, (zbx_socket_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_socket_t)); #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) zbx_tls_init_child(); find_psk_in_cache = DCget_psk_by_identity; #endif zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_handle_log(); zbx_setproctitle("%s #%d [processed data in " ZBX_FS_DBL " sec, waiting for connection]", get_process_type_string(process_type), process_num, sec); update_selfmon_counter(ZBX_PROCESS_STATE_IDLE); /* Trapper has to accept all types of connections it can accept with the specified configuration. */ /* Only after receiving data it is known who has sent them and one can decide to accept or discard */ /* the data. */ if (SUCCEED == zbx_tcp_accept(&s, ZBX_TCP_SEC_TLS_CERT | ZBX_TCP_SEC_TLS_PSK | ZBX_TCP_SEC_UNENCRYPTED)) { zbx_timespec_t ts; /* get connection timestamp */ zbx_timespec(&ts); update_selfmon_counter(ZBX_PROCESS_STATE_BUSY); zbx_setproctitle("%s #%d [processing data]", get_process_type_string(process_type), process_num); sec = zbx_time(); process_trapper_child(&s, &ts); sec = zbx_time() - sec; zbx_tcp_unaccept(&s); } else if (EINTR != zbx_socket_last_error()) { zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming connection: %s", zbx_socket_strerror()); } } }
/****************************************************************************** * * * Function: main_datasender_loop * * * * Purpose: periodically sends history and events to the server * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ ZBX_THREAD_ENTRY(datasender_thread, args) { int records = 0, r; double sec = 0.0; struct zbx_json j; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); zbx_json_init(&j, 16 * ZBX_KIBIBYTE); for (;;) { zbx_setproctitle("%s [sent %d values in " ZBX_FS_DBL " sec, sending data]", get_process_type_string(process_type), records, sec); sec = zbx_time(); host_availability_sender(&j); records = 0; retry_history: history_sender(&j, &r, ZBX_PROTO_VALUE_HISTORY_DATA, proxy_get_hist_data, proxy_set_hist_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_history; retry_dhistory: history_sender(&j, &r, ZBX_PROTO_VALUE_DISCOVERY_DATA, proxy_get_dhis_data, proxy_set_dhis_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_dhistory; retry_autoreg_host: history_sender(&j, &r, ZBX_PROTO_VALUE_AUTO_REGISTRATION_DATA, proxy_get_areg_data, proxy_set_areg_lastid); records += r; if (ZBX_MAX_HRECORDS == r) goto retry_autoreg_host; sec = zbx_time() - sec; zbx_setproctitle("%s [sent %d values in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), records, sec, CONFIG_PROXYDATA_FREQUENCY); zbx_sleep_loop(CONFIG_PROXYDATA_FREQUENCY); } }
/****************************************************************************** * * * Function: main_timer_loop * * * * Purpose: periodically updates time-related triggers * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: does update once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_timer_loop() { int now, cur; /* int itemid,functionid; char *function; char *parameter;*/ DB_ITEM item; DB_RESULT result; DB_ROW row; for(;;) { zbx_setproctitle("Timer: updating nodata() functions"); DBconnect(ZBX_DB_CONNECT_NORMAL); now=time(NULL); /* #ifdef HAVE_POSTGRESQL zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter::text::integer<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #else zbx_snprintf(sql,sizeof(sql),"select distinct f.itemid,f.functionid,f.parameter,f.function from functions f, items i,hosts h where h.hostid=i.hostid and h.status=%d and i.itemid=f.itemid and f.function in ('nodata','date','dayofweek','time','now') and i.lastclock+f.parameter<=%d and i.status=%d", HOST_STATUS_MONITORED, now, ITEM_STATUS_ACTIVE); #endif */ result = DBselect("select %s, functions f where h.hostid=i.hostid and h.status=%d and i.status=%d and f.function in ('nodata','date','dayofweek','time','now','count') and i.itemid=f.itemid and " ZBX_COND_SITE, ZBX_SQL_ITEM_SELECT, HOST_STATUS_MONITORED, ITEM_STATUS_ACTIVE, getSiteCondition ()); cur = 1; while((row=DBfetch(result))) { #ifdef HAVE_MYSQL zbx_setproctitle("Timer: processing %d item of %d", cur++, result->row_count); #endif DBget_item_from_db(&item,row); DBbegin(); update_functions(&item); update_triggers(item.itemid); DBcommit(); DBfree_item(&item); } DBfree_result(result); DBclose(); zbx_setproctitle("Timer: sleeping for 10 sec"); sleep(10); } }
/****************************************************************************** * * * Function: main_heart_loop * * * * Purpose: periodically send heartbeat message to the server * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void main_heart_loop(void) { int start, sleeptime = 0, res; double sec, total_sec = 0.0, old_total_sec = 0.0; time_t last_stat_time; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ last_stat_time = time(NULL); zbx_setproctitle("%s [sending heartbeat message]", get_process_type_string(process_type)); for (;;) { if (0 != sleeptime) { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "sending heartbeat message]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", old_total_sec); } start = time(NULL); sec = zbx_time(); res = send_heartbeat(); total_sec += zbx_time() - sec; sleeptime = CONFIG_HEARTBEAT_FREQUENCY - (time(NULL) - start); if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time) { if (0 == sleeptime) { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "sending heartbeat message]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", total_sec); } else { zbx_setproctitle("%s [sending heartbeat message %s in " ZBX_FS_DBL " sec, " "idle %d sec]", get_process_type_string(process_type), SUCCEED == res ? "success" : "failed", total_sec, sleeptime); old_total_sec = total_sec; } total_sec = 0.0; last_stat_time = time(NULL); } zbx_sleep_loop(sleeptime); } #undef STAT_INTERVAL }
/****************************************************************************** * * * Function: main_discoverer_loop * * * * Purpose: periodically try to find new hosts and services * * * * Author: Alexei Vladishev * * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_discoverer_loop(void) { int now, nextcheck, sleeptime = -1, rule_count = 0, old_rule_count = 0; double sec, total_sec = 0.0, old_total_sec = 0.0; time_t last_stat_time; #define STAT_INTERVAL 5 /* if a process is busy and does not sleep then update status not faster than */ /* once in STAT_INTERVAL seconds */ zbx_setproctitle("%s #%d [connecting to the database]", get_process_type_string(process_type), process_num); last_stat_time = time(NULL); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { if (0 != sleeptime) { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, performing discovery]", get_process_type_string(process_type), process_num, old_rule_count, old_total_sec); } now = time(NULL); sec = zbx_time(); rule_count += process_discovery(now); total_sec += zbx_time() - sec; nextcheck = get_minnextcheck(now); sleeptime = calculate_sleeptime(nextcheck, DISCOVERER_DELAY); if (0 != sleeptime || STAT_INTERVAL <= time(NULL) - last_stat_time) { if (0 == sleeptime) { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, performing " "discovery]", get_process_type_string(process_type), process_num, rule_count, total_sec); } else { zbx_setproctitle("%s #%d [processed %d rules in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), process_num, rule_count, total_sec, sleeptime); old_rule_count = rule_count; old_total_sec = total_sec; } rule_count = 0; total_sec = 0.0; last_stat_time = time(NULL); } zbx_sleep_loop(sleeptime); } #undef STAT_INTERVAL }
/****************************************************************************** * * * Function: main_watchdog_loop * * * * Purpose: check database availability every DB_PING_FREQUENCY seconds and * * alert admins if it is down * * * * Author: Alexei Vladishev, Rudolfs Kreicbergs * * * ******************************************************************************/ ZBX_THREAD_ENTRY(watchdog_thread, args) { int now, nextsync = 0, action; double sec; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); zbx_vector_ptr_create(&recipients); for (;;) { zbx_setproctitle("%s [pinging database]", get_process_type_string(process_type)); sec = zbx_time(); action = 0; if (ZBX_DB_OK != DBconnect(ZBX_DB_CONNECT_ONCE)) { zabbix_log(LOG_LEVEL_WARNING, "watchdog: database is down"); send_alerts(); action = 1; } else if (nextsync <= (now = (int)time(NULL))) { zbx_setproctitle("%s [syncing configuration]", get_process_type_string(process_type)); sync_config(); nextsync = now + CONFIG_CONFSYNCER_FREQUENCY; action = 2; } DBclose(); sec = zbx_time() - sec; if (1 == action) { zbx_setproctitle("%s [database is down, checking took " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } else if (2 == action) { zbx_setproctitle("%s [synced alerts config in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), sec, (int)DB_PING_FREQUENCY); } zbx_sleep_loop(DB_PING_FREQUENCY); } }
ZBX_THREAD_ENTRY(listener_thread, args) { int ret, local_request_failed = 0; zbx_sock_t s; assert(args); assert(((zbx_thread_args_t *)args)->args); process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_daemon_type_string(daemon_type), server_num, get_process_type_string(process_type), process_num); memcpy(&s, (zbx_sock_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_sock_t)); zbx_free(args); while (ZBX_IS_RUNNING()) { zbx_setproctitle("listener #%d [waiting for connection]", process_num); if (SUCCEED == (ret = zbx_tcp_accept(&s))) { local_request_failed = 0; /* reset consecutive errors counter */ zbx_setproctitle("listener #%d [processing request]", process_num); if (SUCCEED == (ret = zbx_tcp_check_security(&s, CONFIG_HOSTS_ALLOWED, 0))) process_listener(&s); zbx_tcp_unaccept(&s); } if (SUCCEED == ret || EINTR == zbx_sock_last_error()) continue; zabbix_log(LOG_LEVEL_DEBUG, "failed to accept an incoming connection: %s", zbx_tcp_strerror()); if (local_request_failed++ > 1000) { zabbix_log(LOG_LEVEL_WARNING, "too many failures to accept an incoming connection"); local_request_failed = 0; } if (ZBX_IS_RUNNING()) zbx_sleep(1); } #ifdef _WINDOWS ZBX_DO_EXIT(); zbx_thread_exit(EXIT_SUCCESS); #endif }
void main_poller_loop(zbx_process_t p, int type, int num) { struct sigaction phan; int now; int nextcheck, sleeptime; int items; double sec; zabbix_log( LOG_LEVEL_DEBUG, "In main_poller_loop(type:%d,num:%d)", type, num); /* phan.sa_handler = child_signal_handler;*/ phan.sa_sigaction = child_signal_handler; sigemptyset(&phan.sa_mask); phan.sa_flags = SA_SIGINFO; sigaction(SIGALRM, &phan, NULL); zbx_process = p; poller_type = type; poller_num = num; DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("poller [getting values]"); now = time(NULL); sec = zbx_time(); items = get_values(now, &nextcheck); sec = zbx_time() - sec; if (FAIL == nextcheck) sleeptime = POLLER_DELAY; else { sleeptime = nextcheck - time(NULL); if (sleeptime < 0) sleeptime = 0; if (sleeptime > POLLER_DELAY) sleeptime = POLLER_DELAY; } zabbix_log(LOG_LEVEL_DEBUG, "Poller spent " ZBX_FS_DBL " seconds while updating %3d values." " Sleeping for %d seconds", sec, items, sleeptime); if (sleeptime > 0) { zbx_setproctitle("poller [sleeping for %d seconds]", sleeptime); sleep(sleeptime); } } }
ZBX_THREAD_ENTRY(listener_thread, args) { int ret, local_request_failed = 0; zbx_sock_t s; assert(args); assert(((zbx_thread_args_t *)args)->args); zabbix_log(LOG_LEVEL_WARNING, "agent #%d started [listener]", ((zbx_thread_args_t *)args)->thread_num); memcpy(&s, (zbx_sock_t *)((zbx_thread_args_t *)args)->args, sizeof(zbx_sock_t)); zbx_free(args); while (ZBX_IS_RUNNING()) { zbx_setproctitle("listener [waiting for connection]"); if (SUCCEED == (ret = zbx_tcp_accept(&s))) { local_request_failed = 0; /* reset consecutive errors counter */ zbx_setproctitle("listener [processing request]"); zabbix_log(LOG_LEVEL_DEBUG, "Processing request."); if (SUCCEED == (ret = zbx_tcp_check_security(&s, CONFIG_HOSTS_ALLOWED, 0))) process_listener(&s); zbx_tcp_unaccept(&s); } if (SUCCEED == ret) continue; zabbix_log(LOG_LEVEL_DEBUG, "Listener error: %s", zbx_tcp_strerror()); if (local_request_failed++ > 1000) { zabbix_log(LOG_LEVEL_WARNING, "Too many consecutive errors on accept() call."); local_request_failed = 0; } if (ZBX_IS_RUNNING()) zbx_sleep(1); } #ifdef _WINDOWS zabbix_log(LOG_LEVEL_INFORMATION, "zabbix_agentd listener stopped"); ZBX_DO_EXIT(); zbx_thread_exit(0); #endif }
ZBX_THREAD_ENTRY(listener_thread, pSock) { int ret, local_request_failed = 0; zbx_sock_t s; assert(pSock); zbx_setproctitle("listener waiting for connection"); zabbix_log( LOG_LEVEL_INFORMATION, "zabbix_agentd listener started"); memcpy(&s, ((zbx_sock_t *)pSock), sizeof(zbx_sock_t)); while(ZBX_IS_RUNNING) { if( SUCCEED == (ret = zbx_tcp_accept(&s)) ) { local_request_failed = 0; /* Reset consecutive errors counter */ zbx_setproctitle("processing request"); zabbix_log(LOG_LEVEL_DEBUG, "Processing request."); if( SUCCEED == (ret = zbx_tcp_check_security(&s, CONFIG_HOSTS_ALLOWED, 0)) ) { process_listener(&s); } zbx_tcp_unaccept(&s); } zbx_setproctitle("listener waiting for connection"); if( SUCCEED == ret ) continue; zabbix_log(LOG_LEVEL_DEBUG, "Listener error: %s", zbx_tcp_strerror()); if (local_request_failed++ > 1000) { zabbix_log( LOG_LEVEL_WARNING, "Too many consecutive errors on accept() call."); local_request_failed = 0; } if(ZBX_IS_RUNNING) zbx_sleep(1); } zabbix_log( LOG_LEVEL_INFORMATION, "zabbix_agentd listener stopped"); ZBX_DO_EXIT(); zbx_tread_exit(0); }
ZBX_THREAD_ENTRY(taskmanager_thread, args) { static int cleanup_time = 0; double sec1, sec2; int tasks_num, sleeptime, nextcheck; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) zbx_tls_init_child(); #endif zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); sec1 = zbx_time(); sleeptime = ZBX_TM_PROCESS_PERIOD - (int)sec1 % ZBX_TM_PROCESS_PERIOD; zbx_setproctitle("%s [started, idle %d sec]", get_process_type_string(process_type), sleeptime); for (;;) { zbx_sleep_loop(sleeptime); sec1 = zbx_time(); zbx_update_env(sec1); zbx_setproctitle("%s [processing tasks]", get_process_type_string(process_type)); tasks_num = tm_process_tasks((int)sec1); if (ZBX_TM_CLEANUP_PERIOD <= sec1 - cleanup_time) { tm_remove_old_tasks((int)sec1); cleanup_time = sec1; } sec2 = zbx_time(); nextcheck = (int)sec1 - (int)sec1 % ZBX_TM_PROCESS_PERIOD + ZBX_TM_PROCESS_PERIOD; if (0 > (sleeptime = nextcheck - (int)sec2)) sleeptime = 0; zbx_setproctitle("%s [processed %d task(s) in " ZBX_FS_DBL " sec, idle %d sec]", get_process_type_string(process_type), tasks_num, sec2 - sec1, sleeptime); } }
/****************************************************************************** * * * Function: main_nodewatcher_loop * * * * Purpose: periodically calculates checks sum of config data * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: never returns * * * ******************************************************************************/ int main_nodewatcher_loop() { int start, end; int lastrun = 0; zabbix_log( LOG_LEVEL_DEBUG, "In main_nodeupdater_loop()"); for(;;) { start = time(NULL); zbx_setproctitle("connecting to the database"); zabbix_log( LOG_LEVEL_DEBUG, "Starting sync with nodes"); DBconnect(ZBX_DB_CONNECT_NORMAL); #if 0 if(lastrun + 120 < start) { DBbegin(); calculate_checksums(); compare_checksums(); update_checksums(); /* Send configuration changes to required nodes */ main_nodesender(); DBcommit(); lastrun = start; } #endif /* Send new events to master node */ main_eventsender(); /* Send new history data to master node */ main_historysender(); DBclose(); end = time(NULL); if(end-start<10) { zbx_setproctitle("sender [sleeping for %d seconds]", 10-(end-start)); zabbix_log( LOG_LEVEL_DEBUG, "Sleeping %d seconds", 10-(end-start)); sleep(10-(end-start)); } } }
/****************************************************************************** * * * Function: zbx_sleep_loop * * * * Purpose: sleeping process * * * * Parameters: sleeptime - [IN] required sleeptime, in seconds * * * * Author: Alexander Vladishev * * * ******************************************************************************/ void zbx_sleep_loop(int sleeptime) { #ifdef HAVE_FUNCTION_SETPROCTITLE extern unsigned char process_type; const char *process_type_string; #endif if (0 >= sleeptime) return; sleep_remains = sleeptime; zabbix_log(LOG_LEVEL_DEBUG, "sleeping for %d seconds", sleep_remains); update_selfmon_counter(ZBX_PROCESS_STATE_IDLE); #ifdef HAVE_FUNCTION_SETPROCTITLE process_type_string = get_process_type_string(process_type); #endif do { #ifdef HAVE_FUNCTION_SETPROCTITLE zbx_setproctitle("%s [sleeping for %d seconds]", process_type_string, sleep_remains); #endif sleep(1); } while (0 < --sleep_remains); update_selfmon_counter(ZBX_PROCESS_STATE_BUSY); }
/****************************************************************************** * * * Function: zbx_sleep_loop * * * * Purpose: sleeping process * * * * Parameters: sleeptime - [IN] required sleeptime, in seconds * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: * * * ******************************************************************************/ void zbx_sleep_loop(int sleeptime) { #ifdef HAVE_FUNCTION_SETPROCTITLE extern unsigned char process_type; const char *process_type_string; #endif /* HAVE_FUNCTION_SETPROCTITLE */ if (sleeptime <= 0) return; zabbix_log(LOG_LEVEL_DEBUG, "sleeping for %d seconds", sleeptime); update_selfmon_counter(ZBX_PROCESS_STATE_IDLE); #ifdef HAVE_FUNCTION_SETPROCTITLE process_type_string = get_process_type_string(process_type); do { zbx_setproctitle("%s [sleeping for %d seconds]", process_type_string, sleeptime); sleep(1); } while (--sleeptime > 0); #else sleep(sleeptime); #endif /* HAVE_FUNCTION_SETPROCTITLE */ update_selfmon_counter(ZBX_PROCESS_STATE_BUSY); }
/****************************************************************************** * * * Function: main_discoverer_loop * * * * Purpose: periodically try to find new hosts and services * * * * Parameters: * * * * Return value: * * * * Author: Alexei Vladishev * * * * Comments: executes once per 30 seconds (hardcoded) * * * ******************************************************************************/ void main_discoverer_loop(int num) { int now; DB_RESULT result; DB_ROW row; DB_DRULE rule; zabbix_log( LOG_LEVEL_DEBUG, "In main_discoverer_loop(num:%d)", num); discoverer_num = num; DBconnect(ZBX_DB_CONNECT_NORMAL); for(;;) { zbx_setproctitle("Discoverer finding new hosts and services"); now=time(NULL); result = DBselect("select druleid,iprange,delay,nextcheck,name,status,siteid from drules where status=%d and nextcheck<=%d and " ZBX_SQL_MOD(druleid,%d) "=%d", DRULE_STATUS_MONITORED, now, CONFIG_DISCOVERER_FORKS, discoverer_num-1); while((row=DBfetch(result))) { memset(&rule, 0, sizeof(DB_DRULE)); ZBX_STR2UINT64(rule.druleid,row[0]); rule.iprange = row[1]; rule.delay = atoi(row[2]); rule.nextcheck = atoi(row[3]); rule.name = row[4]; rule.status = atoi(row[5]); ZBX_STR2UINT64(rule.siteid,row[6]); process_rule(&rule); } DBfree_result(result); zbx_setproctitle("Discoverer [sleeping for 30 sec]"); sleep(30); } DBclose(); }
/****************************************************************************** * * * Function: main_proxyconfig_loop * * * * Purpose: periodically request config data * * * * Parameters: * * * * Return value: * * * * Author: Alexander Vladishev * * * * Comments: never returns * * * ******************************************************************************/ void main_proxyconfig_loop() { zabbix_log(LOG_LEVEL_DEBUG, "In main_proxyconfig_loop()"); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); for (;;) { zbx_setproctitle("%s [loading configuration]", get_process_type_string(process_type)); process_configuration_sync(); zbx_sleep_loop(CONFIG_PROXYCONFIG_FREQUENCY); } }
/****************************************************************************** * * * Function: main_snmptrapper_loop * * * * Purpose: SNMP trap reader's entry point * * * * Author: Rudolfs Kreicbergs * * * ******************************************************************************/ ZBX_THREAD_ENTRY(snmptrapper_thread, args) { const char *__function_name = "main_snmptrapper_loop"; double sec; process_type = ((zbx_thread_args_t *)args)->process_type; server_num = ((zbx_thread_args_t *)args)->server_num; process_num = ((zbx_thread_args_t *)args)->process_num; zabbix_log(LOG_LEVEL_INFORMATION, "%s #%d started [%s #%d]", get_program_type_string(program_type), server_num, get_process_type_string(process_type), process_num); zabbix_log(LOG_LEVEL_DEBUG, "In %s() trapfile:'%s'", __function_name, CONFIG_SNMPTRAP_FILE); zbx_setproctitle("%s [connecting to the database]", get_process_type_string(process_type)); DBconnect(ZBX_DB_CONNECT_NORMAL); DBget_lastsize(); buffer = zbx_malloc(buffer, MAX_BUFFER_LEN); *buffer = '\0'; for (;;) { zbx_handle_log(); zbx_setproctitle("%s [processing data]", get_process_type_string(process_type)); sec = zbx_time(); while (SUCCEED == get_latest_data()) read_traps(); sec = zbx_time() - sec; zbx_setproctitle("%s [processed data in " ZBX_FS_DBL " sec, idle 1 sec]", get_process_type_string(process_type), sec); zbx_sleep_loop(1); } zbx_free(buffer); if (-1 != trap_fd) close(trap_fd); }