From 36a615d278769a2678446dc4977b77147e6ee1c2 Mon Sep 17 00:00:00 2001
From: Krzysztof Piotr Oledzki <ole#ans.pl>
Date: Sun, 20 Apr 2008 21:34:47 +0200
Subject: [BUG] Flush buffers also where there are exactly 0 bytes left
I noticed it was possible to get truncated http/csv stats. Sometimes. Usually the problem disappeared as fast as it appeared, but once it happend that my http-stats page was truncated for about one hour. It was quite weird as it happened independently for csv and http output and it took me some time to track & fix this bug.
Both buffer_write & buffer_write_chunk used to return 0 in two situations: is case of success or where there was exactly 0 bytes left. The first one is intentional but I believe the second one is not as it was not possible to distinguish between successful write and unsuccessful one, which means that if the buffer was 100% filled, it was never flushed and it was not possible to write more data.
This patch fixes this problem.
--- src/buffers.c | 12 +++++++----- src/dumpstats.c | 20 ++++++++++---------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/buffers.c b/src/buffers.c index 8b2c4d3..fa6b8a9 100644 --- a/src/buffers.c +++ b/src/buffers.cReceived on 2008/04/20 22:12
@@ -29,7 +29,7 @@ int init_buffer()
} -/* writes <len> bytes from message <msg> to buffer <buf>. Returns 0 in case of +/* writes <len> bytes from message <msg> to buffer <buf>. Returns -1 in case of * success, or the number of bytes available otherwise. * FIXME-20060521: handle unaligned data. */
@@ -48,10 +48,11 @@ int buffer_write(struct buffer *buf, const char *msg, int len)
buf->total += len; if (buf->r == buf->data + BUFSIZE) buf->r = buf->data; - return 0; + + return -1; } -/* writes the chunk <chunk> to buffer <buf>. Returns 0 in case of +/* writes the chunk <chunk> to buffer <buf>. Returns -1 in case of * success, or the number of bytes available otherwise. If the chunk * has been written, its size is automatically reset to zero. */
@@ -60,7 +61,7 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
int max; if (chunk->len == 0) - return 0; + return -1; max = buffer_realign(buf);
@@ -74,7 +75,8 @@ int buffer_write_chunk(struct buffer *buf, struct chunk *chunk)
if (buf->r == buf->data + BUFSIZE) buf->r = buf->data; chunk->len = 0; - return 0; + + return -1; } /* diff --git a/src/dumpstats.c b/src/dumpstats.c index a9fb84d..ddadddd 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c
@@ -204,7 +204,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri)
case DATA_ST_HEAD: if (s->data_ctx.stats.flags & STAT_SHOW_STAT) { print_csv_header(&msg, sizeof(trash)); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -240,7 +240,7 @@ int stats_dump_raw(struct session *s, struct uri_auth *uri)
global.maxconn, actconn ); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -422,7 +422,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
} else { print_csv_header(&msg, sizeof(trash)); } - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; s->data_state = DATA_ST_INFO;
@@ -532,7 +532,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
"" ); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -561,7 +561,7 @@ int stats_dump_http(struct session *s, struct uri_auth *uri)
case DATA_ST_END: if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) { chunk_printf(&msg, sizeof(trash), "</body></html>\n"); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -656,7 +656,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
"</tr>", px->id); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -725,7 +725,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
relative_pid, px->uuid, STATS_TYPE_FE); } - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -942,7 +942,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
/* type, then EOL */ chunk_printf(&msg, sizeof(trash), "%d,\n", STATS_TYPE_SV); } - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; } /* for sv */
@@ -1039,7 +1039,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
relative_pid, px->uuid, px->cum_lbconn, STATS_TYPE_BE); } - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; }
@@ -1050,7 +1050,7 @@ int stats_dump_proxy(struct session *s, struct proxy *px, struct uri_auth *uri)
if (!(s->data_ctx.stats.flags & STAT_FMT_CSV)) { chunk_printf(&msg, sizeof(trash), "</table><p>\n"); - if (buffer_write_chunk(rep, &msg) != 0) + if (buffer_write_chunk(rep, &msg) >= 0) return 0; } -- 1.5.4.3
This archive was generated by hypermail 2.2.0 : 2008/04/20 22:15 CEST