return 0;
if (srv->admin & SRV_ADMF_MAINT)
return 0;
- if (state & SRV_STF_GOINGDOWN)
+ switch (state) {
+ case SRV_ST_STARTING:
+ case SRV_ST_RUNNING:
+ return 1;
+ case SRV_ST_STOPPING:
+ case SRV_ST_STOPPED:
return 0;
- if (!(state & SRV_STF_RUNNING))
- return 0;
- return 1;
+ }
+ return 0;
}
/* This function returns non-zero if the designated server was usable for LB
return 0;
if (srv->prev_admin & SRV_ADMF_MAINT)
return 0;
- if (state & SRV_STF_GOINGDOWN)
- return 0;
- if (!(state & SRV_STF_RUNNING))
+ switch (state) {
+ case SRV_ST_STARTING:
+ case SRV_ST_RUNNING:
+ return 1;
+ case SRV_ST_STOPPING:
+ case SRV_ST_STOPPED:
return 0;
- return 1;
+ }
+ return 0;
}
/* This function commits the current server state and weight onto the previous
#include <types/checks.h>
-/* server states, still used as cumulative flags */
+/* server states. Only SRV_ST_DOWN indicates a down server. */
enum srv_state {
- SRV_STF_RUNNING = 0x1, /* the server is UP */
- SRV_STF_GOINGDOWN = 0x2, /* the server is going down (eg: 404) */
- SRV_STF_WARMINGUP = 0x4, /* the server is warming up after a failure */
+ SRV_ST_STOPPED = 0, /* the server is down. Please keep set to zero. */
+ SRV_ST_STARTING, /* the server is warming up (up but throttled) */
+ SRV_ST_RUNNING, /* the server is fully up */
+ SRV_ST_STOPPING, /* the server is up but soft-stopping (eg: 404) */
};
/* Maintenance mode : each server may be in maintenance by itself or may inherit
struct server {
enum obj_type obj_type; /* object type == OBJ_TYPE_SERVER */
- enum srv_state state, prev_state; /* server state among SRV_STF_* */
+ enum srv_state state, prev_state; /* server state among SRV_ST_* */
enum srv_admin admin, prev_admin; /* server maintenance status : SRV_ADMF_* */
unsigned char flags; /* server flags (SRV_F_*) */
struct server *next;
while (srv) {
if (srv->addr.ss_family == AF_INET &&
memcmp(&addr, &(srv->addr), sizeof(addr)) == 0) {
- if ((srv->state & SRV_STF_RUNNING) || (px->options & PR_O_PERSIST)) {
+ if ((srv->state != SRV_ST_STOPPED) || (px->options & PR_O_PERSIST)) {
/* we found the server and it is usable */
s->flags |= SN_DIRECT | SN_ASSIGNED;
s->target = &srv->obj_type;
smp->flags = SMP_F_VOL_TEST;
smp->type = SMP_T_BOOL;
if (!(srv->admin & SRV_ADMF_MAINT) &&
- (!(srv->check.state & CHK_ST_CONFIGURED) || (srv->state & SRV_STF_RUNNING)))
+ (!(srv->check.state & CHK_ST_CONFIGURED) || (srv->state != SRV_ST_STOPPED)))
smp->data.uint = 1;
else
smp->data.uint = 0;
smp->data.uint = 0;
for (iterator = args->data.prx->srv; iterator; iterator = iterator->next) {
- if ((iterator->state & SRV_STF_RUNNING) == 0)
+ if (iterator->state == SRV_ST_STOPPED)
continue;
if (iterator->maxconn == 0 || iterator->maxqueue == 0) {
/* if the other server is forced disabled, we have to do the same here */
if (srv->admin & SRV_ADMF_MAINT) {
- newsrv->state &= ~SRV_STF_RUNNING;
+ newsrv->state = SRV_ST_STOPPED;
newsrv->check.health = 0;
newsrv->agent.health = 0;
}
}
if (xferred >= 0) {
- if (!(s->state & SRV_STF_RUNNING))
+ if (s->state == SRV_ST_STOPPED)
chunk_appendf(msg, ". %d active and %d backup servers left.%s"
" %d sessions active, %d requeued, %d remaining in queue",
s->proxy->srv_act, s->proxy->srv_bck,
health--; /* still good */
} else {
if (health == rise)
- state &= ~(SRV_STF_RUNNING | SRV_STF_GOINGDOWN);
+ state = SRV_ST_STOPPED;
health = 0;
}
health++; /* was bad, stays for a while */
if (health == rise)
- state |= SRV_STF_RUNNING;
+ state = SRV_ST_RUNNING;
if (health >= rise)
health = rise + fall - 1; /* OK now */
server_status_printf(&trash, s, check, -1);
chunk_appendf(&trash, ", status: %d/%d %s",
- (state & SRV_STF_RUNNING) ? (health - rise + 1) : (health),
- (state & SRV_STF_RUNNING) ? (fall) : (rise),
- (state & SRV_STF_RUNNING) ? (s->uweight?"UP":"DRAIN"):"DOWN");
+ (state != SRV_ST_STOPPED) ? (health - rise + 1) : (health),
+ (state != SRV_ST_STOPPED) ? (fall) : (rise),
+ (state != SRV_ST_STOPPED) ? (s->uweight?"UP":"DRAIN"):"DOWN");
Warning("%s.\n", trash.str);
send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
check->health = check->rise;
}
- if ((s->state & SRV_STF_RUNNING && check->health == check->rise) || s->track) {
- int srv_was_paused = s->state & SRV_STF_GOINGDOWN;
+ if ((s->state != SRV_ST_STOPPED && check->health == check->rise) || s->track) {
+ int srv_was_stopping = (s->state == SRV_ST_STOPPING);
int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act;
s->last_change = now.tv_sec;
- s->state &= ~(SRV_STF_RUNNING | SRV_STF_GOINGDOWN);
+ s->state = SRV_ST_STOPPED;
if (s->proxy->lbprm.set_server_status_down)
s->proxy->lbprm.set_server_status_down(s);
Warning("%s.\n", trash.str);
/* we don't send an alert if the server was previously paused */
- if (srv_was_paused)
+ if (srv_was_stopping)
send_log(s->proxy, LOG_NOTICE, "%s.\n", trash.str);
else
send_log(s->proxy, LOG_ALERT, "%s.\n", trash.str);
s->down_time += now.tv_sec - s->last_change;
s->last_change = now.tv_sec;
- s->state |= SRV_STF_RUNNING;
s->admin &= ~SRV_ADMF_FMAINT;
s->check.state &= ~CHK_ST_PAUSED;
- if (s->slowstart > 0) {
- s->state |= SRV_STF_WARMINGUP;
+ s->state = SRV_ST_STARTING;
+ if (s->slowstart > 0)
task_schedule(s->warmup, tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20))));
- }
+ else
+ s->state = SRV_ST_RUNNING;
server_recalc_eweight(s);
struct server *srv;
int xferred;
- s->state |= SRV_STF_GOINGDOWN;
+ s->state = SRV_ST_STOPPING;
if (s->proxy->lbprm.set_server_status_down)
s->proxy->lbprm.set_server_status_down(s);
struct server *srv;
int xferred;
- s->state &= ~SRV_STF_GOINGDOWN;
+ if (s->slowstart)
+ s->state = SRV_ST_STARTING;
+ else
+ s->state = SRV_ST_RUNNING;
+
if (s->proxy->lbprm.set_server_status_up)
s->proxy->lbprm.set_server_status_up(s);
if (!(s->check.state & CHK_ST_ENABLED))
sv_state = 6;
- else if (s->state & SRV_STF_RUNNING) {
+ else if (s->state != SRV_ST_STOPPED) {
if (s->check.health == s->check.rise + s->check.fall - 1)
sv_state = 3; /* UP */
else
sv_state = 2; /* going down */
- if (s->state & SRV_STF_GOINGDOWN)
+ if (s->state == SRV_ST_STOPPING)
sv_state += 2;
} else {
if (s->check.health)
hlen += snprintf(buffer + hlen, size - hlen,
srv_hlt_st[sv_state],
- (s->state & SRV_STF_RUNNING) ? (s->check.health - s->check.rise + 1) : (s->check.health),
- (s->state & SRV_STF_RUNNING) ? (s->check.fall) : (s->check.rise));
+ (s->state != SRV_ST_STOPPED) ? (s->check.health - s->check.rise + 1) : (s->check.health),
+ (s->state != SRV_ST_STOPPED) ? (s->check.fall) : (s->check.rise));
hlen += snprintf(buffer + hlen, size - hlen, "; name=%s/%s; node=%s; weight=%d/%d; scur=%d/%d; qcur=%d",
s->proxy->id, s->id,
s->cur_sess, s->proxy->beconn - s->proxy->nbpend,
s->nbpend);
- if ((s->state & SRV_STF_WARMINGUP) &&
+ if ((s->state == SRV_ST_STARTING) &&
now.tv_sec < s->last_change + s->slowstart &&
now.tv_sec >= s->last_change) {
ratio = MAX(1, 100 * (now.tv_sec - s->last_change) / s->slowstart);
desc = ltrim(check->bi->data + 12, ' ');
if ((s->proxy->options & PR_O_DISABLE404) &&
- (s->state & SRV_STF_RUNNING) && (check->code == 404)) {
+ (s->state != SRV_ST_STOPPED) && (check->code == 404)) {
/* 404 may be accepted as "stopping" only if the server was up */
cut_crlf(desc);
set_server_check_status(check, HCHK_STATUS_L7OKCD, desc);
/* by default, plan on stopping the task */
t->expire = TICK_ETERNITY;
if ((s->admin & SRV_ADMF_MAINT) ||
- (s->state & (SRV_STF_RUNNING|SRV_STF_WARMINGUP)) != (SRV_STF_RUNNING|SRV_STF_WARMINGUP))
+ (s->state != SRV_ST_STARTING))
return t;
+ /* recalculate the weights and update the state */
server_recalc_eweight(s);
/* probably that we can refill this server with a bit more connections */
/* get back there in 1 second or 1/20th of the slowstart interval,
* whichever is greater, resulting in small 5% steps.
*/
- if (s->state & SRV_STF_WARMINGUP)
+ if (s->state == SRV_ST_STARTING)
t->expire = tick_add(now_ms, MS_TO_TICKS(MAX(1000, s->slowstart / 20)));
return t;
}
check_failed(check);
else { /* check was OK */
/* we may have to add/remove this server from the LB group */
- if ((s->state & SRV_STF_RUNNING) && (s->proxy->options & PR_O_DISABLE404)) {
- if ((s->state & SRV_STF_GOINGDOWN) && (check->result != CHK_RES_CONDPASS))
+ if ((s->state != SRV_ST_STOPPED) && (s->proxy->options & PR_O_DISABLE404)) {
+ if ((s->state == SRV_ST_STOPPING) && (check->result != CHK_RES_CONDPASS))
set_server_enabled(check);
- else if (!(s->state & SRV_STF_GOINGDOWN) && (check->result == CHK_RES_CONDPASS))
+ else if ((s->state != SRV_ST_STOPPING) && (check->result == CHK_RES_CONDPASS))
set_server_disabled(check);
}
/* If this server tracks the status of another one,
* we must restore the good status.
*/
- if (sv->track->state & SRV_STF_RUNNING) {
+ if (sv->track->state != SRV_ST_STOPPED) {
set_server_up(&sv->check);
sv->check.health = sv->check.rise; /* up, but will fall down at first failure */
} else {
chunk_appendf(&trash, "%s ", human_time(now.tv_sec - ref->last_change, 1));
chunk_appendf(&trash,
srv_hlt_st[state],
- (ref->state & SRV_STF_RUNNING) ? (ref->check.health - ref->check.rise + 1) : (ref->check.health),
- (ref->state & SRV_STF_RUNNING) ? (ref->check.fall) : (ref->check.rise));
+ (ref->state != SRV_ST_STOPPED) ? (ref->check.health - ref->check.rise + 1) : (ref->check.health),
+ (ref->state != SRV_ST_STOPPED) ? (ref->check.fall) : (ref->check.rise));
}
if (sv->check.state & CHK_ST_ENABLED) {
chunk_appendf(&trash, "<td colspan=3></td>");
/* throttle */
- if ((sv->state & SRV_STF_WARMINGUP) && !server_is_draining(sv))
+ if (sv->state == SRV_ST_STARTING && !server_is_draining(sv))
chunk_appendf(&trash, "<td class=ac>%d %%</td></tr>\n", server_throttle_rate(sv));
else
chunk_appendf(&trash, "<td class=ac>-</td></tr>\n");
else
chunk_appendf(&trash,
srv_hlt_st[state],
- (ref->state & SRV_STF_RUNNING) ? (ref->check.health - ref->check.rise + 1) : (ref->check.health),
- (ref->state & SRV_STF_RUNNING) ? (ref->check.fall) : (ref->check.rise));
+ (ref->state != SRV_ST_STOPPED) ? (ref->check.health - ref->check.rise + 1) : (ref->check.health),
+ (ref->state != SRV_ST_STOPPED) ? (ref->check.fall) : (ref->check.rise));
chunk_appendf(&trash,
/* weight, active, backup */
relative_pid, px->uuid, sv->puid);
/* throttle */
- if ((sv->state & SRV_STF_WARMINGUP) && !server_is_draining(sv))
+ if (sv->state == SRV_ST_STARTING && !server_is_draining(sv))
chunk_appendf(&trash, "%d", server_throttle_rate(sv));
/* sessions: lbtot */
/* FIXME: produce some small strings for "UP/DOWN x/y &#xxxx;" */
if (!(svs->check.state & CHK_ST_ENABLED))
sv_state = 8;
- else if (svs->state & SRV_STF_RUNNING) {
+ else if (svs->state != SRV_ST_STOPPED) {
if (svs->check.health == svs->check.rise + svs->check.fall - 1)
sv_state = 3; /* UP */
else
if (server_is_draining(sv))
sv_state += 4;
- else if (svs->state & SRV_STF_GOINGDOWN)
+ else if (svs->state == SRV_ST_STOPPING)
sv_state += 2;
}
else
* If this server tracks the status of another one,
* we must restore the good status.
*/
- if (!sv->track || (sv->track->state & SRV_STF_RUNNING)) {
+ if (!sv->track || (sv->track->state != SRV_ST_STOPPED)) {
set_server_up(&sv->check);
sv->check.health = sv->check.rise; /* up, but will fall down at first failure */
}
chunk_printf(&trash,
"SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %lld tot.",
p->id, s->id,
- (s->state & SRV_STF_RUNNING) ? "UP" : "DOWN",
+ (s->state != SRV_ST_STOPPED) ? "UP" : "DOWN",
s->cur_sess, s->nbpend, s->counters.cum_sess);
Warning("%s\n", trash.str);
send_log(p, LOG_NOTICE, "%s\n", trash.str);
for (cur = px->srv; cur; cur = cur->next) {
if (cur->eweight &&
(cur->flags & SRV_F_BACKUP) == flag &&
- (cur->state & (SRV_STF_RUNNING | SRV_STF_GOINGDOWN)) == SRV_STF_RUNNING) {
+ (cur->state == SRV_ST_STARTING || cur->state == SRV_ST_RUNNING)) {
int v;
/* If we are forced to return only one server, we don't want to
while (srv) {
if (strcmp(srv->id, asession->serverid) == 0) {
- if ((srv->state & SRV_STF_RUNNING) ||
+ if ((srv->state != SRV_ST_STOPPED) ||
(s->be->options & PR_O_PERSIST) ||
(s->flags & SN_FORCE_PRST)) {
/* we found the server and it's usable */
txn->flags &= ~TX_CK_MASK;
- txn->flags |= (srv->state & SRV_STF_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
+ txn->flags |= (srv->state != SRV_ST_STOPPED) ? TX_CK_VALID : TX_CK_DOWN;
s->flags |= SN_DIRECT | SN_ASSIGNED;
s->target = &srv->obj_type;
while (srv) {
if (srv->cookie && (srv->cklen == delim - val_beg) &&
!memcmp(val_beg, srv->cookie, delim - val_beg)) {
- if ((srv->state & SRV_STF_RUNNING) ||
+ if ((srv->state != SRV_ST_STOPPED) ||
(s->be->options & PR_O_PERSIST) ||
(s->flags & SN_FORCE_PRST)) {
/* we found the server and we can use it */
txn->flags &= ~TX_CK_MASK;
- txn->flags |= (srv->state & SRV_STF_RUNNING) ? TX_CK_VALID : TX_CK_DOWN;
+ txn->flags |= (srv->state != SRV_ST_STOPPED) ? TX_CK_VALID : TX_CK_DOWN;
s->flags |= SN_DIRECT | SN_ASSIGNED;
s->target = &srv->obj_type;
break;
else max = MAX(s->minconn,
s->proxy->beconn * s->maxconn / s->proxy->fullconn);
- if ((s->state & SRV_STF_WARMINGUP) &&
+ if ((s->state == SRV_ST_STARTING) &&
now.tv_sec < s->last_change + s->slowstart &&
now.tv_sec >= s->last_change) {
unsigned int ratio;
int srv_downtime(const struct server *s)
{
- if ((s->state & SRV_STF_RUNNING) && s->last_change < now.tv_sec) // ignore negative time
+ if ((s->state != SRV_ST_STOPPED) && s->last_change < now.tv_sec) // ignore negative time
return s->down_time;
return now.tv_sec - s->last_change + s->down_time;
if ((check->state & CHK_ST_CONFIGURED) && (check->health == check->rise + check->fall - 1))
return check->inter;
- if (!(s->state & SRV_STF_RUNNING) && check->health == 0)
+ if ((s->state == SRV_ST_STOPPED) && check->health == 0)
return (check->downinter)?(check->downinter):(check->inter);
return (check->fastinter)?(check->fastinter):(check->inter);
if (now.tv_sec < sv->last_change || now.tv_sec >= sv->last_change + sv->slowstart) {
/* go to full throttle if the slowstart interval is reached */
- sv->state &= ~SRV_STF_WARMINGUP;
+ if (sv->state == SRV_ST_STARTING)
+ sv->state = SRV_ST_RUNNING;
}
/* We must take care of not pushing the server to full throttle during slow starts.
* It must also start immediately, at least at the minimal step when leaving maintenance.
*/
- if ((sv->state & SRV_STF_WARMINGUP) && (px->lbprm.algo & BE_LB_PROP_DYN))
+ if ((sv->state == SRV_ST_STARTING) && (px->lbprm.algo & BE_LB_PROP_DYN))
w = (px->lbprm.wdiv * (now.tv_sec - sv->last_change) + sv->slowstart) / sv->slowstart;
else
w = px->lbprm.wdiv;
do_agent = 0;
newsrv->flags = 0;
newsrv->admin = 0;
- newsrv->state = SRV_STF_RUNNING; /* early server setup */
+ newsrv->state = SRV_ST_RUNNING; /* early server setup */
newsrv->last_change = now.tv_sec;
newsrv->id = strdup(args[1]);
}
else if (!defsrv && !strcmp(args[cur_arg], "disabled")) {
newsrv->admin |= SRV_ADMF_FMAINT;
- newsrv->state &= ~SRV_STF_RUNNING;
+ newsrv->state = SRV_ST_STOPPED;
newsrv->check.state |= CHK_ST_PAUSED;
newsrv->check.health = 0;
newsrv->agent.health = 0;
if (ret) {
struct server *srv = rule->srv.ptr;
- if ((srv->state & SRV_STF_RUNNING) ||
+ if ((srv->state != SRV_ST_STOPPED) ||
(px->options & PR_O_PERSIST) ||
(s->flags & SN_FORCE_PRST)) {
s->flags |= SN_DIRECT | SN_ASSIGNED;
struct server *srv;
srv = container_of(node, struct server, conf.id);
- if ((srv->state & SRV_STF_RUNNING) ||
+ if ((srv->state != SRV_ST_STOPPED) ||
(px->options & PR_O_PERSIST) ||
(s->flags & SN_FORCE_PRST)) {
s->flags |= SN_DIRECT | SN_ASSIGNED;