From: Aurelien DARRAGON Date: Thu, 18 Sep 2025 11:29:53 +0000 (+0200) Subject: BUG/MEDIUM: sink: fix unexpected double postinit of sink backend X-Git-Tag: v3.3-dev9~51 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=40eb1dd13545248ce062d704aa894ad288c339b1;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: sink: fix unexpected double postinit of sink backend Willy experienced an unexpected behavior with the config below: global stats socket :1514 ring buf1 server srv1 127.0.0.1:1514 Indeed, haproxy would connect to the ring server twice since commit 23e5f18b ("MEDIUM: sink: change the sink mode type to PR_MODE_SYSLOG"), and one of the connection would report errors. The reason behind is is, despite the above commit saying no change of behavior is expected, with the sink forward_px proxy now being set with PR_MODE_SYSLOG, postcheck_log_backend() was being automatically executed in addition to the manual cfg_post_parse_ring() function for each "ring" section. The consequence is that sink_finalize() was called twice for a given "ring" section, which means the connection init would be triggered twice.. which in turn resulted in the behavior described above, plus possible unexpected side-effects. To fix the issue, when we create the forward_px proxy, we now set the PR_CAP_INT capability on it to tell haproxy not to automatically manage the proxy (ie: to skip the automatic log backend postinit), because we are about to manually manage the proxy from the sink API. No backport needed, this bug is specific to 3.3 --- diff --git a/src/log.c b/src/log.c index a1cc0bc3e..c95905ee2 100644 --- a/src/log.c +++ b/src/log.c @@ -1350,8 +1350,8 @@ static int postcheck_log_backend(struct proxy *be) int err_code = ERR_NONE; int target_type = -1; // -1 is unused in log_tgt enum - if (!(be->cap & PR_CAP_BE) || be->mode != PR_MODE_SYSLOG || - (be->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) + if ((be->cap & PR_CAP_INT) || !(be->cap & PR_CAP_BE) || + be->mode != PR_MODE_SYSLOG || (be->flags & (PR_FL_DISABLED|PR_FL_STOPPED))) return ERR_NONE; /* nothing to do */ err_code |= _postcheck_log_backend_compat(be); diff --git a/src/sink.c b/src/sink.c index 4485e95e5..7a31d3827 100644 --- a/src/sink.c +++ b/src/sink.c @@ -842,8 +842,11 @@ static struct sink *sink_new_ringbuf(const char *id, const char *description, struct sink *sink; struct proxy *p = NULL; // forward_px - /* allocate new proxy to handle forwards */ - p = alloc_new_proxy(id, PR_CAP_BE, err_msg); + /* allocate new proxy to handle forwards, mark it as internal proxy + * because we don't want haproxy to do the automatic syslog backend + * init, instead we will manage it by hand + */ + p = alloc_new_proxy(id, PR_CAP_BE|PR_CAP_INT, err_msg); if (!p) goto err;