]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MEDIUM: sink: pre-initialize the implicit log forwarding server
authorWilly Tarreau <w@1wt.eu>
Wed, 19 Aug 2026 15:24:14 +0000 (17:24 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 19 Aug 2026 15:48:20 +0000 (17:48 +0200)
Since commit 368d01361a ("MEDIUM: server: add and use srv_init() function")
a "log tcp@127.0.0.1:514" line in the global section causes a segfault at
boot, without even trying to connect anywhere.

In this case the target is a ring, which relies on a server to forward
its data. That server is created by sink_new_from_logger(), which is
reached from postresolve_loggers() in REGISTER_POST_CHECK, so it runs
after check_config_validity() has walked all_servers to call srv_preinit()
on every known servers, and after the REGISTER_POST_SERVER_CHECK hooks.
The server therefore never gets initialized, srv->per_thr and srv->per_tgrp
are left NULL, and the first forwarding session dies in stream_set_target()
on per_tgrp[tgid - 1].nb_strm.

sink_new_from_logger() used to call srv_init_per_thr() itself before
the change above, srv_init() has since been split, and the per-thread
part is now srv_preinit(), so let's just call that from there.

Note that the same ordering means these servers also miss srv_postinit(),
so their shared counters stay NULL. They are not used with sinks so we
probably don't care and would better not touch that now, but it's worth
keeping in mind.

This should be backported to 3.3.

src/sink.c

index de2a4518a9a0511f85766ea41f7bf6c2cad9e269..97498c51d830983db291e99eda04c3ea64bd4f24 100644 (file)
@@ -1274,6 +1274,13 @@ struct sink *sink_new_from_logger(struct logger *logger)
        srv->svc_port = get_host_port(logger->target.addr);
        HA_SPIN_INIT(&srv->lock);
 
+       /* This server is created from a POST_CHECK hook, that is after
+        * check_config_validity() has run srv_preinit() over all the servers
+        * known at that point, so it would never be initialized otherwise.
+        */
+       if (srv_preinit(srv) & ERR_CODE)
+               goto error;
+
        if (sink_finalize(sink) & ERR_CODE)
                goto error;