From: Amaury Denoyelle Date: Thu, 23 Jul 2026 14:34:49 +0000 (+0200) Subject: MINOR: proxy: define server list iteration functions X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=b679ccb76021a39f495f652d60634ab95cb68871;p=thirdparty%2Fhaproxy.git MINOR: proxy: define server list iteration functions Define wrappers function to iterate over a proxy servers list. These functions are used when a standard for loop over the whole list is not desirable. This patch will ease the conversion of the proxy servers list into a doubly linked struct list type, as the final conversion patch changes will be smaller. --- diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c index f387bb672..e28dc7d55 100644 --- a/addons/promex/service-prometheus.c +++ b/addons/promex/service-prometheus.c @@ -1398,7 +1398,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) &val, labels, &out, max)) goto full; next_sv: - sv = watcher_next(&ctx->srv_watch, sv->next); + sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv)); } next_px: @@ -1406,7 +1406,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) px = watcher_next(&ctx->px_watch, main_proxies_next(px)); if (px) { /* Update ctx.p[1] via watcher. */ - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); sv = ctx->p[1]; } } @@ -1419,7 +1419,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) px = main_proxies_first(); watcher_attach(&ctx->px_watch, px); if (likely(px)) { - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); sv = ctx->p[1]; } } @@ -1486,7 +1486,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) goto full; next_sv2: - sv = watcher_next(&ctx->srv_watch, sv->next); + sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv)); } next_px2: @@ -1494,7 +1494,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) px = watcher_next(&ctx->px_watch, main_proxies_next(px)); if (px) { /* Update ctx.p[1] via watcher. */ - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); sv = ctx->p[1]; } } @@ -1507,7 +1507,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) px = main_proxies_first(); watcher_attach(&ctx->px_watch, px); if (likely(px)) { - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); sv = ctx->p[1]; } } @@ -1793,7 +1793,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx) watcher_attach(&ctx->px_watch, px); if (likely(px)) { /* Update ctx.p[1] via watcher. */ - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); } } __fallthrough; diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index ff1526801..8470d61cc 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -346,6 +346,16 @@ static inline struct proxy *main_proxies_next(const struct proxy *px) return LIST_ELEM(px->el.n, struct proxy *, el); } +static inline struct server *proxy_first_server(const struct proxy *px) +{ + return px->srv; +} + +static inline struct server *proxy_next_server(const struct server *srv) +{ + return srv->next; +} + #endif /* _HAPROXY_PROXY_H */ /* diff --git a/src/cfgparse-peers.c b/src/cfgparse-peers.c index bf1f9a543..8d5b4ca2b 100644 --- a/src/cfgparse-peers.c +++ b/src/cfgparse-peers.c @@ -314,7 +314,7 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) } else if (strcmp(args[0], "peer") == 0 || strcmp(args[0], "server") == 0) { /* peer or server definition */ - struct server *prev_srv; + struct server *srv, *prev_srv; int local_peer, peer; int parse_addr = 0; @@ -365,10 +365,10 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) * or if we are parsing a "server" line and the current peer is not the local one. */ parse_addr = (peer || !local_peer) ? SRV_PARSE_PARSE_ADDR : 0; - prev_srv = curpeers->peers_fe->srv; + prev_srv = proxy_first_server(curpeers->peers_fe); err_code |= parse_server(file, linenum, args, curpeers->peers_fe, NULL, SRV_PARSE_IN_PEER_SECTION|parse_addr|SRV_PARSE_INITIAL_RESOLVE); - if (curpeers->peers_fe->srv == prev_srv) { + if (prev_srv == proxy_first_server(curpeers->peers_fe)) { /* parse_server didn't add a server: * Remove the newly allocated peer. */ @@ -404,31 +404,33 @@ int cfg_parse_peers(const char *file, int linenum, char **args, int kwm) goto out; } + srv = proxy_first_server(curpeers->peers_fe); + if (!parse_addr && bind_addr) { /* local peer declared using "server": has name but no * address: we use the known "bind" line addr settings * as implicit server's addr and port. */ - curpeers->peers_fe->srv->addr = *bind_addr; - curpeers->peers_fe->srv->svc_port = get_host_port(bind_addr); + srv->addr = *bind_addr; + srv->svc_port = get_host_port(bind_addr); } - if (nb_shards && curpeers->peers_fe->srv->shard > nb_shards) { + if (nb_shards && srv->shard > nb_shards) { ha_warning("parsing [%s:%d] : '%s %s' : %d peer shard greater value than %d shards value is ignored.\n", - file, linenum, args[0], args[1], curpeers->peers_fe->srv->shard, nb_shards); - curpeers->peers_fe->srv->shard = 0; + file, linenum, args[0], args[1], srv->shard, nb_shards); + srv->shard = 0; err_code |= ERR_WARN; } - if (curpeers->peers_fe->srv->init_addr_methods || curpeers->peers_fe->srv->resolvers_id || - curpeers->peers_fe->srv->do_check || curpeers->peers_fe->srv->do_agent) { + if (srv->init_addr_methods || srv->resolvers_id || + srv->do_check || srv->do_agent) { ha_warning("parsing [%s:%d] : '%s %s' : init_addr, resolvers, check and agent are ignored for peers.\n", file, linenum, args[0], args[1]); err_code |= ERR_WARN; } HA_SPIN_INIT(&newpeer->lock); - newpeer->srv = curpeers->peers_fe->srv; + newpeer->srv = srv; if (!newpeer->local) goto out; diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index 92f154263..6424fe2bb 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -1890,7 +1890,7 @@ int hlua_listable_servers_pairs_iterator(lua_State *L) if (ctx->px) { /* First iteration, initialize list on the first server */ - cur = ctx->px->srv; + cur = proxy_first_server(ctx->px); watcher_attach(&ctx->srv_watch, cur); ctx->px = NULL; } @@ -1906,7 +1906,7 @@ int hlua_listable_servers_pairs_iterator(lua_State *L) } /* compute next server */ - ctx->next = watcher_next(&ctx->srv_watch, cur->next); + ctx->next = watcher_next(&ctx->srv_watch, proxy_next_server(cur)); lua_pushstring(L, cur->id); hlua_fcn_new_server(L, cur); diff --git a/src/http_ana.c b/src/http_ana.c index 75369fe18..b4a57cb08 100644 --- a/src/http_ana.c +++ b/src/http_ana.c @@ -3424,7 +3424,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re */ if ((att_end - att_beg == s->be->cookie_len) && (s->be->cookie_name != NULL) && (memcmp(att_beg, s->be->cookie_name, att_end - att_beg) == 0)) { - struct server *srv = s->be->srv; + struct server *srv = proxy_first_server(s->be); char *delim; /* if we're in cookie prefix mode, we'll search the delimiter so that we @@ -3520,7 +3520,7 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re if ((delim == val_beg) || (s->flags & (SF_IGNORE_PRST | SF_ASSIGNED))) srv = NULL; - while (srv) { + for (; srv; srv = proxy_next_server(srv)) { if (srv->cookie && (srv->cklen == delim - val_beg) && !memcmp(val_beg, srv->cookie, delim - val_beg)) { if ((srv->cur_state != SRV_ST_STOPPED) || @@ -3541,7 +3541,6 @@ static void http_manage_client_side_cookies(struct stream *s, struct channel *re txn->flags |= TX_CK_DOWN; } } - srv = srv->next; } if (!srv && !(txn->flags & (TX_CK_DOWN|TX_CK_EXPIRED|TX_CK_OLD))) { diff --git a/src/lb_chash.c b/src/lb_chash.c index ce60bee8b..d19f06de4 100644 --- a/src/lb_chash.c +++ b/src/lb_chash.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -240,7 +241,7 @@ static void chash_set_server_status_down(struct server *srv) */ struct server *srv2 = p->lbprm.fbck; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && !((srv2->flags & SRV_F_BACKUP) && srv_willbe_usable(srv2))); @@ -301,7 +302,7 @@ static void chash_set_server_status_up(struct server *srv) */ struct server *srv2 = srv; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && (srv2 != p->lbprm.fbck)); if (srv2) p->lbprm.fbck = srv; diff --git a/src/lb_fas.c b/src/lb_fas.c index f789d19db..3f601d8a5 100644 --- a/src/lb_fas.c +++ b/src/lb_fas.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -106,7 +107,7 @@ static void fas_set_server_status_down(struct server *srv) */ struct server *srv2 = p->lbprm.fbck; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && !((srv2->flags & SRV_F_BACKUP) && srv_willbe_usable(srv2))); @@ -169,7 +170,7 @@ static void fas_set_server_status_up(struct server *srv) */ struct server *srv2 = srv; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && (srv2 != p->lbprm.fbck)); if (srv2) p->lbprm.fbck = srv; diff --git a/src/lb_fwlc.c b/src/lb_fwlc.c index 6c1cd13e0..c635d5edc 100644 --- a/src/lb_fwlc.c +++ b/src/lb_fwlc.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -560,7 +561,7 @@ static void fwlc_set_server_status_down(struct server *srv) */ struct server *srv2 = p->lbprm.fbck; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && !((srv2->flags & SRV_F_BACKUP) && srv_willbe_usable(srv2))); @@ -623,7 +624,7 @@ static void fwlc_set_server_status_up(struct server *srv) */ struct server *srv2 = srv; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && (srv2 != p->lbprm.fbck)); if (srv2) p->lbprm.fbck = srv; diff --git a/src/lb_fwrr.c b/src/lb_fwrr.c index 8d2386529..28fca679d 100644 --- a/src/lb_fwrr.c +++ b/src/lb_fwrr.c @@ -16,6 +16,7 @@ #include #include #include +#include static inline void fwrr_remove_from_tree(struct server *s, int tgid); @@ -68,7 +69,7 @@ static void fwrr_set_server_status_down(struct server *srv) */ struct server *srv2 = p->lbprm.fbck; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && !((srv2->flags & SRV_F_BACKUP) && srv_willbe_usable(srv2))); @@ -134,7 +135,7 @@ static void fwrr_set_server_status_up(struct server *srv) */ struct server *srv2 = srv; do { - srv2 = srv2->next; + srv2 = proxy_next_server(srv2); } while (srv2 && (srv2 != p->lbprm.fbck)); if (srv2) p->lbprm.fbck = srv; @@ -343,7 +344,7 @@ static int fwrr_init_server_groups(struct proxy *p) srv, i + 1); } j = 0; - for (srv = p->srv; srv && j < i; srv = srv->next) { + for (srv = proxy_first_server(p); srv && j < i; srv = proxy_next_server(srv)) { j++; if (!srv_currently_usable(srv)) continue; diff --git a/src/lb_map.c b/src/lb_map.c index 91d09caf5..e71400349 100644 --- a/src/lb_map.c +++ b/src/lb_map.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -152,13 +153,13 @@ static int init_server_map(struct proxy *p) * find a non-zero weight server. */ pgcd = 1; - srv = p->srv; + srv = proxy_first_server(p); while (srv && !srv->uweight) - srv = srv->next; + srv = proxy_next_server(srv); if (srv) { pgcd = srv->uweight; /* note: cannot be zero */ - while (pgcd > 1 && (srv = srv->next)) { + while (pgcd > 1 && (srv = proxy_next_server(srv))) { int w = srv->uweight; while (w) { int t = pgcd % w; diff --git a/src/proxy.c b/src/proxy.c index a1906f252..4789a86f6 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -4509,9 +4509,9 @@ static int dump_servers_state(struct appctx *appctx) char *srvrecord; if (!ctx->sv) - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); - for (; ctx->sv; watcher_next(&ctx->srv_watch, ctx->sv->next)) { + for (; ctx->sv; watcher_next(&ctx->srv_watch, proxy_next_server(ctx->sv))) { srv = ctx->sv; dump_server_addr(&srv->addr, srv_addr); diff --git a/src/resolvers.c b/src/resolvers.c index 2144561dc..1d99dd953 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -3780,7 +3780,7 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm) goto out; } - if (dns_stream_init(newnameserver, curr_resolvers->px->srv) < 0) { + if (dns_stream_init(newnameserver, proxy_first_server(curr_resolvers->px)) < 0) { ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum); err_code |= ERR_ALERT|ERR_ABORT; free(newnameserver); diff --git a/src/server.c b/src/server.c index 94a8e9772..1171c7364 100644 --- a/src/server.c +++ b/src/server.c @@ -6699,7 +6699,7 @@ leave: static int cli_parse_delete_server(char **args, char *payload, struct appctx *appctx, void *private) { struct proxy *be; - struct server *srv; + struct server *srv, *next; struct ist be_name, sv_name; struct watcher *srv_watch; const char *msg; @@ -6750,10 +6750,11 @@ static int cli_parse_delete_server(char **args, char *payload, struct appctx *ap if (srv->proxy->lbprm.ops && srv->proxy->lbprm.ops->server_deinit) srv->proxy->lbprm.ops->server_deinit(srv); + next = proxy_next_server(srv); + BUG_ON(next && next->flags & SRV_F_DELETED); while (!MT_LIST_ISEMPTY(&srv->watcher_list)) { srv_watch = MT_LIST_NEXT(&srv->watcher_list, struct watcher *, el); - BUG_ON(srv->next && srv->next->flags & SRV_F_DELETED); - watcher_next(srv_watch, srv->next); + watcher_next(srv_watch, next); } /* detach the server from the proxy linked list diff --git a/src/stats-proxy.c b/src/stats-proxy.c index dbcfdb9df..e9337769f 100644 --- a/src/stats-proxy.c +++ b/src/stats-proxy.c @@ -1529,7 +1529,7 @@ more: } /* for servers ctx.obj2 is set via watcher_attach() */ - watcher_attach(&ctx->srv_watch, px->srv); + watcher_attach(&ctx->srv_watch, proxy_first_server(px)); ctx->px_st = STAT_PX_ST_SV; __fallthrough; @@ -1537,7 +1537,7 @@ more: case STAT_PX_ST_SV: /* obj2 is updated and returned through watcher_next() */ for (sv = ctx->obj2; sv; - sv = watcher_next(&ctx->srv_watch, sv->next)) { + sv = watcher_next(&ctx->srv_watch, proxy_next_server(sv))) { if (stats_is_full(appctx, buf, htx)) goto full;