diff --git a/include/haproxy/cli-t.h b/include/haproxy/cli-t.h index 45eed35bc..a581f2a94 100644 --- a/include/haproxy/cli-t.h +++ b/include/haproxy/cli-t.h @@ -47,6 +47,7 @@ #define APPCTX_CLI_ST1_INTER (1 << 3) /* interactive mode (i.e. don't close after 1st cmd) */ #define APPCTX_CLI_ST1_PROMPT (1 << 4) /* display prompt */ #define APPCTX_CLI_ST1_TIMED (1 << 5) /* display timer in prompt */ +#define APPCTX_CLI_ST1_YIELD (1 << 6) /* forced yield between commands */ #define CLI_PREFIX_KW_NB 5 #define CLI_MAX_MATCHES 5 diff --git a/src/cli.c b/src/cli.c index 059e343d7..dea6c36f1 100644 --- a/src/cli.c +++ b/src/cli.c @@ -1087,6 +1087,7 @@ int cli_parse_cmdline(struct appctx *appctx) */ void cli_io_handler(struct appctx *appctx) { + appctx->st1 &= ~APPCTX_CLI_ST1_YIELD; if (unlikely(applet_fl_test(appctx, APPCTX_FL_EOS|APPCTX_FL_ERROR))) { appctx->st0 = CLI_ST_END; @@ -1282,8 +1283,10 @@ void cli_io_handler(struct appctx *appctx) } } - if ((b_data(&appctx->inbuf) && appctx->st0 == CLI_ST_PARSE_CMDLINE) || appctx->st0 == CLI_ST_PROCESS_CMDLINE) + if ((b_data(&appctx->inbuf) && appctx->st0 == CLI_ST_PARSE_CMDLINE) || appctx->st0 == CLI_ST_PROCESS_CMDLINE) { + appctx->st1 |= APPCTX_CLI_ST1_YIELD; appctx_wakeup(appctx); + } /* this forces us to yield between pipelined commands and * avoid extremely long latencies (e.g. "del map" etc). In @@ -3904,6 +3907,10 @@ error: size_t cli_raw_rcv_buf(struct appctx *appctx, struct buffer *buf, size_t count, unsigned int flags) { + /* don't send partial responses, we're just yielding to avoid CPU spikes */ + if (appctx->st1 & APPCTX_CLI_ST1_YIELD) + return 0; + return b_xfer(buf, &appctx->outbuf, MIN(count, b_data(&appctx->outbuf))); }