switch (ctx->field_num) {
case ST_I_PX_AGG_SRV_CHECK_STATUS: // DEPRECATED
case ST_I_PX_AGG_SRV_STATUS:
- if (!px->srv)
+ if (LIST_ISEMPTY(&px->servers))
goto next_px;
- sv = px->srv;
- while (sv) {
+ list_for_each_entry(sv, &px->servers, el_px) {
srv_state = promex_srv_status(sv);
srv_state_count[srv_state] += 1;
- sv = sv->next;
}
for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) {
val = mkf_u32(FN_GAUGE, srv_state_count[ctx->obj_state]);
ctx->obj_state = 0;
goto next_px;
case ST_I_PX_AGG_CHECK_STATUS:
- if (!px->srv)
+ if (LIST_ISEMPTY(&px->servers))
goto next_px;
- sv = px->srv;
- while (sv) {
+ list_for_each_entry(sv, &px->servers, el_px) {
if ((sv->check.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) == CHK_ST_ENABLED) {
srv_check_status = sv->check.status;
srv_check_count[srv_check_status] += 1;
}
- sv = sv->next;
}
for (; ctx->obj_state < HCHK_STATUS_SIZE; ctx->obj_state++) {
if (get_check_status_result(ctx->obj_state) < CHK_RES_FAILED)
ctx->obj_state = 0;
goto next_px;
case ST_I_PX_STATUS:
- bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
+ bkd_state = ((px->lbprm.tot_weight > 0 || LIST_ISEMPTY(&px->servers)) ? 1 : 0);
for (; ctx->obj_state < PROMEX_BACK_STATE_COUNT; ctx->obj_state++) {
labels[lb_idx].name = ist("state");
labels[lb_idx].value = promex_back_st[ctx->obj_state];
#ifdef USE_QUIC
struct list quic_init_rules; /* quic-initial rules */
#endif
- struct server *srv, *defsrv; /* known servers; default server configuration */
+ struct list servers; /* servers present in current backend */
+ struct server *defsrv; /* default server configuration */
struct lbprm lbprm; /* load-balancing parameters */
int srv_act, srv_bck; /* # of servers eligible for LB (UP|!checked) AND (enabled+weight!=0) */
int load_server_state_from_file; /* location of the file containing server state.
static inline struct server *proxy_first_server(const struct proxy *px)
{
- return px->srv;
+ return !LIST_ISEMPTY(&px->servers) ?
+ LIST_NEXT(&px->servers, struct server *, el_px) : NULL;
}
static inline struct server *proxy_next_server(const struct server *srv)
{
- return srv->next;
+ if (srv->el_px.n == &srv->proxy->servers)
+ return NULL;
+ return LIST_ELEM(srv->el_px.n, struct server *, el_px);
}
#endif /* _HAPROXY_PROXY_H */
signed char use_ssl; /* ssl enabled (1: on, 0: disabled, -1 forced off) */
unsigned int flags; /* server flags (SRV_F_*) */
unsigned int pp_opts; /* proxy protocol options (SRV_PP_*) */
- struct mt_list global_list; /* attach point in the global servers_list */
- struct server *next;
+ struct mt_list global_list; /* attach point in the global servers */
+ struct list el_px; /* attach point in parent proxy */
int cklen; /* the len of the cookie, to speed up checks */
int rdr_len; /* the length of the redirection prefix */
char *cookie; /* the id set in the cookie */
static inline void srv_detach(struct server *srv)
{
struct proxy *px = srv->proxy;
- struct server *prev;
-
- if (px->srv == srv) {
- px->srv = srv->next;
- }
- else {
- for (prev = px->srv; prev && prev->next != srv; prev = prev->next)
- ;
- BUG_ON(!prev); /* Server instance not found in proxy list ? */
- prev->next = srv->next;
- }
+ LIST_DEL_INIT(&srv->el_px);
/* Reset the proxy's ready_srv if it was this one. */
HA_ATOMIC_CAS(&px->ready_srv, &srv, NULL);
}
px->srv_act = px->srv_bck = 0;
px->lbprm.tot_wact = px->lbprm.tot_wbck = 0;
px->lbprm.fbck = NULL;
- for (srv = px->srv; srv != NULL; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (!srv_willbe_usable(srv))
continue;
struct proxy *px = s->be;
int ret;
struct sample smp;
- struct server *srv = px->srv;
+ struct server *srv;
uint16_t port;
uint32_t addr;
char *p;
goto no_cookie;
stream_set_target(s, NULL);
- while (srv) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->addr.ss_family == AF_INET &&
port == srv->svc_port &&
addr == ((struct sockaddr_in *)&srv->addr)->sin_addr.s_addr) {
break;
}
}
- srv = srv->next;
}
no_cookie:
smp->data.type = SMP_T_SINT;
smp->data.u.sint = 0;
- for (iterator = px->srv; iterator; iterator = iterator->next) {
+ list_for_each_entry(iterator, &px->servers, el_px) {
if (iterator->cur_state == SRV_ST_STOPPED)
continue;
smp->data.type = SMP_T_SINT;
smp->data.u.sint = 0;
- for (iterator = px->srv; iterator; iterator = iterator->next) {
+ list_for_each_entry(iterator, &px->servers, el_px) {
if (iterator->cur_state == SRV_ST_STOPPED)
continue;
struct server *srv;
list_for_each_entry(px, &main_proxies, el) {
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
srv_diag_cookies(ret, srv, &cookies_tree);
srv_diag_check_reuse(ret, srv, px);
}
* too short an interval for all others.
*/
list_for_each_entry(px, &main_proxies, el) {
- for (s = px->srv; s; s = s->next) {
+ list_for_each_entry(s, &px->servers, el_px) {
if ((px->options2 & PR_O2_USE_SBUF_CHECK) &&
(s->check.tcpcheck->rs && s->check.tcpcheck->rs->flags & TCPCHK_RULES_MAY_USE_SBUF))
s->check.state |= CHK_ST_USE_SMALL_BUFF;
}
}
- for (s = px->srv; s; s = s->next) {
+ list_for_each_entry(s, &px->servers, el_px) {
/* A task for the main check */
if (s->check.state & CHK_ST_CONFIGURED) {
if (s->check.type == PR_O2_EXT_CHK) {
if (fcgi_conf && !(px->options2 & PR_O2_RSTRICT_REQ_HDR_NAMES_MASK))
px->options2 |= PR_O2_RSTRICT_REQ_HDR_NAMES_DEL;
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->mux_proto && isteq(srv->mux_proto->mux_proto, ist("fcgi"))) {
nb_fcgi_srv++;
if (fcgi_conf)
conf->agent->fe.options2 |= PR_O2_INDEPSTR;
conf->agent->fe.conn_retries = CONN_RETRIES;
conf->agent->fe.accept = frontend_accept;
- conf->agent->fe.srv = NULL;
+ LIST_INIT(&conf->agent->fe.servers);
conf->agent->fe.timeout.client = TICK_ETERNITY;
conf->agent->fe.fe_req_ana = AN_REQ_SWITCHING_RULES;
if (!(px->cap & PR_CAP_BE) || px->mode != PR_MODE_SPOP)
goto out;
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->pool_conn_name) {
ha_free(&srv->pool_conn_name);
release_sample_expr(srv->pool_conn_name_expr);
ha_warning("SIGHUP received, dumping servers states.\n");
list_for_each_entry(p, &main_proxies, el) {
- struct server *s = p->srv;
+ struct server *s;
send_log(p, LOG_NOTICE, "SIGHUP received, dumping servers states for proxy %s.\n", p->id);
- while (s) {
+ list_for_each_entry(s, &p->servers, el_px) {
chunk_printf(&trash,
"SIGHUP: Server %s/%s is %s. Conn: %d act, %d pend, %llu tot.",
p->id, s->id,
s->cur_sess, s->queueslength, (ullong)COUNTERS_SHARED_TOTAL(s->counters.shared.tg, cum_sess, HA_ATOMIC_LOAD));
ha_warning("%s\n", trash.area);
send_log(p, LOG_NOTICE, "%s\n", trash.area);
- s = s->next;
}
/* FIXME: those info are a bit outdated. We should be able to distinguish between FE and BE. */
- if (!p->srv) {
+ if (LIST_ISEMPTY(&p->servers)) {
chunk_printf(&trash,
"SIGHUP: Proxy %s has no servers. Conn: act(FE+BE): %d+%d, %d pend (%d unass), tot(FE+BE): %llu+%llu.",
p->id,
continue;
list_for_each_entry(pscf, &post_server_check_list, list) {
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
err_code |= pscf->fct(srv);
if (err_code & (ERR_ABORT|ERR_FATAL)) {
ha_alert("Fatal errors found in configuration.\n");
hc->px = px;
- for (srv = px->srv; srv != NULL; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->xprt == xprt_get(XPRT_RAW)) {
hc->srv_raw = srv;
#ifdef USE_OPENSSL
#ifdef USE_OPENSSL
/* initialize the SNI for the SSL servers */
- for (srv = curproxy->srv; srv != NULL; srv = srv->next) {
+ list_for_each_entry(srv, &curproxy->servers, el_px) {
if (srv->xprt == xprt_get(XPRT_SSL)) {
srv_ssl = srv;
}
struct eb_root init_head = EB_ROOT;
p->lbprm.wdiv = BE_WEIGHT_SCALE;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
srv_lb_commit_status(srv);
}
p->lbprm.chash.last = NULL;
/* queue active and backup servers in two distinct groups */
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->lb_tree = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.chash.bck : &p->lbprm.chash.act;
srv->lb_nodes_tot = srv->uweight * BE_WEIGHT_SCALE;
srv->lb_nodes_now = 0;
struct eb_root init_head = EB_ROOT;
p->lbprm.wdiv = BE_WEIGHT_SCALE;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
srv_lb_commit_status(srv);
}
p->lbprm.fas.bck = init_head;
/* queue active and backup servers in two distinct groups */
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
if (!srv_currently_usable(srv))
continue;
srv->lb_tree = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fas.bck : &p->lbprm.fas.act;
struct eb_root init_head = EB_ROOT;
p->lbprm.wdiv = BE_WEIGHT_SCALE;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
srv_lb_commit_status(srv);
}
p->lbprm.fwlc.bck = init_head;
/* queue active and backup servers in two distinct groups */
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
if (!srv_currently_usable(srv))
continue;
srv->lb_tree = (srv->flags & SRV_F_BACKUP) ? &p->lbprm.fwlc.bck : &p->lbprm.fwlc.act;
int i, j;
p->lbprm.wdiv = BE_WEIGHT_SCALE;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
srv_lb_commit_status(srv);
}
/* queue active and backup servers in two distinct groups */
j = 0;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
j++;
if (!srv_currently_usable(srv))
continue;
* the first declared. This is an important assumption for the backup
* case, where we want the first server only.
*/
- for (cur = px->srv; cur; cur = cur->next)
+ list_for_each_entry(cur, &px->servers, el_px)
cur->wscore = 0;
for (o = 0; o < tot; o++) {
int max = 0;
best = NULL;
- for (cur = px->srv; cur; cur = cur->next) {
+ list_for_each_entry(cur, &px->servers, el_px) {
if ((cur->flags & SRV_F_BACKUP) == flag &&
srv_willbe_usable(cur)) {
int v;
int pgcd;
int act, bck;
- if (!p->srv)
+ if (LIST_ISEMPTY(&p->servers))
return 0;
/* We will factor the weights to reduce the table,
p->lbprm.wmult = pgcd;
act = bck = 0;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = (srv->uweight * p->lbprm.wdiv + p->lbprm.wmult - 1) / p->lbprm.wmult;
if (srv->flags & SRV_F_BACKUP)
first = NULL;
- for (cur = px->srv; cur; cur = cur->next) {
+ list_for_each_entry(cur, &px->servers, el_px) {
if ((cur->flags & SRV_F_BACKUP) == flag &&
srv_willbe_usable(cur)) {
first = cur;
{
struct server *srv;
- if (!p->srv)
+ if (LIST_ISEMPTY(&p->servers))
return 0;
- for (srv = p->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &p->servers, el_px) {
srv->next_eweight = 1; /* ignore weights, all servers have the same weight */
srv_lb_commit_status(srv);
}
}
/* finish the initialization of proxy's servers */
- srv = be->srv;
- while (srv) {
+ list_for_each_entry(srv, &be->servers, el_px) {
BUG_ON(srv->log_target);
BUG_ON(srv->addr_type.proto_type != PROTO_TYPE_DGRAM &&
srv->addr_type.proto_type != PROTO_TYPE_STREAM);
goto end;
}
srv->log_target->flags |= LOG_TARGET_FL_RESOLVED;
- srv = srv->next;
}
end:
if (err_code & ERR_CODE) {
*/
void deinit_proxy(struct proxy *p)
{
- struct server *s, *s_next;
+ struct server *s, *s_back;
struct cap_hdr *h,*h_next;
struct listener *l,*l_next;
struct bind_conf *bind_conf, *bind_back;
h = h_next;
}/* end while(h) */
- s = p->srv;
- while (s) {
+ list_for_each_entry_safe(s, s_back, &p->servers, el_px) {
list_for_each_entry(srvdf, &server_deinit_list, list)
srvdf->fct(s);
if (p->lbprm.ops && p->lbprm.ops->server_deinit)
p->lbprm.ops->server_deinit(s);
- s_next = s->next;
srv_drop(s);
- s = s_next;
}/* end while(s) */
/* also free default-server parameters since some of them might have
memset(p, 0, sizeof(struct proxy));
p->obj_type = OBJ_TYPE_PROXY;
LIST_INIT(&p->global_list);
+ LIST_INIT(&p->servers);
LIST_INIT(&p->el);
LIST_INIT(&p->acl);
LIST_INIT(&p->http_req_rules);
int proxy_finalize(struct proxy *px, int *err_code)
{
+ struct list tmp_list = LIST_HEAD_INIT(tmp_list);
struct bind_conf *bind_conf;
- struct server *newsrv;
+ struct server *newsrv, *newsrv_back;
struct switching_rule *rule;
struct server_rule *srule;
struct sticking_rule *mrule;
free(px->defbe.name);
px->defbe.be = target;
/* Emit a warning if this proxy also has some servers */
- if (px->srv) {
+ if (!LIST_ISEMPTY(&px->servers)) {
ha_warning("In proxy '%s', the 'default_backend' rule always has precedence over the servers, which will never be used.\n",
px->id);
*err_code |= ERR_WARN;
#endif
/* Warn is a switch-mode http is used on a TCP listener with servers but no backend */
- if (!px->defbe.name && LIST_ISEMPTY(&px->switching_rules) && px->srv) {
+ if (!px->defbe.name && LIST_ISEMPTY(&px->switching_rules) && !LIST_ISEMPTY(&px->servers)) {
if ((px->options & PR_O_HTTP_UPG) && px->mode == PR_MODE_TCP)
ha_warning("Proxy '%s' : 'switch-mode http' configured for a %s %s with no backend. "
"Incoming connections upgraded to HTTP cannot be routed to TCP servers\n",
if (!(px->cap & PR_CAP_INT) && (px->mode == PR_MODE_TCP || px->mode == PR_MODE_HTTP) &&
(((px->cap & PR_CAP_FE) && !px->timeout.client) ||
- ((px->cap & PR_CAP_BE) && (px->srv) &&
+ ((px->cap & PR_CAP_BE) && !LIST_ISEMPTY(&px->servers) &&
(!px->timeout.connect ||
(!px->timeout.server && (px->mode == PR_MODE_HTTP || !px->timeout.tunnel)))))) {
ha_warning("missing timeouts for %s '%s'.\n"
}
/* first, we will invert the servers list order */
- newsrv = NULL;
- while (px->srv) {
- struct server *next;
-
- next = px->srv->next;
- px->srv->next = newsrv;
- newsrv = px->srv;
- if (!next)
- break;
- px->srv = next;
+ list_for_each_entry_safe(newsrv, newsrv_back, &px->servers, el_px) {
+ LIST_DEL_INIT(&newsrv->el_px);
+ LIST_INSERT(&tmp_list, &newsrv->el_px);
}
+ LIST_SPLICE(&px->servers, &tmp_list);
/* Check that no server name conflicts. This causes trouble in the stats.
* We only emit an error for the first conflict affecting each server,
* we simply have to check for the current server's duplicates to spot
* conflicts.
*/
- for (newsrv = px->srv; newsrv; newsrv = newsrv->next) {
+ list_for_each_entry(newsrv, &px->servers, el_px) {
struct server *other_srv;
/* Note: internal servers are not always registered and
/* assign automatic UIDs to servers which don't have one yet */
next_id = 1;
- newsrv = px->srv;
- while (newsrv != NULL) {
+ list_for_each_entry(newsrv, &px->servers, el_px) {
if (!newsrv->puid) {
/* server ID not set, use automatic numbering with first
* spare entry starting with next_svid.
}
next_id++;
- newsrv = newsrv->next;
}
px->lbprm.wmult = 1; /* default weight multiplier */
* tasks to fill the emptied slots when a connection leaves.
* Also, resolve deferred tracking dependency if needed.
*/
- newsrv = px->srv;
- while (newsrv != NULL) {
+ list_for_each_entry(newsrv, &px->servers, el_px) {
set_usermsgs_ctx(newsrv->conf.file, newsrv->conf.line, &newsrv->obj_type);
srv_minmax_conn_apply(newsrv);
next_srv:
reset_usermsgs_ctx();
- newsrv = newsrv->next;
}
/*
* have been provided yet.
*/
if (px->ck_opts & PR_CK_DYNAMIC) {
- newsrv = px->srv;
- while (newsrv != NULL) {
+ list_for_each_entry(newsrv, &px->servers, el_px)
srv_set_dyncookie(newsrv);
- newsrv = newsrv->next;
- }
}
/* We have to initialize the server lookup mechanism depending
/*
* ensure that we're not cross-dressing a TCP server into HTTP.
*/
- newsrv = px->srv;
- while (newsrv != NULL) {
+ list_for_each_entry(newsrv, &px->servers, el_px) {
if ((px->mode != PR_MODE_HTTP) && newsrv->rdr_len) {
ha_alert("%s '%s' : server cannot have cookie or redirect prefix in non-HTTP mode.\n",
proxy_type_str(px), px->id);
*err_code |= ERR_FATAL | ERR_ALERT;
goto out;
}
-
- newsrv = newsrv->next;
}
/* Check filter configuration, if any */
/* Check the mux protocols, if any, for each server attached to
* the current proxy */
- for (newsrv = px->srv; newsrv; newsrv = newsrv->next) {
+ list_for_each_entry(newsrv, &px->servers, el_px) {
int mode = conn_pr_mode_to_proto_mode(px->mode);
const struct mux_proto_list *mux_ent;
px->ck_opts |= PR_CK_DYNAMIC;
HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
- for (s = px->srv; s != NULL; s = s->next) {
+ list_for_each_entry(s, &px->servers, el_px) {
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
srv_set_dyncookie(s);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
px->ck_opts &= ~PR_CK_DYNAMIC;
HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
- for (s = px->srv; s != NULL; s = s->next) {
+ list_for_each_entry(s, &px->servers, el_px) {
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
if (!(s->flags & SRV_F_COOKIESET))
ha_free(&s->cookie);
px->dyncookie_key = newkey;
HA_RWLOCK_WRUNLOCK(PROXY_LOCK, &px->lock);
- for (s = px->srv; s != NULL; s = s->next) {
+ list_for_each_entry(s, &px->servers, el_px) {
HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
srv_set_dyncookie(s);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
goto out;
}
- if (be->srv) {
+ if (!LIST_ISEMPTY(&be->servers)) {
msg = "Only a backend without server can be deleted.";
goto out;
}
continue;
}
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
struct resolvers *resolvers;
if (!srv->resolvers_id)
list_for_each_entry(r, &sec_resolvers, list) {
/* prepare forward server descriptors */
if (r->px) {
- srv = r->px->srv;
- while (srv) {
+ list_for_each_entry(srv, &r->px->servers, el_px) {
/* init ssl if needed */
if (srv->use_ssl == 1 && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv) {
if (xprt_get(XPRT_SSL)->prepare_srv(srv)) {
break;
}
}
- srv = srv->next;
}
}
}
struct proxy *p = s->proxy;
struct server *tmpserv;
- for (tmpserv = p->srv; tmpserv != NULL;
- tmpserv = tmpserv->next) {
+ list_for_each_entry(tmpserv, &p->servers, el_px) {
if (tmpserv == s)
continue;
if (tmpserv->next_admin & SRV_ADMF_FMAINT)
{
struct server *srv;
- for (srv = px->srv; srv != NULL; srv = srv->next)
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->flags & SRV_F_BACKUP)
srv_shutdown_streams(srv, why);
+ }
}
static void srv_append_op_chg_cause(struct buffer *msg, struct server *s, enum srv_op_st_chg_cause cause)
{
struct server *srv;
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->track)
continue;
srv_propagate_admin_state(srv);
#endif
// add server to proxy list:
- /* TODO use a double-linked list for px->srv */
- if (!(proxy->flags & PR_FL_CHECKED) || !proxy->srv) {
+ if (!(proxy->flags & PR_FL_CHECKED)) {
/* they are linked backwards first during parsing
* This will be restablished after parsing.
*/
- srv->next = proxy->srv;
- proxy->srv = srv;
+ LIST_INSERT(&proxy->servers, &srv->el_px);
}
else {
- struct server *sv = proxy->srv;
-
// runtime, add the server at the end of the list
- while (sv && sv->next)
- sv = sv->next;
- sv->next = srv;
+ LIST_APPEND(&proxy->servers, &srv->el_px);
}
HA_RWLOCK_INIT(&srv->path_params.param_lock);
return NULL;
be = srv->proxy;
- for (tmpsrv = be->srv; tmpsrv; tmpsrv = tmpsrv->next) {
+ list_for_each_entry(tmpsrv, &be->servers, el_px) {
/* we found the current server is the same, ignore it */
if (srv == tmpsrv)
continue;
if (!(curproxy->cap & PR_CAP_BE) || (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)))
continue;
- for (srv = curproxy->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &curproxy->servers, el_px) {
set_usermsgs_ctx(srv->conf.file, srv->conf.line, &srv->obj_type);
if (srv->hostname || srv->srvrq)
return_code |= srv_iterate_initaddr(srv);
struct server *srv;
unsigned long key;
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
chunk_printf(&trash, "%s %s", px->id, srv->id);
key = XXH3(trash.area, trash.data, 0);
node = eb64_lookup(st_tree, key);
struct eb_root local_state_tree = EB_ROOT_UNIQUE;
/* Must be an enabled backend with at least a server */
- if (!(curproxy->cap & PR_CAP_BE) || (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) || !curproxy->srv)
+ if (!(curproxy->cap & PR_CAP_BE) || (curproxy->flags & (PR_FL_DISABLED|PR_FL_STOPPED)) || LIST_ISEMPTY(&curproxy->servers))
continue; /* next proxy */
/* Mode must be specified */
/* prepare forward server descriptors */
if (sink->forward_px) {
/* sink proxy is set: register all servers from the proxy */
- srv = sink->forward_px->srv;
- while (srv) {
+ list_for_each_entry(srv, &sink->forward_px->servers, el_px) {
if (!sink_add_srv(sink, srv)) {
err_code |= ERR_ALERT | ERR_FATAL;
break;
}
- srv = srv->next;
}
}
/* init forwarding if at least one sft is registered */
struct stats_module *mod;
int stats_module_len = 0;
- if (px->cap & PR_CAP_BE && px->srv && (ctx->flags & STAT_F_ADMIN)) {
+ if (px->cap & PR_CAP_BE && !LIST_ISEMPTY(&px->servers) && (ctx->flags & STAT_F_ADMIN)) {
/* A form to enable/disable this proxy servers */
/* scope_txt = search pattern + search query, ctx->scope_len is always <= STAT_SCOPE_TXT_MAXLEN */
if (ctx->flags & STAT_F_ADMIN) {
/* Column heading for Enable or Disable server */
- if ((px->cap & PR_CAP_BE) && px->srv)
+ if ((px->cap & PR_CAP_BE) && !LIST_ISEMPTY(&px->servers))
chunk_appendf(chk,
"<th rowspan=2 width=1><input type=\"checkbox\" "
"onclick=\"for(c in document.getElementsByClassName('%s-checkbox')) "
chunk_appendf(chk, "</table>");
- if ((px->cap & PR_CAP_BE) && px->srv && (ctx->flags & STAT_F_ADMIN)) {
+ if ((px->cap & PR_CAP_BE) && !LIST_ISEMPTY(&px->servers) && (ctx->flags & STAT_F_ADMIN)) {
/* close the form used to enable/disable this proxy servers */
chunk_appendf(chk,
"Choose the action to perform on the checked servers : "
const struct server *srv;
nbup_tmp = nbsrv_tmp = totuw_tmp = 0;
- for (srv = px->srv; srv; srv = srv->next) {
+ list_for_each_entry(srv, &px->servers, el_px) {
if (srv->cur_state != SRV_ST_STOPPED) {
nbup_tmp++;
if (srv_currently_usable(srv) &&
break;
case ST_I_PX_STATUS:
fld = chunk_newstr(out);
- chunk_appendf(out, "%s", (px->lbprm.tot_weight > 0 || !px->srv) ? "UP" : "DOWN");
+ chunk_appendf(out, "%s", (px->lbprm.tot_weight > 0 || LIST_ISEMPTY(&px->servers)) ? "UP" : "DOWN");
if (px->flags & PR_FL_BE_UNPUBLISHED)
chunk_appendf(out, " (UNPUB)");
if (flags & (STAT_F_HIDE_MAINT|STAT_F_HIDE_DOWN))
field = mkf_u32(0, px->srv_bck);
break;
case ST_I_PX_DOWNTIME:
- if (px->srv)
+ if (!LIST_ISEMPTY(&px->servers))
field = mkf_u32(FN_COUNTER, be_downtime(px));
break;
case ST_I_PX_PID:
px->fe_counters.cps_max = 0;
}
- for (sv = px->srv; sv; sv = sv->next)
+ list_for_each_entry(sv, &px->servers, el_px) {
if (clrall)
memset(&sv->counters, 0, sizeof(sv->counters));
else {
sv->counters.dtime_max = 0;
sv->counters.ttime_max = 0;
}
+ }
list_for_each_entry(li, &px->conf.listeners, by_fe)
if (li->counters) {
}
if (mod_cap & STATS_PX_CAP_SRV) {
- for (sv = px->srv; sv; sv = sv->next) {
+ list_for_each_entry(sv, &px->servers, el_px) {
EXTRA_COUNTERS_INIT(sv->extra_counters,
mod,
mod->counters,
}
}
- for (sv = px->srv; sv; sv = sv->next) {
+ list_for_each_entry(sv, &px->servers, el_px) {
if (!stats_allocate_proxy_counters_internal(&sv->extra_counters,
COUNTERS_SV,
STATS_PX_CAP_SRV,