]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: lb-chash: free lb_nodes from chash's deinit(), not global
authorWilly Tarreau <w@1wt.eu>
Tue, 10 Feb 2026 05:49:24 +0000 (06:49 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 10 Feb 2026 06:20:50 +0000 (07:20 +0100)
There's an ambuity on the ownership of lb_nodes in chash, it's allocated
by chash but freed by the server code in srv_free_params() from srv_drop()
upon deinit. Let's move this free() call to a chash-specific function
which will own the responsibility for doing this instead. Note that
the .server_deinit() callback is properly called both on proxy being
taken down and on server deletion.

src/lb_chash.c
src/server.c

index 59300d13a9c784e6b9f6c06d8f83cf55851fa892..9e902545864f4cf5576c71e40c18ba8a52e79b44 100644 (file)
@@ -552,6 +552,12 @@ struct server *chash_get_next_server(struct proxy *p, struct server *srvtoavoid)
        return srv;
 }
 
+/* Releases the allocated lb_nodes for this server */
+void chash_server_deinit(struct server *srv)
+{
+       ha_free(&srv->lb_nodes);
+}
+
 /* This function is responsible for building the active and backup trees for
  * consistent hashing. The servers receive an array of initialized nodes
  * with their assigned keys. It also sets p->lbprm.wdiv to the eweight to
@@ -567,6 +573,7 @@ int chash_init_server_tree(struct proxy *p)
        p->lbprm.set_server_status_up   = chash_set_server_status_up;
        p->lbprm.set_server_status_down = chash_set_server_status_down;
        p->lbprm.update_server_eweight  = chash_update_server_weight;
+       p->lbprm.server_deinit          = chash_server_deinit;
        p->lbprm.server_take_conn = NULL;
        p->lbprm.server_drop_conn = NULL;
 
index a475c881bbdb238b975bba93f637d826545f5ff9..2452f0382dea635638da2c771664cf8f83f25ac7 100644 (file)
@@ -3184,7 +3184,6 @@ void srv_free_params(struct server *srv)
        free(srv->cc_algo);
        free(srv->tcp_md5sig);
        free(srv->addr_key);
-       free(srv->lb_nodes);
        counters_be_shared_drop(&srv->counters.shared);
        if (srv->log_target) {
                deinit_log_target(srv->log_target);