]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] stats: use a dedicated state to output static data
authorWilly Tarreau <w@1wt.eu>
Sun, 11 Oct 2009 21:12:51 +0000 (23:12 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Oct 2009 21:12:51 +0000 (23:12 +0200)
It is a bit expensive and complex to use to call buffer_feed()
directly from the request parser, and there are risks that some
output messages are lost in case of buffer full. Since most of
these messages are static, let's have a state dedicated to print
these messages and store them in a specific area shared with the
stats in the session. This both reduces code size and risks of
losing output data.

include/proto/dumpstats.h
include/types/session.h
src/dumpstats.c

index ea579f59ad73f85cb0af9e3d173cf05d5e668e33..0fe2bbefa4bd2102c7a9f18a82aa47475276c58c 100644 (file)
@@ -46,8 +46,8 @@
 #define STAT_CLI_GETREQ 2   /* wait for a request */
 #define STAT_CLI_OUTPUT 3   /* all states after this one are responses */
 #define STAT_CLI_PROMPT 3   /* display the prompt (first output, same code) */
+#define STAT_CLI_PRINT  4   /* display message in cli->msg */
 
-#define STAT_CLI_O_HELP 4   /* display help */
 #define STAT_CLI_O_INFO 5   /* dump info/stats */
 #define STAT_CLI_O_SESS 6   /* dump sessions */
 #define STAT_CLI_O_ERR  7   /* dump errors */
index 356f0caf3e2528d858121bc54329ff8388cdc20d..a8734ff1065972bf730836ebbda25d1c2290ebe1 100644 (file)
@@ -212,6 +212,9 @@ struct session {
                        int ptr;                /* <0: headers, >=0 : text pointer to restart from */
                        int bol;                /* pointer to beginning of current line */
                } errors;
+               struct {
+                       const char *msg;        /* pointer to a persistent message to be returned in PRINT state */
+               } cli;
        } data_ctx;                             /* used by stats I/O handlers to dump the stats */
        unsigned int uniq_id;                   /* unique ID used for the traces */
 };
index 510d0d25f790333409701cdf0554d478cd07a87f..6d42b41279a4e0b6bccee37bb67026c4d883ac8f 100644 (file)
@@ -250,7 +250,8 @@ int print_csv_header(struct chunk *msg)
 /* Processes the stats interpreter on the statistics socket. This function is
  * called from an applet running in a stream interface. The function returns 1
  * if the request was understood, otherwise zero. It sets si->st0 to a value
- * designating the function which will have to process the request.
+ * designating the function which will have to process the request, which can
+ * also be the print function to display the return message set into cli.msg.
  */
 int stats_sock_parse_request(struct stream_interface *si, char *line)
 {
@@ -305,14 +306,16 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                else if (strcmp(args[1], "sess") == 0) {
                        s->data_state = DATA_ST_INIT;
                        if (s->listener->perm.ux.level < ACCESS_LVL_OPER) {
-                               buffer_feed(si->ib, stats_permission_denied_msg);
+                               s->data_ctx.cli.msg = stats_permission_denied_msg;
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
                        si->st0 = STAT_CLI_O_SESS; // stats_dump_sess_to_buffer
                }
                else if (strcmp(args[1], "errors") == 0) {
                        if (s->listener->perm.ux.level < ACCESS_LVL_OPER) {
-                               buffer_feed(si->ib, stats_permission_denied_msg);
+                               s->data_ctx.cli.msg = stats_permission_denied_msg;
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
                        if (*args[2])
@@ -340,7 +343,8 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                        /* check permissions */
                        if (s->listener->perm.ux.level < ACCESS_LVL_OPER ||
                            (clrall && s->listener->perm.ux.level < ACCESS_LVL_ADMIN)) {
-                               buffer_feed(si->ib, stats_permission_denied_msg);
+                               s->data_ctx.cli.msg = stats_permission_denied_msg;
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
@@ -392,15 +396,14 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                                }
 
                        if (!*line) {
-                               buffer_feed(si->ib, "Require 'backend/server'.\n");
+                               s->data_ctx.cli.msg = "Require 'backend/server'.\n";
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
                        if (!get_backend_server(args[2], line, &px, &sv)) {
-                               if (!px)
-                                       buffer_feed(si->ib, "No such backend.\n");
-                               else
-                                       buffer_feed(si->ib, "No such server.\n");
+                               s->data_ctx.cli.msg = px ? "No such server.\n" : "No such backend.\n";
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
@@ -420,7 +423,8 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                        int w;
 
                        if (s->listener->perm.ux.level < ACCESS_LVL_ADMIN) {
-                               buffer_feed(si->ib, stats_permission_denied_msg);
+                               s->data_ctx.cli.msg = stats_permission_denied_msg;
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
@@ -432,15 +436,14 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                                }
 
                        if (!*line || !*args[3]) {
-                               buffer_feed(si->ib, "Require 'backend/server' and 'weight' or 'weight%'.\n");
+                               s->data_ctx.cli.msg = "Require 'backend/server' and 'weight' or 'weight%'.\n";
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
                        if (!get_backend_server(args[2], line, &px, &sv)) {
-                               if (!px)
-                                       buffer_feed(si->ib, "No such backend.\n");
-                               else
-                                       buffer_feed(si->ib, "No such server.\n");
+                               s->data_ctx.cli.msg = px ? "No such server.\n" : "No such backend.\n";
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
@@ -450,20 +453,23 @@ int stats_sock_parse_request(struct stream_interface *si, char *line)
                        w = atoi(args[3]);
                        if (strchr(args[3], '%') != NULL) {
                                if (w < 0 || w > 100) {
-                                       buffer_feed(si->ib, "Relative weight can only be set between 0 and 100% inclusive.\n");
+                                       s->data_ctx.cli.msg = "Relative weight can only be set between 0 and 100% inclusive.\n";
+                                       si->st0 = STAT_CLI_PRINT;
                                        return 1;
                                }
                                w = sv->iweight * w / 100;
                        }
                        else {
                                if (w < 0 || w > 256) {
-                                       buffer_feed(si->ib, "Absolute weight can only be between 0 and 256 inclusive.\n");
+                                       s->data_ctx.cli.msg = "Absolute weight can only be between 0 and 256 inclusive.\n";
+                                       si->st0 = STAT_CLI_PRINT;
                                        return 1;
                                }
                        }
 
                        if (w && w != sv->iweight && !(px->lbprm.algo & BE_LB_PROP_DYN)) {
-                               buffer_feed(si->ib, "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n");
+                               s->data_ctx.cli.msg = "Backend is using a static LB algorithm and only accepts weights '0%' and '100%'.\n";
+                               si->st0 = STAT_CLI_PRINT;
                                return 1;
                        }
 
@@ -576,8 +582,10 @@ void stats_io_handler(struct stream_interface *si)
                                else if (strcmp(trash, "prompt") == 0)
                                        si->st1 = !si->st1;
                                else if (strcmp(trash, "help") == 0 ||
-                                        !stats_sock_parse_request(si, trash))
-                                       si->st0 = STAT_CLI_O_HELP;
+                                        !stats_sock_parse_request(si, trash)) {
+                                       s->data_ctx.cli.msg = stats_sock_usage_msg;
+                                       si->st0 = STAT_CLI_PRINT;
+                               }
                                /* NB: stats_sock_parse_request() may have put
                                 * another STAT_CLI_O_* into si->st0.
                                 */
@@ -587,7 +595,8 @@ void stats_io_handler(struct stream_interface *si)
                                 * so that the user at least knows how to enable
                                 * prompt and find help.
                                 */
-                               si->st0 = STAT_CLI_O_HELP;
+                               s->data_ctx.cli.msg = stats_sock_usage_msg;
+                               si->st0 = STAT_CLI_PRINT;
                        }
 
                        /* re-adjust req buffer */
@@ -601,8 +610,8 @@ void stats_io_handler(struct stream_interface *si)
                        }
 
                        switch (si->st0) {
-                       case STAT_CLI_O_HELP:
-                               if (buffer_feed(si->ib, stats_sock_usage_msg) < 0)
+                       case STAT_CLI_PRINT:
+                               if (buffer_feed(si->ib, s->data_ctx.cli.msg) < 0)
                                        si->st0 = STAT_CLI_PROMPT;
                                break;
                        case STAT_CLI_O_INFO: