/* Store new weight in real_server struct and then update kernel. */ void update_svr_wgt(int weight, virtual_server_t * vs, real_server_t * rs , int update_quorum) { if (weight != rs->weight) { log_message(LOG_INFO, "Changing weight from %d to %d for %s service %s of VS %s" , rs->weight , weight , ISALIVE(rs) ? "active" : "inactive" , FMT_RS(rs) , FMT_VS(vs)); rs->weight = weight; /* * Have weight change take effect now only if rs is in * the pool and alive and the quorum is met (or if * there is no sorry server). If not, it will take * effect later when it becomes alive. */ if (rs->set && ISALIVE(rs) && (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr))) ipvs_cmd(LVS_CMD_EDIT_DEST, vs, rs); if (update_quorum) update_quorum_state(vs); } }
/* Store new weight in real_server struct and then update kernel. */ void update_svr_wgt(int weight, virtual_server * vs, real_server * rs) { char rsip[INET6_ADDRSTRLEN]; if (weight != rs->weight) { log_message(LOG_INFO, "Changing weight from %d to %d for %s service [%s]:%d of VS [%s]:%d" , rs->weight , weight , ISALIVE(rs) ? "active" : "inactive" , inet_sockaddrtos2(&rs->addr, rsip) , ntohs(inet_sockaddrport(&rs->addr)) , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr) , ntohs(inet_sockaddrport(&vs->addr))); rs->weight = weight; /* * Have weight change take effect now only if rs is in * the pool and alive and the quorum is met (or if * there is no sorry server). If not, it will take * effect later when it becomes alive. */ if (rs->set && ISALIVE(rs) && (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr))) ipvs_cmd(LVS_CMD_EDIT_DEST, check_data->vs_group, vs, rs); update_quorum_state(vs); } }
/* Set a virtualserver IPVS rules */ static int init_service_vs(virtual_server_t * vs) { /* Init the VS root */ if (!ISALIVE(vs) || vs->vsgname) { if (!ipvs_cmd(LVS_CMD_ADD, vs, NULL)) return 0; else SET_ALIVE(vs); } /* Processing real server queue */ if (!init_service_rs(vs)) return 0; if (vs->reloaded) { if (vs->vsgname) /* add reloaded dests into new vsg entries */ sync_service_vsg(vs); /* we may have got/lost quorum due to quorum setting changed */ update_quorum_state(vs); } return 1; }
/* Set a virtualserver IPVS rules */ static int init_service_vs(virtual_server_t * vs) { /* Init the VS root */ if (!ISALIVE(vs) || vs->vsgname) { if (!ipvs_cmd(LVS_CMD_ADD, check_data->vs_group, vs, NULL)) return 0; else SET_ALIVE(vs); } /* Processing real server queue */ if (!LIST_ISEMPTY(vs->rs)) { if (vs->alpha && ! vs->reloaded) vs->quorum_state = DOWN; if (!init_service_rs(vs)) return 0; } /* if the service was reloaded, we may have got/lost quorum due to quorum setting changed */ if (vs->reloaded) update_quorum_state(vs); return 1; }
/* manipulate add/remove rs according to alive state */ static int perform_svr_state(int alive, virtual_server_t * vs, real_server_t * rs) { /* * | ISALIVE(rs) | alive | context * | 0 | 0 | first check failed under alpha mode, unreachable here * | 0 | 1 | RS went up, add it to the pool * | 1 | 0 | RS went down, remove it from the pool * | 1 | 1 | first check succeeded w/o alpha mode, unreachable here */ if (!ISALIVE(rs) && alive) { log_message(LOG_INFO, "%s service %s to VS %s" , (rs->inhibit) ? "Enabling" : "Adding" , FMT_RS(rs) , FMT_VS(vs)); /* Add only if we have quorum or no sorry server */ if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) { if (ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs)) return -1; } rs->alive = alive; if (rs->notify_up) { log_message(LOG_INFO, "Executing [%s] for service %s in VS %s" , rs->notify_up , FMT_RS(rs) , FMT_VS(vs)); notify_exec(rs->notify_up); } #ifdef _WITH_SNMP_CHECKER_ check_snmp_rs_trap(rs, vs); #endif /* We may have gained quorum */ update_quorum_state(vs); } if (ISALIVE(rs) && !alive) { log_message(LOG_INFO, "%s service %s from VS %s" , (rs->inhibit) ? "Disabling" : "Removing" , FMT_RS(rs) , FMT_VS(vs)); /* server is down, it is removed from the LVS realserver pool * Remove only if we have quorum or no sorry server */ if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) { if (ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs)) return -1; } rs->alive = alive; 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_CHECKER_ check_snmp_rs_trap(rs, vs); #endif /* We may have lost quorum */ update_quorum_state(vs); } return 0; }
/* manipulate add/remove rs according to alive state */ void perform_svr_state(int alive, virtual_server * vs, real_server * rs) { char rsip[INET6_ADDRSTRLEN]; /* * | ISALIVE(rs) | alive | context * | 0 | 0 | first check failed under alpha mode, unreachable here * | 0 | 1 | RS went up, add it to the pool * | 1 | 0 | RS went down, remove it from the pool * | 1 | 1 | first check succeeded w/o alpha mode, unreachable here */ if (!ISALIVE(rs) && alive) { log_message(LOG_INFO, "%s service [%s]:%d to VS [%s]:%d" , (rs->inhibit) ? "Enabling" : "Adding" , inet_sockaddrtos2(&rs->addr, rsip) , ntohs(inet_sockaddrport(&rs->addr)) , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr) , ntohs(inet_sockaddrport(&vs->addr))); /* Add only if we have quorum or no sorry server */ if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) { ipvs_cmd(LVS_CMD_ADD_DEST, check_data->vs_group, vs, rs); } rs->alive = alive; if (rs->notify_up) { log_message(LOG_INFO, "Executing [%s] for service [%s]:%d in VS [%s]:%d" , rs->notify_up , 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_up); } /* We may have gained quorum */ update_quorum_state(vs); } if (ISALIVE(rs) && !alive) { log_message(LOG_INFO, "%s service [%s]:%d from VS [%s]:%d" , (rs->inhibit) ? "Disabling" : "Removing" , inet_sockaddrtos2(&rs->addr, rsip) , ntohs(inet_sockaddrport(&rs->addr)) , (vs->vsgname) ? vs->vsgname : inet_sockaddrtos(&vs->addr) , ntohs(inet_sockaddrport(&vs->addr))); /* server is down, it is removed from the LVS realserver pool * Remove only if we have quorum or no sorry server */ if (vs->quorum_state == UP || !vs->s_svr || !ISALIVE(vs->s_svr)) { ipvs_cmd(LVS_CMD_DEL_DEST, check_data->vs_group, vs, rs); } rs->alive = alive; 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); } /* We may have lost quorum */ update_quorum_state(vs); } }