diff --git a/include/proto/backend.h b/include/proto/backend.h index 601a61ada..31c191e25 100644 --- a/include/proto/backend.h +++ b/include/proto/backend.h @@ -63,11 +63,15 @@ static inline int srv_is_usable(const struct server *srv) 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 @@ -81,11 +85,15 @@ static inline int srv_was_usable(const struct server *srv) return 0; if (srv->prev_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 commits the current server state and weight onto the previous diff --git a/include/types/server.h b/include/types/server.h index ba0a1a51f..377ea061c 100644 --- a/include/types/server.h +++ b/include/types/server.h @@ -43,11 +43,12 @@ #include -/* 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 @@ -113,7 +114,7 @@ struct tree_occ { 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; diff --git a/src/backend.c b/src/backend.c index 0b4ff4dec..e5c2ad1ab 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1242,7 +1242,7 @@ int tcp_persist_rdp_cookie(struct session *s, struct channel *req, int an_bit) 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; @@ -1490,7 +1490,7 @@ smp_fetch_srv_is_up(struct proxy *px, struct session *l4, void *l7, unsigned int 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; @@ -1512,7 +1512,7 @@ smp_fetch_connslots(struct proxy *px, struct session *l4, void *l7, unsigned int 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) { diff --git a/src/cfgparse.c b/src/cfgparse.c index 037eaa913..5384f4f95 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -6618,7 +6618,7 @@ int check_config_validity() /* 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; } diff --git a/src/checks.c b/src/checks.c index f4bfd54b4..62c8779c2 100644 --- a/src/checks.c +++ b/src/checks.c @@ -182,7 +182,7 @@ static void server_status_printf(struct chunk *msg, struct server *s, struct che } 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, @@ -264,7 +264,7 @@ static void set_server_check_status(struct check *check, short status, const cha health--; /* still good */ } else { if (health == rise) - state &= ~(SRV_STF_RUNNING | SRV_STF_GOINGDOWN); + state = SRV_ST_STOPPED; health = 0; } @@ -276,7 +276,7 @@ static void set_server_check_status(struct check *check, short status, const cha 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 */ @@ -300,9 +300,9 @@ static void set_server_check_status(struct check *check, short status, const cha 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); @@ -416,12 +416,12 @@ void set_server_down(struct check *check) 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); @@ -452,7 +452,7 @@ void set_server_down(struct check *check) 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); @@ -498,14 +498,14 @@ void set_server_up(struct check *check) { 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); @@ -559,7 +559,7 @@ static void set_server_disabled(struct check *check) { 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); @@ -596,7 +596,11 @@ static void set_server_enabled(struct check *check) { 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); @@ -745,13 +749,13 @@ static int httpchk_build_status_header(struct server *s, char *buffer, int size) 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) @@ -762,8 +766,8 @@ static int httpchk_build_status_header(struct server *s, char *buffer, int size) 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, @@ -773,7 +777,7 @@ static int httpchk_build_status_header(struct server *s, char *buffer, int size) 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); @@ -1084,7 +1088,7 @@ static void event_srv_chk_r(struct connection *conn) 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); @@ -1481,9 +1485,10 @@ static struct task *server_warmup(struct task *t) /* 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 */ @@ -1492,7 +1497,7 @@ static struct task *server_warmup(struct task *t) /* 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; } @@ -1701,10 +1706,10 @@ static struct task *process_chk(struct task *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); } diff --git a/src/dumpstats.c b/src/dumpstats.c index 1de4199fd..fbe1d2ab0 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -1716,7 +1716,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line) /* 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 { @@ -2923,8 +2923,8 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in 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) { @@ -2987,7 +2987,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in chunk_appendf(&trash, ""); /* 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 %%\n", server_throttle_rate(sv)); else chunk_appendf(&trash, "-\n"); @@ -3037,8 +3037,8 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in 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 */ @@ -3065,7 +3065,7 @@ static int stats_dump_sv_stats(struct stream_interface *si, struct proxy *px, in 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 */ @@ -3621,7 +3621,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy /* 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 @@ -3629,7 +3629,7 @@ static int stats_dump_proxy_to_buffer(struct stream_interface *si, struct proxy 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 @@ -4264,7 +4264,7 @@ static int stats_process_http_post(struct stream_interface *si) * 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 */ } diff --git a/src/haproxy.c b/src/haproxy.c index ca74e4ec6..d8d8c61a3 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -449,7 +449,7 @@ void sig_dump_state(struct sig_handler *sh) 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); diff --git a/src/lb_map.c b/src/lb_map.c index 24ae4eccd..df7af7f33 100644 --- a/src/lb_map.c +++ b/src/lb_map.c @@ -101,7 +101,7 @@ void recalc_server_map(struct proxy *px) 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 diff --git a/src/proto_http.c b/src/proto_http.c index 4892b8bf9..bd6d02425 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -7069,12 +7069,12 @@ void manage_client_side_appsession(struct session *s, const char *buf, int len) 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; @@ -7479,12 +7479,12 @@ void manage_client_side_cookies(struct session *s, struct channel *req) 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; diff --git a/src/queue.c b/src/queue.c index 8fd1f08c6..21a48d6cd 100644 --- a/src/queue.c +++ b/src/queue.c @@ -50,7 +50,7 @@ unsigned int srv_dynamic_maxconn(const struct server *s) 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; diff --git a/src/server.c b/src/server.c index 7309f4281..0351411c9 100644 --- a/src/server.c +++ b/src/server.c @@ -32,7 +32,7 @@ static struct srv_kw_list srv_keywords = { 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; @@ -53,7 +53,7 @@ int srv_getinter(const struct check *check) 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); @@ -185,13 +185,14 @@ void server_recalc_eweight(struct server *sv) 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; @@ -347,7 +348,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr 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]); @@ -682,7 +683,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr } 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; diff --git a/src/session.c b/src/session.c index 336274cec..cfb45c8ce 100644 --- a/src/session.c +++ b/src/session.c @@ -1375,7 +1375,7 @@ static int process_server_rules(struct session *s, struct channel *req, int an_b 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; @@ -1460,7 +1460,7 @@ static int process_sticking_rules(struct session *s, struct channel *req, int an 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;