/* Set a realserver IPVS rules */ static int init_service_rs(virtual_server * vs) { element e; real_server *rs; for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); /* In alpha mode, be pessimistic (or realistic?) and don't * add real servers into the VS pool. They will get there * later upon healthchecks recovery (if ever). */ if (vs->alpha) { UNSET_ALIVE(rs); continue; } if (!ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs)) return 0; else SET_ALIVE(rs); } else if (vs->vsgname) { UNSET_ALIVE(rs); if (!ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs)) return 0; SET_ALIVE(rs); } } return 1; }
/* Set a realserver IPVS rules */ static int init_service_rs(virtual_server_t * vs) { element e; real_server_t *rs; for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); /* Do not re-add failed RS instantly on reload */ if (rs->reloaded) { /* force re-adding of the rs into vs_group: * we may have new vsg entries */ if (vs->vsgname) UNSET_ALIVE(rs); continue; } /* In alpha mode, be pessimistic (or realistic?) and don't * add real servers into the VS pool. They will get there * later upon healthchecks recovery (if ever). */ if (vs->alpha) { UNSET_ALIVE(rs); continue; } if (!ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs)) return 0; SET_ALIVE(rs); } } return 1; }
/* Remove a realserver IPVS rule */ static int clear_service_rs(virtual_server_t * vs, list l) { element e; real_server_t *rs; long weight_sum; long down_threshold = vs->quorum - vs->hysteresis; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (ISALIVE(rs)) { log_message(LOG_INFO, "Removing service %s from VS %s" , FMT_RS(rs) , FMT_VS(vs)); if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs)) return 0; UNSET_ALIVE(rs); if (!vs->omega) continue; /* In Omega mode we call VS and RS down notifiers * all the way down the exit, as necessary. */ if (rs->notify_down) { log_message(LOG_INFO, "Executing [%s] for service %s in VS %s" , rs->notify_down , FMT_RS(rs) , FMT_VS(vs)); notify_exec(rs->notify_down); } #ifdef _WITH_SNMP_ check_snmp_rs_trap(rs, vs); #endif /* Sooner or later VS will lose the quorum (if any). However, * we don't push in a sorry server then, hence the regression * is intended. */ weight_sum = weigh_live_realservers(vs); if (vs->quorum_state == UP && ( !weight_sum || weight_sum < down_threshold) ) { vs->quorum_state = DOWN; if (vs->quorum_down) { log_message(LOG_INFO, "Executing [%s] for VS %s" , vs->quorum_down , FMT_VS(vs)); notify_exec(vs->quorum_down); } #ifdef _WITH_SNMP_ check_snmp_quorum_trap(vs); #endif } } } return 1; }
/* Remove a realserver IPVS rule */ static int clear_service_rs(list vs_group, virtual_server * vs, list l) { element e; real_server *rs; char rsip[16], vsip[16]; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_DEL_DEST , vs_group , vs , rs)) return 0; UNSET_ALIVE(rs); if (!vs->omega) continue; /* In Omega mode we call VS and RS down notifiers * all the way down the exit, as necessary. */ if (rs->notify_down) { log_message(LOG_INFO, "Executing [%s] for service [%s:%d]" " in VS [%s:%d]" , rs->notify_down , inet_ntoa2(SVR_IP(rs), rsip) , ntohs(SVR_PORT(rs)) , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(rs->notify_down); } /* Sooner or later VS will lose the quorum (if any). However, * we don't push in a sorry server then, hence the regression * is intended. */ if (vs->quorum_state == UP && vs->quorum_down && weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) { vs->quorum_state = DOWN; log_message(LOG_INFO, "Executing [%s] for VS [%s:%d]" , vs->quorum_down , (vs->vsgname) ? vs->vsgname : inet_ntoa2(SVR_IP(vs), vsip) , ntohs(SVR_PORT(vs))); notify_exec(vs->quorum_down); } } #ifdef _KRNL_2_2_ /* if we have a /32 mask, we create one nat rules per * realserver. */ if (vs->nat_mask == HOST_NETMASK) if (!ipfw_cmd(IP_FW_CMD_DEL, vs, rs)) return 0; #endif } return 1; }
/* Set a realserver IPVS rules */ static int init_service_rs(virtual_server * vs) { element e; real_server *rs; for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); /* In alpha mode, be pessimistic (or realistic?) and don't * add real servers into the VS pool. They will get there * later upon healthchecks recovery (if ever). */ if (vs->alpha) { UNSET_ALIVE(rs); continue; } if (!ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs)) return 0; else SET_ALIVE(rs); } else if (vs->vsgname) { UNSET_ALIVE(rs); if (!ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs)) return 0; SET_ALIVE(rs); } #ifdef _KRNL_2_2_ /* if we have a /32 mask, we create one nat rules per * realserver. */ if (vs->nat_mask == HOST_NETMASK) if (!ipfw_cmd(IP_FW_CMD_ADD, vs, rs)) return 0; #endif } return 1; }
/* Remove a realserver IPVS rule */ static int clear_service_rs(list vs_group, virtual_server * vs, list l) { element e; real_server *rs; char rsip[INET6_ADDRSTRLEN]; for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { rs = ELEMENT_DATA(e); if (ISALIVE(rs)) { if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs_group, vs, rs)) return 0; UNSET_ALIVE(rs); if (!vs->omega) continue; /* In Omega mode we call VS and RS down notifiers * all the way down the exit, as necessary. */ if (rs->notify_down) { log_message(LOG_INFO, "Executing [%s] for service [%s]:%d in VS [%s]:%d" , rs->notify_down , inet_sockaddrtos2(&rs->addr, rsip) , ntohs(inet_sockaddrport(&rs->addr)) , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr) , ntohs(inet_sockaddrport(&vs->addr))); notify_exec(rs->notify_down); } /* Sooner or later VS will lose the quorum (if any). However, * we don't push in a sorry server then, hence the regression * is intended. */ if (vs->quorum_state == UP && vs->quorum_down && weigh_live_realservers(vs) < vs->quorum - vs->hysteresis) { vs->quorum_state = DOWN; log_message(LOG_INFO, "Executing [%s] for VS [%s]:%d" , vs->quorum_down , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr) , ntohs(inet_sockaddrport(&vs->addr))); notify_exec(vs->quorum_down); } } } return 1; }
/* Remove a virtualserver IPVS rule */ static int clear_service_vs(virtual_server_t * vs) { /* Processing real server queue */ if (!LIST_ISEMPTY(vs->rs)) { if (vs->s_svr) { if (ISALIVE(vs->s_svr)) ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr); } else if (!clear_service_rs(vs, vs->rs)) return 0; /* The above will handle Omega case for VS as well. */ } ipvs_cmd(LVS_CMD_DEL, vs, NULL); UNSET_ALIVE(vs); return 1; }