/****************************************************************************** * * * Function: zbx_thread_start * * * * Purpose: Start the handled function as "thread" * * * * Parameters: "thread" handle * * * * Return value: returns a handle to the newly created "thread", * * ZBX_THREAD_ERROR on an error * * * * Author: Eugene Grigorjev * * * * Comments: The zbx_thread_exit must be called from the handler! * * * ******************************************************************************/ ZBX_THREAD_HANDLE zbx_thread_start(ZBX_THREAD_ENTRY_POINTER(handler), zbx_thread_args_t *thread_args) { ZBX_THREAD_HANDLE thread = ZBX_THREAD_HANDLE_NULL; #ifdef _WINDOWS unsigned thrdaddr; /* NOTE: _beginthreadex returns 0 on failure, rather than 1 */ if (0 == (thread = (ZBX_THREAD_HANDLE)_beginthreadex(NULL, 0, handler, thread_args, 0, &thrdaddr))) { zabbix_log(LOG_LEVEL_CRIT, "failed to create a thread: %s", strerror_from_system(GetLastError())); thread = (ZBX_THREAD_HANDLE)ZBX_THREAD_ERROR; } #else if (0 == (thread = zbx_child_fork())) /* child process */ { (*handler)(thread_args); /* The zbx_thread_exit must be called from the handler. */ /* And in normal case the program will never reach this point. */ zbx_thread_exit(EXIT_SUCCESS); /* program will never reach this point */ } else if (-1 == thread) { zbx_error("failed to fork: %s", zbx_strerror(errno)); thread = (ZBX_THREAD_HANDLE)ZBX_THREAD_ERROR; } #endif return thread; }
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 }
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 }
/****************************************************************************** * * * Function: * * * * Purpose: * * * * Parameters: * * * * Return value: * * * * Comments: * * * ******************************************************************************/ ZBX_THREAD_ENTRY(monitor_thread, args) { assert(args); zabbix_log(LOG_LEVEL_INFORMATION, "jobarg_monitor #%d started [monitor]", ((zbx_thread_args_t *) args)->thread_num); zbx_free(args); DBconnect(ZBX_DB_CONNECT_NORMAL); CONFIG_SPAN_TIME = ja_schedule_load_span(); while (ZBX_IS_RUNNING()) { zbx_setproctitle("process monitor"); process_monitor(); zbx_sleep(CONFIG_JAMONITOR_INTERVAL); } zabbix_log(LOG_LEVEL_INFORMATION, "jobarg_monitor stopped"); zbx_thread_exit(0); }
/****************************************************************************** * * * Function: collector_thread * * * * Purpose: Collect system information * * * * Author: Eugene Grigorjev * * * ******************************************************************************/ ZBX_THREAD_ENTRY(collector_thread, args) { assert(args); zabbix_log(LOG_LEVEL_WARNING, "agent #%d started [collector]", ((zbx_thread_args_t *)args)->thread_num); zbx_free(args); if (SUCCEED != init_cpu_collector(&(collector->cpus))) free_cpu_collector(&(collector->cpus)); while (ZBX_IS_RUNNING()) { zbx_setproctitle("collector [processing data]"); #ifdef _WINDOWS collect_perfstat(); #else if (0 != CPU_COLLECTOR_STARTED(collector)) collect_cpustat(&(collector->cpus)); if (0 != DISKDEVICE_COLLECTOR_STARTED(collector)) collect_stats_diskdevices(); #endif #ifdef _AIX if (1 == collector->vmstat.enabled) collect_vmstat_data(&collector->vmstat); #endif zbx_setproctitle("collector [sleeping for 1 seconds]"); zbx_sleep(1); } if (CPU_COLLECTOR_STARTED(collector)) free_cpu_collector(&(collector->cpus)); #ifdef _WINDOWS free_perf_collector(); /* cpu_collector must be freed before perf_collector is freed */ #endif zabbix_log(LOG_LEVEL_INFORMATION, "zabbix_agentd collector stopped"); ZBX_DO_EXIT(); zbx_thread_exit(0); }
static ZBX_THREAD_ENTRY(send_value, args) { ZBX_THREAD_SENDVAL_ARGS *sentdval_args; zbx_sock_t sock; char *answer = NULL; int tcp_ret, ret = FAIL; assert(args); assert(((zbx_thread_args_t *)args)->args); sentdval_args = (ZBX_THREAD_SENDVAL_ARGS *)((zbx_thread_args_t *)args)->args; #if !defined(_WINDOWS) signal(SIGINT, send_signal_handler); signal(SIGTERM, send_signal_handler); signal(SIGQUIT, send_signal_handler); signal(SIGALRM, send_signal_handler); #endif if (SUCCEED == (tcp_ret = zbx_tcp_connect(&sock, CONFIG_SOURCE_IP, sentdval_args->server, sentdval_args->port, GET_SENDER_TIMEOUT))) { if (SUCCEED == (tcp_ret = zbx_tcp_send(&sock, sentdval_args->json.buffer))) { if (SUCCEED == (tcp_ret = zbx_tcp_recv(&sock, &answer))) { zabbix_log(LOG_LEVEL_DEBUG, "answer [%s]", answer); if (NULL == answer || SUCCEED != check_response(answer)) zabbix_log(LOG_LEVEL_WARNING, "incorrect answer from server [%s]", answer); else ret = SUCCEED; } } zbx_tcp_close(&sock); } if (FAIL == tcp_ret) zabbix_log(LOG_LEVEL_DEBUG, "send value error: %s", zbx_tcp_strerror()); zbx_thread_exit(ret); }
ZBX_THREAD_ENTRY(listener_thread, args) { #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) char *msg = NULL; #endif int ret; zbx_socket_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_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)); zbx_free(args); #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) zbx_tls_init_child(); #endif while (ZBX_IS_RUNNING()) { zbx_setproctitle("listener #%d [waiting for connection]", process_num); ret = zbx_tcp_accept(&s, configured_tls_accept_modes); zbx_update_env(zbx_time()); if (SUCCEED == ret) { zbx_setproctitle("listener #%d [processing request]", process_num); if ('\0' != *CONFIG_HOSTS_ALLOWED && SUCCEED == (ret = zbx_tcp_check_allowed_peers(&s, CONFIG_HOSTS_ALLOWED))) { #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) if (ZBX_TCP_SEC_TLS_CERT != s.connection_type || SUCCEED == (ret = zbx_check_server_issuer_subject(&s, &msg))) #endif { process_listener(&s); } } zbx_tcp_unaccept(&s); } if (SUCCEED == ret || EINTR == zbx_socket_last_error()) continue; #if defined(HAVE_POLARSSL) || defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) if (NULL != msg) { zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming connection: %s", msg); zbx_free(msg); } else #endif { zabbix_log(LOG_LEVEL_WARNING, "failed to accept an incoming connection: %s", zbx_socket_strerror()); } if (ZBX_IS_RUNNING()) zbx_sleep(1); } #ifdef _WINDOWS ZBX_DO_EXIT(); zbx_thread_exit(EXIT_SUCCESS); #endif }