From f3764b79938e175c1f6507f01b56ec33b425f754 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 31 Mar 2016 13:45:10 +0200 Subject: [PATCH] MEDIUM: proxy: use dynamic allocation for error dumps 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 | 2 +- src/dumpstats.c | 4 ++-- src/proto_http.c | 13 +++++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/types/proxy.h b/include/types/proxy.h index 79a34117f8..e23b4e4bfa 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -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 { diff --git a/src/dumpstats.c b/src/dumpstats.c index 447e6f0cc3..341fd56e91 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -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; diff --git a/src/proto_http.c b/src/proto_http.c index ddf05448cc..0b2001198d 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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; -- 2.47.3