/****************************************************************************** * * * Function: user1_signal_handler * * * * Purpose: handle user signal SIGUSR1 * * * ******************************************************************************/ static void user1_signal_handler(int sig, siginfo_t *siginfo, void *context) { #ifdef HAVE_SIGQUEUE int flags; #endif SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d(0x%08x)].", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_uid), SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT), (unsigned int)SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT)); #ifdef HAVE_SIGQUEUE flags = SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT); if (!SIG_PARENT_PROCESS) { common_sigusr_handler(flags); return; } if (NULL == threads) { zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: shutdown in progress"); return; } switch (ZBX_RTC_GET_MSG(flags)) { case ZBX_RTC_CONFIG_CACHE_RELOAD: if (0 != (program_type & ZBX_PROGRAM_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache" " cannot be performed for a passive proxy"); return; } zbx_signal_process_by_type(ZBX_PROCESS_TYPE_CONFSYNCER, 1, flags); break; case ZBX_RTC_HOUSEKEEPER_EXECUTE: zbx_signal_process_by_type(ZBX_PROCESS_TYPE_HOUSEKEEPER, 1, flags); break; case ZBX_RTC_LOG_LEVEL_INCREASE: case ZBX_RTC_LOG_LEVEL_DECREASE: if ((ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID) == ZBX_RTC_GET_SCOPE(flags)) zbx_signal_process_by_pid(ZBX_RTC_GET_DATA(flags), flags); else zbx_signal_process_by_type(ZBX_RTC_GET_SCOPE(flags), ZBX_RTC_GET_DATA(flags), flags); break; } #endif }
/****************************************************************************** * * * Function: terminate_signal_handler * * * * Purpose: handle terminate signals: SIGQUIT, SIGINT, SIGTERM * * * ******************************************************************************/ static void terminate_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); if (!SIG_PARENT_PROCESS) { zabbix_log(sig_parent_pid == SIG_CHECKED_FIELD(siginfo, si_pid) ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d," "reason:%d]. Exiting ...", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_uid), SIG_CHECKED_FIELD(siginfo, si_code)); exit(FAIL); } else { if (0 == sig_exiting) { sig_exiting = 1; zabbix_log(sig_parent_pid == SIG_CHECKED_FIELD(siginfo, si_pid) ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d," "reason:%d]. Exiting ...", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_uid), SIG_CHECKED_FIELD(siginfo, si_code)); zbx_on_exit(); } } }
/****************************************************************************** * * * Function: child_signal_handler * * * * Purpose: handle child signal SIGCHLD * * * ******************************************************************************/ static void child_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); if (!SIG_PARENT_PROCESS) exit(FAIL); if (0 == sig_exiting) { sig_exiting = 1; zabbix_log(LOG_LEVEL_CRIT, "One child process died (PID:%d,exitcode/signal:%d). Exiting ...", SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_status)); zbx_on_exit(); } }
/****************************************************************************** * * * Function: user1_signal_handler * * * * Purpose: handle user signal SIGUSR1 * * * ******************************************************************************/ static void user1_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d].", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_uid), SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT)); #ifdef HAVE_SIGQUEUE if (!SIG_PARENT_PROCESS) { extern void zbx_sigusr_handler(zbx_task_t task); zbx_sigusr_handler(SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT)); } else if (ZBX_TASK_CONFIG_CACHE_RELOAD == SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT)) { extern unsigned char daemon_type; if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache" " cannot be performed for a passive proxy"); } else { union sigval s; extern pid_t *threads; s.ZBX_SIVAL_INT = ZBX_TASK_CONFIG_CACHE_RELOAD; /* threads[0] is configuration syncer (it is set in proxy.c and server.c) */ if (NULL != threads && -1 != sigqueue(threads[0], SIGUSR1, s)) { zabbix_log(LOG_LEVEL_DEBUG, "the signal is redirected to" " the configuration syncer"); } else { zabbix_log(LOG_LEVEL_ERR, "failed to redirect signal: %s", zbx_strerror(errno)); } } } #endif }
/****************************************************************************** * * * Function: pipe_signal_handler * * * * Purpose: handle pipe signal SIGPIPE * * * ******************************************************************************/ static void pipe_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d]. Ignoring ...", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid)); }
/****************************************************************************** * * * Function: fatal_signal_handler * * * * Purpose: handle fatal signals: SIGILL, SIGILL, SIGSEGV, SIGBUS * * * ******************************************************************************/ static void fatal_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_CRIT, "Got signal [signal:%d(%s),reason:%d,refaddr:%p]. Crashing ...", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_code), SIG_CHECKED_FIELD_TYPE(siginfo, si_addr, void *)); print_fatal_info(sig, siginfo, context); exit(FAIL); }
/****************************************************************************** * * * Function: user1_signal_handler * * * * Purpose: handle user signal SIGUSR1 * * * ******************************************************************************/ static void user1_signal_handler(int sig, siginfo_t *siginfo, void *context) { #ifdef HAVE_SIGQUEUE int flags, process_num, found = 0, i; union sigval s; unsigned char process_type; #endif SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d(0x%08x)].", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_pid), SIG_CHECKED_FIELD(siginfo, si_uid), SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT), SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT)); #ifdef HAVE_SIGQUEUE flags = SIG_CHECKED_FIELD(siginfo, si_value.ZBX_SIVAL_INT); if (!SIG_PARENT_PROCESS) { common_sigusr_handler(flags); } else if (NULL == threads) { zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: shutdown in progress"); } else if (ZBX_RTC_CONFIG_CACHE_RELOAD == ZBX_RTC_GET_MSG(flags)) { extern unsigned char daemon_type; if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache" " cannot be performed for a passive proxy"); return; } for (i = 0; i < threads_num; i++) { if (FAIL == get_process_info_by_thread(i + 1, &process_type, &process_num)) continue; if (ZBX_PROCESS_TYPE_CONFSYNCER == process_type) break; } if (i != threads_num) { s.ZBX_SIVAL_INT = flags; if (-1 != sigqueue(threads[i], SIGUSR1, s)) zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to the configuration syncer"); else zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno)); } else zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal to configuration syncer: process not found"); } else if (ZBX_RTC_LOG_LEVEL_INCREASE == ZBX_RTC_GET_MSG(flags) || ZBX_RTC_LOG_LEVEL_DECREASE == ZBX_RTC_GET_MSG(flags)) { s.ZBX_SIVAL_INT = flags; if ((ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID) == ZBX_RTC_GET_SCOPE(flags)) { for (i = 0; i < threads_num; i++) { if (0 != ZBX_RTC_GET_DATA(flags) && threads[i] != ZBX_RTC_GET_DATA(flags)) continue; found = 1; if (-1 != sigqueue(threads[i], SIGUSR1, s)) { zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to process pid:%d", threads[i]); } else zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno)); } if (0 != ZBX_RTC_GET_DATA(flags) && 0 == found) { zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: process pid:%d is not a Zabbix child" " process", ZBX_RTC_GET_DATA(flags)); } } else { for (i = 0; i < threads_num; i++) { if (FAIL == get_process_info_by_thread(i + 1, &process_type, &process_num)) break; if (ZBX_RTC_GET_SCOPE(flags) != process_type) { /* check if we have already checked processes of target type */ if (1 == found) break; continue; } if (0 != ZBX_RTC_GET_DATA(flags) && ZBX_RTC_GET_DATA(flags) != process_num) continue; found = 1; if (-1 != sigqueue(threads[i], SIGUSR1, s)) { zabbix_log(LOG_LEVEL_DEBUG, "the signal was redirected to \"%s\" process" " pid:%d", get_process_type_string(process_type), threads[i]); } else zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal: %s", zbx_strerror(errno)); } if (0 == found) { if (0 == ZBX_RTC_GET_DATA(flags)) { zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:" " \"%s\" process does not exist", get_process_type_string(ZBX_RTC_GET_SCOPE(flags))); } else { zabbix_log(LOG_LEVEL_ERR, "cannot redirect signal:" " \"%s #%d\" process does not exist", get_process_type_string(ZBX_RTC_GET_SCOPE(flags)), ZBX_RTC_GET_DATA(flags)); } } } } #endif }