From: Amaury Denoyelle Date: Wed, 15 Jul 2026 14:30:45 +0000 (+0200) Subject: MINOR: proxy: define proxies_list iteration functions X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=164d05706132107a405d23663dbca29916910f55;p=thirdparty%2Fhaproxy.git MINOR: proxy: define proxies_list iteration functions Define wrappers function for iteration. These functions are used when a standard for loop over the whole list is not desirable. The objective of this patch is to ease the conversion of from a singly linked list to a standard doubly linked list type. This will help to keep the final conversion patch smaller. Also, iteration over struct list is sligthly more complicated as it requires more operation, for example for list end detection. Thus, the wrappers will become handy to avoid tedious code repetion. --- diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c index a0ebdff63..f387bb672 100644 --- a/addons/promex/service-prometheus.c +++ b/addons/promex/service-prometheus.c @@ -539,9 +539,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx) if (promex_filter_metric(appctx, prefix, name)) continue; - if (!px) - px = proxies_list; - + px = main_proxies_cond_first(px); while (px) { struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; enum promex_mt_type type; @@ -618,7 +616,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx) &val, labels, &out, max)) goto full; next_px: - px = px->next; + px = main_proxies_next(px); } ctx->flags |= PROMEX_FL_METRIC_HDR; } @@ -643,9 +641,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx) if (promex_filter_metric(appctx, prefix, name)) continue; - if (!px) - px = proxies_list; - + px = main_proxies_cond_first(px); while (px) { struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; struct promex_metric metric; @@ -680,7 +676,7 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx) goto full; next_px2: - px = px->next; + px = main_proxies_next(px); } ctx->flags |= PROMEX_FL_METRIC_HDR; } @@ -739,9 +735,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx) if (promex_filter_metric(appctx, prefix, name)) continue; - if (!px) - px = proxies_list; - + px = main_proxies_cond_first(px); while (px) { struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; int lb_idx = 0; @@ -806,7 +800,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx) li = NULL; next_px: - px = px->next; + px = main_proxies_next(px); } ctx->flags |= PROMEX_FL_METRIC_HDR; } @@ -831,9 +825,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx) if (promex_filter_metric(appctx, prefix, name)) continue; - if (!px) - px = proxies_list; - + px = main_proxies_cond_first(px); while (px) { struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; struct promex_metric metric; @@ -879,7 +871,7 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx) li = NULL; next_px2: - px = px->next; + px = main_proxies_next(px); } ctx->flags |= PROMEX_FL_METRIC_HDR; } @@ -1097,7 +1089,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) &val, labels, &out, max)) goto full; next_px: - px = watcher_next(&ctx->px_watch, px->next); + px = watcher_next(&ctx->px_watch, main_proxies_next(px)); } watcher_detach(&ctx->px_watch); ctx->flags |= PROMEX_FL_METRIC_HDR; @@ -1105,8 +1097,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) /* Prepare a new iteration for the next stat column. * Update ctx.p[0] via watcher. */ - watcher_attach(&ctx->px_watch, proxies_list); - px = proxies_list; + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); } /* Skip extra counters */ @@ -1163,7 +1155,7 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) goto full; next_px2: - px = watcher_next(&ctx->px_watch, px->next); + px = watcher_next(&ctx->px_watch, main_proxies_next(px)); } watcher_detach(&ctx->px_watch); ctx->flags |= PROMEX_FL_METRIC_HDR; @@ -1171,8 +1163,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx) /* Prepare a new iteration for the next stat column. * Update ctx.p[0] via watcher. */ - watcher_attach(&ctx->px_watch, proxies_list); - px = proxies_list; + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); } ctx->field_num += mod->stats_count; @@ -1411,7 +1403,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) next_px: watcher_detach(&ctx->srv_watch); - px = watcher_next(&ctx->px_watch, px->next); + 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); @@ -1424,8 +1416,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) /* Prepare a new iteration for the next stat column. * Update ctx.p[0]/p[1] via px_watch/srv_watch. */ - watcher_attach(&ctx->px_watch, proxies_list); - px = proxies_list; + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); if (likely(px)) { watcher_attach(&ctx->srv_watch, px->srv); sv = ctx->p[1]; @@ -1499,7 +1491,7 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) next_px2: watcher_detach(&ctx->srv_watch); - px = watcher_next(&ctx->px_watch, px->next); + 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); @@ -1512,8 +1504,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx) /* Prepare a new iteration for the next stat column. * Update ctx.p[0]/p[1] via px_watch/srv_watch. */ - watcher_attach(&ctx->px_watch, proxies_list); - px = proxies_list; + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); if (likely(px)) { watcher_attach(&ctx->srv_watch, px->srv); sv = ctx->p[1]; @@ -1711,6 +1703,7 @@ static int promex_dump_all_modules_metrics(struct appctx *appctx, struct htx *ht static int promex_dump_metrics(struct appctx *appctx, struct htx *htx) { struct promex_ctx *ctx = appctx->svcctx; + struct proxy *px; int ret; switch (appctx->st1) { @@ -1773,7 +1766,8 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx) if (ctx->flags & PROMEX_FL_SCOPE_BACK) { /* Update ctx.p[0] via watcher. */ - watcher_attach(&ctx->px_watch, proxies_list); + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); } __fallthrough; @@ -1795,10 +1789,11 @@ static int promex_dump_metrics(struct appctx *appctx, struct htx *htx) if (ctx->flags & PROMEX_FL_SCOPE_SERVER) { /* Update ctx.p[0] via watcher. */ - watcher_attach(&ctx->px_watch, proxies_list); - if (likely(proxies_list)) { + px = main_proxies_first(); + watcher_attach(&ctx->px_watch, px); + if (likely(px)) { /* Update ctx.p[1] via watcher. */ - watcher_attach(&ctx->srv_watch, proxies_list->srv); + watcher_attach(&ctx->srv_watch, px->srv); } } __fallthrough; diff --git a/include/haproxy/proxy.h b/include/haproxy/proxy.h index 3d543024c..2884e8110 100644 --- a/include/haproxy/proxy.h +++ b/include/haproxy/proxy.h @@ -324,6 +324,28 @@ static inline void main_proxies_register(struct proxy *px) proxies_list = px; } +/* Returns first entry in main proxies list or NULL if empty. */ +static inline struct proxy *main_proxies_first(void) +{ + return proxies_list; +} + +/* Returns first entry in main proxies list unless is already set. This is + * useful when iterating over proxies with possible task yielding interruption. + */ +static inline struct proxy *main_proxies_cond_first(struct proxy *px) +{ + if (!px) + px = proxies_list; + return px; +} + +/* Return next entry after in main proxies list or NULL if reaching end of list. */ +static inline struct proxy *main_proxies_next(const struct proxy *px) +{ + return px->next; +} + #endif /* _HAPROXY_PROXY_H */ /* diff --git a/src/ech.c b/src/ech.c index d7e74dbcc..d5de79268 100644 --- a/src/ech.c +++ b/src/ech.c @@ -154,7 +154,7 @@ static int cli_parse_show_ech(char **args, char *payload, } else { ctx->specific_name = NULL; ctx->specific_ctx = NULL; - ctx->pp = proxies_list; + ctx->pp = main_proxies_first(); ctx->b = NULL; ctx->state = SHOW_ECH_ALL; } @@ -246,7 +246,7 @@ static int cli_io_handler_ech_details(struct appctx *appctx) bind_conf = ctx->b; p = ctx->pp; - for (; p; p = p->next) { + for (; p; p = main_proxies_next(p)) { if (!(p->cap & PR_CAP_FE) || LIST_ISEMPTY(&p->conf.bind)) continue; diff --git a/src/hlua_fcn.c b/src/hlua_fcn.c index f204c0a04..92f154263 100644 --- a/src/hlua_fcn.c +++ b/src/hlua_fcn.c @@ -2379,10 +2379,10 @@ int hlua_listable_proxies_pairs_iterator(lua_State *L) lua_pushstring(L, ctx->next->id); hlua_fcn_new_proxy(L, ctx->next); - ctx->next = watcher_next(&ctx->px_watch, ctx->next->next); + ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next)); for (; ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities); - ctx->next = watcher_next(&ctx->px_watch, ctx->next->next)) + ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next))) ; return 2; @@ -2426,9 +2426,9 @@ int hlua_listable_proxies_pairs(lua_State *L) ctx->next = NULL; watcher_init(&ctx->px_watch, &ctx->next, offsetof(struct proxy, watcher_list)); - for (watcher_attach(&ctx->px_watch, proxies_list); + for (watcher_attach(&ctx->px_watch, main_proxies_first()); ctx->next && !hlua_listable_proxies_match(ctx->next, ctx->capabilities); - ctx->next = watcher_next(&ctx->px_watch, ctx->next->next)) + ctx->next = watcher_next(&ctx->px_watch, main_proxies_next(ctx->next))) ; lua_pushcclosure(L, hlua_listable_proxies_pairs_iterator, 1); diff --git a/src/proxy.c b/src/proxy.c index f3d705fd9..23adbbf0e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -4592,10 +4592,10 @@ static int cli_io_handler_servers_state(struct appctx *appctx) ctx->state = SHOW_SRV_LIST; if (!ctx->px) - watcher_attach(&ctx->px_watch, proxies_list); + watcher_attach(&ctx->px_watch, main_proxies_first()); } - for (; ctx->px; watcher_next(&ctx->px_watch, ctx->px->next)) { + for (; ctx->px; watcher_next(&ctx->px_watch, main_proxies_next(ctx->px))) { curproxy = ctx->px; /* servers are only in backends */ if ((curproxy->cap & PR_CAP_BE) && !(curproxy->cap & PR_CAP_INT)) { @@ -4629,11 +4629,11 @@ static int cli_io_handler_show_backend(struct appctx *appctx) watcher_init(&ctx->px_watch, &ctx->px, offsetof(struct proxy, watcher_list)); /* This will automatically update ctx->px pointer. */ - watcher_attach(&ctx->px_watch, proxies_list); + watcher_attach(&ctx->px_watch, main_proxies_first()); } - for (; ctx->px; watcher_next(&ctx->px_watch, ctx->px->next)) { - curproxy = ctx->px; + for (; ctx->px; watcher_next(&ctx->px_watch, main_proxies_next(ctx->px))) { + curproxy = appctx->svcctx; /* looking for non-internal backends only */ if ((curproxy->cap & (PR_CAP_BE|PR_CAP_INT)) != PR_CAP_BE) @@ -5111,7 +5111,7 @@ static int cli_parse_delete_backend(char **args, char *payload, struct appctx *a while (!MT_LIST_ISEMPTY(&px->watcher_list)) { px_watch = MT_LIST_NEXT(&px->watcher_list, struct watcher *, el); - watcher_next(px_watch, px->next); + watcher_next(px_watch, main_proxies_next(px)); } ceb32_item_delete(&used_proxy_id, conf.uuid_node, uuid, px); @@ -5327,7 +5327,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx) if (applet_putchk(appctx, &trash) == -1) goto cant_send; - watcher_attach(&ctx->px_watch, proxies_list); + watcher_attach(&ctx->px_watch, main_proxies_first()); ctx->bol = 0; ctx->ptr = -1; } @@ -5459,7 +5459,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx) ctx->ptr = -1; ctx->flag ^= 1; if (!(ctx->flag & 1)) - watcher_next(&ctx->px_watch, ctx->px->next); + watcher_next(&ctx->px_watch, main_proxies_next(ctx->px)); } /* dump complete */ diff --git a/src/ssl_ckch.c b/src/ssl_ckch.c index c3de2cbd8..59fb01456 100644 --- a/src/ssl_ckch.c +++ b/src/ssl_ckch.c @@ -1720,15 +1720,15 @@ static int cli_io_handler_show_sni(struct appctx *appctx) return 1; /* ctx->bind is NULL only once we finished dumping a frontend or when starting - * so let's dump the header in these cases*/ + * so let's dump the header in these cases. + */ if (ctx->bind == NULL && (ctx->options & SHOW_SNI_OPT_1FRONTEND || - (!(ctx->options & SHOW_SNI_OPT_1FRONTEND) && ctx->px == proxies_list))) + (!(ctx->options & SHOW_SNI_OPT_1FRONTEND) && ctx->px == main_proxies_first()))) chunk_appendf(trash, "# Frontend/Bind\tSNI\tNegative Filter\tType\tFilename\tNotAfter\tNotBefore\n"); if (applet_putchk(appctx, trash) == -1) goto yield; - for (px = ctx->px; px; px = px->next) { - + for (px = ctx->px; px; px = main_proxies_next(px)) { /* only check the frontends which are not internal proxies */ if (!(px->cap & PR_CAP_FE) || (px->cap & PR_CAP_INT)) continue; @@ -1851,7 +1851,7 @@ static int cli_parse_show_sni(char **args, char *payload, struct appctx *appctx, struct show_sni_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx)); int cur_arg = 3; - ctx->px = proxies_list; + ctx->px = main_proxies_first(); /* look for the right to display */ diff --git a/src/stats-proxy.c b/src/stats-proxy.c index 9238810ef..5b43aac57 100644 --- a/src/stats-proxy.c +++ b/src/stats-proxy.c @@ -1635,7 +1635,7 @@ int stats_dump_proxies(struct stconn *sc, struct buffer *buf, struct htx *htx) /* dump proxies */ /* obj1 is updated and returned through watcher_next() */ for (px = ctx->obj1; px; - px = watcher_next(&ctx->px_watch, px->next)) { + px = watcher_next(&ctx->px_watch, main_proxies_next(px))) { if (stats_is_full(appctx, buf, htx)) goto full; diff --git a/src/stats.c b/src/stats.c index 6843f49b4..442632ad4 100644 --- a/src/stats.c +++ b/src/stats.c @@ -596,7 +596,7 @@ int stats_dump_stat_to_buffer(struct stconn *sc, struct buffer *buf, struct htx ctx->state = STAT_STATE_LIST; /* Update ctx->obj1 via watcher to point on the first proxy. */ if (domain == STATS_DOMAIN_PROXY) - watcher_attach(&ctx->px_watch, proxies_list); + watcher_attach(&ctx->px_watch, main_proxies_first()); __fallthrough;