/* Sync checkers activity with netlink kernel reflection */ void update_checker_activity(uint32_t address, int enable) { checker *checker_obj; element e; /* Display netlink operation */ if (debug & 32) log_message(LOG_INFO, "Netlink reflector reports IP %s %s", inet_ntop2(address), (enable) ? "added" : "removed"); /* Processing Healthcheckers queue */ if (!LIST_ISEMPTY(checkers_queue)) for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { checker_obj = ELEMENT_DATA(e); if (CHECKER_VIP(checker_obj) == address && CHECKER_HA_SUSPEND(checker_obj)) { if (!CHECKER_ENABLED(checker_obj) && enable) log_message(LOG_INFO, "Activating healtchecker for service [%s:%d]", inet_ntop2(CHECKER_RIP(checker_obj)), ntohs(CHECKER_RPORT(checker_obj))); if (CHECKER_ENABLED(checker_obj) && !enable) log_message(LOG_INFO, "Suspending healtchecker for service [%s:%d]", inet_ntop2(CHECKER_RIP(checker_obj)), ntohs(CHECKER_RPORT(checker_obj))); checker_obj->enabled = enable; } } }
/* dump checker data */ static void dump_checker(void *data_obj) { checker *checker_obj = data_obj; log_message(LOG_INFO, " %s:%d", inet_ntop2(CHECKER_RIP(checker_obj)) , ntohs(CHECKER_RPORT(checker_obj))); (*checker_obj->dump_func) (checker_obj); }
/* register checkers to the global I/O scheduler */ void register_checkers_thread(void) { checker *checker_obj; element e; for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { checker_obj = ELEMENT_DATA(e); log_message(LOG_INFO, "Activating healtchecker for service [%s:%d]", inet_ntop2(CHECKER_RIP(checker_obj)), ntohs(CHECKER_RPORT(checker_obj))); CHECKER_ENABLE(checker_obj); if (checker_obj->launch) thread_add_timer(master, checker_obj->launch, checker_obj, BOOTSTRAP_DELAY); } }
int misc_check_child_thread(thread * thread_obj) { int wait_status; checker *checker_obj; misc_checker *misc_chk; checker_obj = THREAD_ARG(thread_obj); misc_chk = CHECKER_ARG(checker_obj); if (thread_obj->type == THREAD_CHILD_TIMEOUT) { pid_t pid; pid = THREAD_CHILD_PID(thread_obj); /* The child hasn't responded. Kill it off. */ if (svr_checker_up(checker_obj->id, checker_obj->rs)) { log_message(LOG_INFO, "Misc check to [%s] for [%s] timed out", inet_ntop2(CHECKER_RIP(checker_obj)), misc_chk->path); smtp_alert(checker_obj->rs, NULL, NULL, "DOWN", "=> MISC CHECK script timeout on service <="); update_svr_checker_state(DOWN, checker_obj->id , checker_obj->vs , checker_obj->rs); } kill(pid, SIGTERM); thread_add_child(thread_obj->master, misc_check_child_timeout_thread, checker_obj, pid, 2); return 0; } wait_status = THREAD_CHILD_STATUS(thread_obj); if (WIFEXITED(wait_status)) { int status; status = WEXITSTATUS(wait_status); if (status == 0 || (misc_chk->dynamic == 1 && status >= 2 && status <= 255)) { /* * The actual weight set when using misc_dynamic is two less than * the exit status returned. Effective range is 0..253. * Catch legacy case of status being 0 but misc_dynamic being set. */ if (misc_chk->dynamic == 1 && status != 0) update_svr_wgt(status - 2, checker_obj->vs, checker_obj->rs); /* everything is good */ if (!svr_checker_up(checker_obj->id, checker_obj->rs)) { log_message(LOG_INFO, "Misc check to [%s] for [%s] success.", inet_ntop2(CHECKER_RIP(checker_obj)), misc_chk->path); smtp_alert(checker_obj->rs, NULL, NULL, "UP", "=> MISC CHECK succeed on service <="); update_svr_checker_state(UP, checker_obj->id , checker_obj->vs , checker_obj->rs); } } else { if (svr_checker_up(checker_obj->id, checker_obj->rs)) { log_message(LOG_INFO, "Misc check to [%s] for [%s] failed.", inet_ntop2(CHECKER_RIP(checker_obj)), misc_chk->path); smtp_alert(checker_obj->rs, NULL, NULL, "DOWN", "=> MISC CHECK failed on service <="); update_svr_checker_state(DOWN, checker_obj->id , checker_obj->vs , checker_obj->rs); } } } return 0; }