]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proxy: take the defsrv out of the struct proxy
authorWilly Tarreau <w@1wt.eu>
Thu, 10 Jul 2025 14:16:24 +0000 (16:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 15 Jul 2025 08:34:18 +0000 (10:34 +0200)
The server struct has gone huge over time (~3.8kB), and having a copy
of it in the defsrv section of the struct proxy costs a lot of RAM,
that is not needed anymore at run time.

This patch replaces this struct with a dynamically allocated one. The
field is allocated and initialized during alloc_new_proxy() and is
freed when the proxy is destroyed for now. But the goal will be to
support freeing it after parsing the section.

include/haproxy/proxy-t.h
src/http_client.c
src/proxy.c
src/server.c

index 2d08a7852c8f145c31376305ea09cf82768a0506..2d4971012b70783cc9c8371311e6b80049620163 100644 (file)
@@ -352,7 +352,7 @@ struct proxy {
 #ifdef USE_QUIC
        struct list quic_init_rules;            /* quic-initial rules */
 #endif
-       struct server *srv, defsrv;             /* known servers; default server configuration */
+       struct server *srv, *defsrv;            /* known servers; default server configuration */
        struct lbprm lbprm;                     /* load-balancing parameters */
        int srv_act, srv_bck;                   /* # of servers eligible for LB (UP|!checked) AND (enabled+weight!=0) */
        int served;                             /* # of active sessions currently being served */
index cffc5de7e2e4945560e45a1408dddab8262ac149..8381e043435bae0e6e72c4f649cdfa6378895c84 100644 (file)
@@ -1145,7 +1145,7 @@ struct proxy *httpclient_create_proxy(const char *id)
                goto err;
        }
 
-       srv_settings_cpy(srv_raw, &px->defsrv, 0);
+       srv_settings_cpy(srv_raw, px->defsrv, 0);
        srv_raw->iweight = 0;
        srv_raw->uweight = 0;
        srv_raw->xprt = xprt_get(XPRT_RAW);
@@ -1165,7 +1165,7 @@ struct proxy *httpclient_create_proxy(const char *id)
                err_code |= ERR_ALERT | ERR_FATAL;
                goto err;
        }
-       srv_settings_cpy(srv_ssl, &px->defsrv, 0);
+       srv_settings_cpy(srv_ssl, px->defsrv, 0);
        srv_ssl->iweight = 0;
        srv_ssl->uweight = 0;
        srv_ssl->xprt = xprt_get(XPRT_SSL);
index 24939662f3bcabd6efe3b37d0e71cb28659821f7..deef09b02d85b39481d6862b4707f96f9b4765fa 100644 (file)
@@ -386,7 +386,10 @@ void deinit_proxy(struct proxy *p)
        /* also free default-server parameters since some of them might have
         * been dynamically allocated (e.g.: config hints, cookies, ssl..)
         */
-       srv_free_params(&p->defsrv);
+       if (p->defsrv) {
+               srv_free_params(p->defsrv);
+               ha_free(&p->defsrv);
+       }
 
        if (p->lbprm.proxy_deinit)
                p->lbprm.proxy_deinit(p);
@@ -1477,7 +1480,6 @@ void init_new_proxy(struct proxy *p)
 
        MT_LIST_INIT(&p->lbprm.lb_free_list);
 
-       p->defsrv.id = "default-server";
        p->conf.used_listener_id = EB_ROOT;
        p->conf.used_server_id   = EB_ROOT;
        p->used_server_addr      = EB_ROOT_UNIQUE;
@@ -1531,8 +1533,6 @@ void proxy_preset_defaults(struct proxy *defproxy)
                defproxy->options2 |= PR_O2_INDEPSTR;
        defproxy->max_out_conns = MAX_SRV_LIST;
 
-       srv_settings_init(&defproxy->defsrv);
-
        lf_expr_init(&defproxy->logformat);
        lf_expr_init(&defproxy->logformat_sd);
        lf_expr_init(&defproxy->format_unique_id);
@@ -1557,8 +1557,9 @@ void proxy_free_defaults(struct proxy *defproxy)
        proxy_free_common(defproxy);
 
        /* default proxy specific cleanup */
-       ha_free((char **)&defproxy->defsrv.conf.file);
+       ha_free((char **)&defproxy->defsrv->conf.file);
        ha_free(&defproxy->defbe.name);
+       ha_free(&defproxy->defsrv);
 
        h = defproxy->req_cap;
        while (h) {
@@ -1683,6 +1684,16 @@ int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char *
 {
        init_new_proxy(px);
 
+       /* allocate the default server section */
+       px->defsrv = calloc(1, sizeof(*px->defsrv));
+       if (!px->defsrv) {
+               memprintf(errmsg, "out of memory");
+               goto fail;
+       }
+
+       px->defsrv->id = "default-server";
+       srv_settings_init(px->defsrv);
+
        if (name) {
                px->id = strdup(name);
                if (!px->id) {
@@ -1706,6 +1717,7 @@ int setup_new_proxy(struct proxy *px, const char *name, unsigned int cap, char *
        if (name)
                memprintf(errmsg, "proxy '%s': %s", name, *errmsg);
 
+       ha_free(&px->defsrv);
        ha_free(&px->id);
        counters_fe_shared_drop(px->fe_counters.shared);
        counters_be_shared_drop(px->be_counters.shared);
@@ -1736,6 +1748,8 @@ struct proxy *alloc_new_proxy(const char *name, unsigned int cap, char **errmsg)
         * but its not worth trying to unroll everything here just before
         * quitting.
         */
+       if (curproxy)
+               free(curproxy->defsrv);
        free(curproxy);
        return NULL;
 }
@@ -1792,7 +1806,7 @@ static int proxy_defproxy_cpy(struct proxy *curproxy, const struct proxy *defpro
        struct eb32_node *node;
 
        /* set default values from the specified default proxy */
-       srv_settings_cpy(&curproxy->defsrv, &defproxy->defsrv, 0);
+       srv_settings_cpy(curproxy->defsrv, defproxy->defsrv, 0);
 
        curproxy->flags = (defproxy->flags & PR_FL_DISABLED); /* Only inherit from disabled flag */
        curproxy->options = defproxy->options;
index 2722195346917bbf33e80b81e220b802c1808db1..acf397e55ef83dd0f07fe424623e50bd0a0e43a3 100644 (file)
@@ -2706,7 +2706,7 @@ static void srv_ssl_settings_cpy(struct server *srv, const struct server *src)
        /* <src> is the current proxy's default server and SSL is enabled */
        BUG_ON(src->ssl_ctx.ctx != NULL); /* the SSL_CTX must never be initialized in a default-server */
 
-       if (srv->proxy && src == &srv->proxy->defsrv && src->use_ssl == 1)
+       if (srv->proxy && src == srv->proxy->defsrv && src->use_ssl == 1)
                srv->flags |= SRV_F_DEFSRV_USE_SSL;
 
        if (src->ssl_ctx.ca_file != NULL)
@@ -3692,13 +3692,13 @@ static int _srv_parse_init(struct server **srv, char **args, int *cur_arg,
  skip_addr:
                if (!(parse_flags & SRV_PARSE_DYNAMIC)) {
                        /* Copy default server settings to new server */
-                       srv_settings_cpy(newsrv, &curproxy->defsrv, 0);
+                       srv_settings_cpy(newsrv, curproxy->defsrv, 0);
                } else
                        srv_settings_init(newsrv);
                HA_SPIN_INIT(&newsrv->lock);
        }
        else {
-               *srv = newsrv = &curproxy->defsrv;
+               *srv = newsrv = curproxy->defsrv;
                *cur_arg = 1;
        }