/* 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; } } }
int tcp_connect_thread(thread_t * thread) { checker_t *checker = THREAD_ARG(thread); tcp_checker_t *tcp_check = CHECKER_ARG(checker); int fd; int status; /* * Register a new checker thread & return * if checker is disabled */ if (!CHECKER_ENABLED(checker)) { thread_add_timer(thread->master, tcp_connect_thread, checker, checker->vs->delay_loop); return 0; } if ((fd = socket(tcp_check->dst.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { DBG("TCP connect fail to create socket."); return 0; } status = tcp_bind_connect(fd, &tcp_check->dst, &tcp_check->bindto); if (status == connect_error) { thread_add_timer(thread->master, tcp_connect_thread, checker, checker->vs->delay_loop); } /* handle tcp connection status & register check worker thread */ tcp_connection_state(fd, status, thread, tcp_check_thread, tcp_check->connection_to); return 0; }
/* Sync checkers activity with netlink kernel reflection */ void update_checker_activity(sa_family_t family, void *address, int enable) { checker_t *checker; sa_family_t vip_family; element e; char addr_str[INET6_ADDRSTRLEN]; void *addr; /* Display netlink operation */ if (debug & 32) { inet_ntop(family, address, addr_str, sizeof(addr_str)); log_message(LOG_INFO, "Netlink reflector reports IP %s %s" , addr_str, (enable) ? "added" : "removed"); } /* Processing Healthcheckers queue */ if (!LIST_ISEMPTY(checkers_queue)) { for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) { checker = ELEMENT_DATA(e); vip_family = checker->vs->addr.ss_family; if (vip_family != family) continue; if (family == AF_INET6) { addr = (void *) &((struct sockaddr_in6 *)&checker->vs->addr)->sin6_addr; } else { addr = (void *) &((struct sockaddr_in *)&checker->vs->addr)->sin_addr; } if (inaddr_equal(family, addr, address) && CHECKER_HA_SUSPEND(checker)) { if (!CHECKER_ENABLED(checker) && enable) log_message(LOG_INFO, "Activating healthchecker for service [%s]:%d" , inet_sockaddrtos(&checker->rs->addr) , ntohs(inet_sockaddrport(&checker->rs->addr))); if (CHECKER_ENABLED(checker) && !enable) log_message(LOG_INFO, "Suspending healthchecker for service [%s]:%d" , inet_sockaddrtos(&checker->rs->addr) , ntohs(inet_sockaddrport(&checker->rs->addr))); checker->enabled = enable; } } } }
int misc_check_thread(thread * thread_obj) { checker *checker_obj; misc_checker *misc_chk; int status, ret; pid_t pid; checker_obj = THREAD_ARG(thread_obj); misc_chk = CHECKER_ARG(checker_obj); /* * Register a new checker thread & return * if checker is disabled */ if (!CHECKER_ENABLED(checker_obj)) { /* Register next timer checker */ thread_add_timer(thread_obj->master, misc_check_thread, checker_obj, checker_obj->vs->delay_loop); return 0; } /* Register next timer checker */ thread_add_timer(thread_obj->master, misc_check_thread, checker_obj, checker_obj->vs->delay_loop); /* Daemonization to not degrade our scheduling timer */ pid = fork(); /* In case of fork is error. */ if (pid < 0) { log_message(LOG_INFO, "Failed fork process"); return -1; } /* In case of this is parent process */ if (pid) { long timeout; timeout = (misc_chk->timeout) ? misc_chk->timeout : checker_obj->vs->delay_loop; thread_add_child(thread_obj->master, misc_check_child_thread, checker_obj, pid, timeout); return 0; } /* Child part */ signal_handler_destroy(); closeall(0); open("/dev/null", O_RDWR); ret = dup(0); ret = dup(0); status = system_call(misc_chk->path); if (status < 0 || !WIFEXITED(status)) status = 0; /* Script errors aren't server errors */ else status = WEXITSTATUS(status); exit(status); }