]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: stats: show backend may show an empty or incomplete result
authorCyril Bonté <cyril.bonte@free.fr>
Fri, 6 May 2016 10:18:49 +0000 (12:18 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 6 May 2016 10:28:43 +0000 (12:28 +0200)
This is the same issue as "show servers state", where the result is incorrect
it the data can't fit in one buffer. The similar fix is applied, to restart
the data processing where it stopped as buffers are sent to the client.

This fix should be backported to haproxy 1.6

include/types/applet.h
src/dumpstats.c

index bf801f41dcf76c02933bf8897f3b6ea09c167e89..eb15456063dbbb212760d31cb52f3ac61bf50f7a 100644 (file)
@@ -135,6 +135,9 @@ struct appctx {
                        struct proxy *px;       /* current proxy being dumped, NULL = not started yet. */
                        struct server *sv;      /* current server being dumped, NULL = not started yet. */
                } server_state;
+               struct {
+                       struct proxy *px;       /* current proxy being dumped, NULL = not started yet. */
+               } be;                           /* used by "show backends" command */
                struct {
                        char **var;
                } env;
index a6d021bfc215369d6d66e69c75eb0b85eb3a24fa..4f0c43880146fd5541eacda3fe396dad4b248aa2 100644 (file)
@@ -1304,6 +1304,7 @@ static int stats_sock_parse_request(struct stream_interface *si, char *line)
        appctx->ctx.stats.flags = 0;
        if (strcmp(args[0], "show") == 0) {
                if (strcmp(args[1], "backend") == 0) {
+                       appctx->ctx.be.px = NULL;
                        appctx->st2 = STAT_ST_INIT;
                        appctx->st0 = STAT_CLI_O_BACKEND;
                }
@@ -3117,13 +3118,24 @@ static int dump_servers_state(struct stream_interface *si, struct chunk *buf)
 /* Parses backend list and simply report backend names */
 static int stats_dump_backend_to_buffer(struct stream_interface *si)
 {
+       struct appctx *appctx = __objt_appctx(si->end);
        extern struct proxy *proxy;
        struct proxy *curproxy;
 
        chunk_reset(&trash);
-       chunk_printf(&trash, "# name\n");
 
-       for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
+       if (!appctx->ctx.be.px) {
+               chunk_printf(&trash, "# name\n");
+               if (bi_putchk(si_ic(si), &trash) == -1) {
+                       si_applet_cant_put(si);
+                       return 0;
+               }
+               appctx->ctx.be.px = proxy;
+       }
+
+       for (; appctx->ctx.be.px != NULL; appctx->ctx.be.px = curproxy->next) {
+               curproxy = appctx->ctx.be.px;
+
                /* looking for backends only */
                if (!(curproxy->cap & PR_CAP_BE))
                        continue;
@@ -3133,11 +3145,10 @@ static int stats_dump_backend_to_buffer(struct stream_interface *si)
                        continue;
 
                chunk_appendf(&trash, "%s\n", curproxy->id);
-       }
-
-       if (bi_putchk(si_ic(si), &trash) == -1) {
-               si_applet_cant_put(si);
-               return 0;
+               if (bi_putchk(si_ic(si), &trash) == -1) {
+                       si_applet_cant_put(si);
+                       return 0;
+               }
        }
 
        return 1;