]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proxy: use dynamic allocation for error dumps
authorWilly Tarreau <w@1wt.eu>
Thu, 31 Mar 2016 11:45:10 +0000 (13:45 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 31 Mar 2016 11:49:23 +0000 (13:49 +0200)
There are two issues with error captures. The first one is that the
capture size is still hard-coded to BUFSIZE regardless of any possible
tune.bufsize setting and of the fact that frontends only capture request
errors and that backends only capture response errors. The second is that
captures are allocated in both directions for all proxies, which start to
count a lot in configs using thousands of proxies.

This patch changes this so that error captures are allocated only when
needed, and of the proper size. It also refrains from dumping a buffer
that was not allocated, which still allows to emit all relevant info
such as flags and HTTP states. This way it is possible to save up to
32 kB of RAM per proxy in the default configuration.

include/types/proxy.h
src/dumpstats.c
src/proto_http.c

index 79a34117f8e58b2219aaf40413de63f58819c4a2..e23b4e4bfa7e99be64d482d871c2f32d957ad993 100644 (file)
@@ -221,7 +221,7 @@ struct error_snapshot {
        struct server *srv;             /* server associated with the error (or NULL) */
        struct proxy *oe;               /* other end = frontend or backend involved */
        struct sockaddr_storage src;    /* client's address */
-       char buf[BUFSIZE];              /* copy of the beginning of the message */
+       char *buf;                      /* copy of the beginning of the message (may be NULL) */
 };
 
 struct email_alert {
index 447e6f0cc37e7e6de51c374d3a82d20fb0b23ada..341fd56e91567945f4926e1a140f5de23f16defe 100644 (file)
@@ -7032,12 +7032,12 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si)
                }
 
                /* OK, ptr >= 0, so we have to dump the current line */
-               while (appctx->ctx.errors.ptr < es->len && appctx->ctx.errors.ptr < sizeof(es->buf)) {
+               while (es->buf && appctx->ctx.errors.ptr < es->len && appctx->ctx.errors.ptr < global.tune.bufsize) {
                        int newptr;
                        int newline;
 
                        newline = appctx->ctx.errors.bol;
-                       newptr = dump_text_line(&trash, es->buf, sizeof(es->buf), es->len, &newline, appctx->ctx.errors.ptr);
+                       newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->len, &newline, appctx->ctx.errors.ptr);
                        if (newptr == appctx->ctx.errors.ptr)
                                return 0;
 
index ddf05448cc7075f94ba82695640c6ce2b1365e8b..0b2001198d7425048c3819d164418adf7c7e6505 100644 (file)
@@ -8382,14 +8382,19 @@ void http_capture_bad_message(struct error_snapshot *es, struct stream *s,
        struct channel *chn = msg->chn;
        int len1, len2;
 
-       es->len = MIN(chn->buf->i, sizeof(es->buf));
+       es->len = MIN(chn->buf->i, global.tune.bufsize);
        len1 = chn->buf->data + chn->buf->size - chn->buf->p;
        len1 = MIN(len1, es->len);
        len2 = es->len - len1; /* remaining data if buffer wraps */
 
-       memcpy(es->buf, chn->buf->p, len1);
-       if (len2)
-               memcpy(es->buf + len1, chn->buf->data, len2);
+       if (!es->buf)
+               es->buf = malloc(global.tune.bufsize);
+
+       if (es->buf) {
+               memcpy(es->buf, chn->buf->p, len1);
+               if (len2)
+                       memcpy(es->buf + len1, chn->buf->data, len2);
+       }
 
        if (msg->err_pos >= 0)
                es->pos = msg->err_pos;