mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
CLEANUP: proxy/cli: take the "show errors" context definition out of the appctx
This makes use of the generic command context allocation so that the appctx doesn't have to declare a specific one anymore. The context is created during parsing. The code still has room for improvement, such as in the "flags" field where bits are hard-coded, but they weren't modified.
This commit is contained in:
parent
6177cfc3b5
commit
0fd8f0e236
@ -149,14 +149,6 @@ struct appctx {
|
|||||||
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
int iid, type, sid; /* proxy id, type and service id if bounding of stats is enabled */
|
||||||
int st_code; /* the status code returned by an action */
|
int st_code; /* the status code returned by an action */
|
||||||
} stats;
|
} stats;
|
||||||
struct {
|
|
||||||
int iid; /* if >= 0, ID of the proxy to filter on */
|
|
||||||
struct proxy *px; /* current proxy being dumped, NULL = not started yet. */
|
|
||||||
unsigned int flag; /* bit0: buffer being dumped, 0 = req, 1 = resp ; bit1=skip req ; bit2=skip resp. */
|
|
||||||
unsigned int ev_id; /* event ID of error being dumped */
|
|
||||||
int ptr; /* <0: headers, >=0 : text pointer to restart from */
|
|
||||||
int bol; /* pointer to beginning of current line */
|
|
||||||
} errors;
|
|
||||||
struct {
|
struct {
|
||||||
void *target; /* table we want to dump, or NULL for all */
|
void *target; /* table we want to dump, or NULL for all */
|
||||||
struct stktable *t; /* table being currently dumped (first if NULL) */
|
struct stktable *t; /* table being currently dumped (first if NULL) */
|
||||||
|
99
src/proxy.c
99
src/proxy.c
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include <haproxy/acl.h>
|
#include <haproxy/acl.h>
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
#include <haproxy/applet-t.h>
|
#include <haproxy/applet.h>
|
||||||
#include <haproxy/capture-t.h>
|
#include <haproxy/capture-t.h>
|
||||||
#include <haproxy/cfgparse.h>
|
#include <haproxy/cfgparse.h>
|
||||||
#include <haproxy/cli.h>
|
#include <haproxy/cli.h>
|
||||||
@ -3083,11 +3083,23 @@ static int cli_parse_enable_frontend(char **args, char *payload, struct appctx *
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* appctx context used during "show errors" */
|
||||||
|
struct show_errors_ctx {
|
||||||
|
struct proxy *px; /* current proxy being dumped, NULL = not started yet. */
|
||||||
|
unsigned int flag; /* bit0: buffer being dumped, 0 = req, 1 = resp ; bit1=skip req ; bit2=skip resp. */
|
||||||
|
unsigned int ev_id; /* event ID of error being dumped */
|
||||||
|
int iid; /* if >= 0, ID of the proxy to filter on */
|
||||||
|
int ptr; /* <0: headers, >=0 : text pointer to restart from */
|
||||||
|
int bol; /* pointer to beginning of current line */
|
||||||
|
};
|
||||||
|
|
||||||
/* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop
|
/* "show errors" handler for the CLI. Returns 0 if wants to continue, 1 to stop
|
||||||
* now.
|
* now.
|
||||||
*/
|
*/
|
||||||
static int cli_parse_show_errors(char **args, char *payload, struct appctx *appctx, void *private)
|
static int cli_parse_show_errors(char **args, char *payload, struct appctx *appctx, void *private)
|
||||||
{
|
{
|
||||||
|
struct show_errors_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
|
||||||
|
|
||||||
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -3096,22 +3108,22 @@ static int cli_parse_show_errors(char **args, char *payload, struct appctx *appc
|
|||||||
|
|
||||||
px = proxy_find_by_name(args[2], 0, 0);
|
px = proxy_find_by_name(args[2], 0, 0);
|
||||||
if (px)
|
if (px)
|
||||||
appctx->ctx.errors.iid = px->uuid;
|
ctx->iid = px->uuid;
|
||||||
else
|
else
|
||||||
appctx->ctx.errors.iid = atoi(args[2]);
|
ctx->iid = atoi(args[2]);
|
||||||
|
|
||||||
if (!appctx->ctx.errors.iid)
|
if (!ctx->iid)
|
||||||
return cli_err(appctx, "No such proxy.\n");
|
return cli_err(appctx, "No such proxy.\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
appctx->ctx.errors.iid = -1; // dump all proxies
|
ctx->iid = -1; // dump all proxies
|
||||||
|
|
||||||
appctx->ctx.errors.flag = 0;
|
ctx->flag = 0;
|
||||||
if (strcmp(args[3], "request") == 0)
|
if (strcmp(args[3], "request") == 0)
|
||||||
appctx->ctx.errors.flag |= 4; // ignore response
|
ctx->flag |= 4; // ignore response
|
||||||
else if (strcmp(args[3], "response") == 0)
|
else if (strcmp(args[3], "response") == 0)
|
||||||
appctx->ctx.errors.flag |= 2; // ignore request
|
ctx->flag |= 2; // ignore request
|
||||||
appctx->ctx.errors.px = NULL;
|
ctx->px = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3121,6 +3133,7 @@ static int cli_parse_show_errors(char **args, char *payload, struct appctx *appc
|
|||||||
*/
|
*/
|
||||||
static int cli_io_handler_show_errors(struct appctx *appctx)
|
static int cli_io_handler_show_errors(struct appctx *appctx)
|
||||||
{
|
{
|
||||||
|
struct show_errors_ctx *ctx = appctx->svcctx;
|
||||||
struct conn_stream *cs = appctx->owner;
|
struct conn_stream *cs = appctx->owner;
|
||||||
extern const char *monthname[12];
|
extern const char *monthname[12];
|
||||||
|
|
||||||
@ -3129,7 +3142,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
|
|
||||||
chunk_reset(&trash);
|
chunk_reset(&trash);
|
||||||
|
|
||||||
if (!appctx->ctx.errors.px) {
|
if (!ctx->px) {
|
||||||
/* the function had not been called yet, let's prepare the
|
/* the function had not been called yet, let's prepare the
|
||||||
* buffer for a response.
|
* buffer for a response.
|
||||||
*/
|
*/
|
||||||
@ -3144,39 +3157,39 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
||||||
goto cant_send;
|
goto cant_send;
|
||||||
|
|
||||||
appctx->ctx.errors.px = proxies_list;
|
ctx->px = proxies_list;
|
||||||
appctx->ctx.errors.bol = 0;
|
ctx->bol = 0;
|
||||||
appctx->ctx.errors.ptr = -1;
|
ctx->ptr = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we have two inner loops here, one for the proxy, the other one for
|
/* we have two inner loops here, one for the proxy, the other one for
|
||||||
* the buffer.
|
* the buffer.
|
||||||
*/
|
*/
|
||||||
while (appctx->ctx.errors.px) {
|
while (ctx->px) {
|
||||||
struct error_snapshot *es;
|
struct error_snapshot *es;
|
||||||
|
|
||||||
HA_RWLOCK_RDLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
|
HA_RWLOCK_RDLOCK(PROXY_LOCK, &ctx->px->lock);
|
||||||
|
|
||||||
if ((appctx->ctx.errors.flag & 1) == 0) {
|
if ((ctx->flag & 1) == 0) {
|
||||||
es = appctx->ctx.errors.px->invalid_req;
|
es = ctx->px->invalid_req;
|
||||||
if (appctx->ctx.errors.flag & 2) // skip req
|
if (ctx->flag & 2) // skip req
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
es = appctx->ctx.errors.px->invalid_rep;
|
es = ctx->px->invalid_rep;
|
||||||
if (appctx->ctx.errors.flag & 4) // skip resp
|
if (ctx->flag & 4) // skip resp
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!es)
|
if (!es)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (appctx->ctx.errors.iid >= 0 &&
|
if (ctx->iid >= 0 &&
|
||||||
appctx->ctx.errors.px->uuid != appctx->ctx.errors.iid &&
|
ctx->px->uuid != ctx->iid &&
|
||||||
(!es->oe || es->oe->uuid != appctx->ctx.errors.iid))
|
(!es->oe || es->oe->uuid != ctx->iid))
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (appctx->ctx.errors.ptr < 0) {
|
if (ctx->ptr < 0) {
|
||||||
/* just print headers now */
|
/* just print headers now */
|
||||||
|
|
||||||
char pn[INET6_ADDRSTRLEN];
|
char pn[INET6_ADDRSTRLEN];
|
||||||
@ -3197,12 +3210,12 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
port = 0;
|
port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (appctx->ctx.errors.flag & 1) {
|
switch (ctx->flag & 1) {
|
||||||
case 0:
|
case 0:
|
||||||
chunk_appendf(&trash,
|
chunk_appendf(&trash,
|
||||||
" frontend %s (#%d): invalid request\n"
|
" frontend %s (#%d): invalid request\n"
|
||||||
" backend %s (#%d)",
|
" backend %s (#%d)",
|
||||||
appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
|
ctx->px->id, ctx->px->uuid,
|
||||||
(es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
|
(es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->id : "<NONE>",
|
||||||
(es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
|
(es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1);
|
||||||
break;
|
break;
|
||||||
@ -3210,7 +3223,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
chunk_appendf(&trash,
|
chunk_appendf(&trash,
|
||||||
" backend %s (#%d): invalid response\n"
|
" backend %s (#%d): invalid response\n"
|
||||||
" frontend %s (#%d)",
|
" frontend %s (#%d)",
|
||||||
appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid,
|
ctx->px->id, ctx->px->uuid,
|
||||||
es->oe ? es->oe->id : "<NONE>" , es->oe ? es->oe->uuid : -1);
|
es->oe ? es->oe->id : "<NONE>" , es->oe ? es->oe->uuid : -1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3234,11 +3247,11 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
||||||
goto cant_send_unlock;
|
goto cant_send_unlock;
|
||||||
|
|
||||||
appctx->ctx.errors.ptr = 0;
|
ctx->ptr = 0;
|
||||||
appctx->ctx.errors.ev_id = es->ev_id;
|
ctx->ev_id = es->ev_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appctx->ctx.errors.ev_id != es->ev_id) {
|
if (ctx->ev_id != es->ev_id) {
|
||||||
/* the snapshot changed while we were dumping it */
|
/* the snapshot changed while we were dumping it */
|
||||||
chunk_appendf(&trash,
|
chunk_appendf(&trash,
|
||||||
" WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
|
" WARNING! update detected on this snapshot, dump interrupted. Please re-check!\n");
|
||||||
@ -3249,35 +3262,35 @@ static int cli_io_handler_show_errors(struct appctx *appctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* OK, ptr >= 0, so we have to dump the current line */
|
/* OK, ptr >= 0, so we have to dump the current line */
|
||||||
while (appctx->ctx.errors.ptr < es->buf_len && appctx->ctx.errors.ptr < global.tune.bufsize) {
|
while (ctx->ptr < es->buf_len && ctx->ptr < global.tune.bufsize) {
|
||||||
int newptr;
|
int newptr;
|
||||||
int newline;
|
int newline;
|
||||||
|
|
||||||
newline = appctx->ctx.errors.bol;
|
newline = ctx->bol;
|
||||||
newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, appctx->ctx.errors.ptr);
|
newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, ctx->ptr);
|
||||||
if (newptr == appctx->ctx.errors.ptr)
|
if (newptr == ctx->ptr)
|
||||||
goto cant_send_unlock;
|
goto cant_send_unlock;
|
||||||
|
|
||||||
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
if (ci_putchk(cs_ic(cs), &trash) == -1)
|
||||||
goto cant_send_unlock;
|
goto cant_send_unlock;
|
||||||
|
|
||||||
appctx->ctx.errors.ptr = newptr;
|
ctx->ptr = newptr;
|
||||||
appctx->ctx.errors.bol = newline;
|
ctx->bol = newline;
|
||||||
};
|
};
|
||||||
next:
|
next:
|
||||||
HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
|
HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &ctx->px->lock);
|
||||||
appctx->ctx.errors.bol = 0;
|
ctx->bol = 0;
|
||||||
appctx->ctx.errors.ptr = -1;
|
ctx->ptr = -1;
|
||||||
appctx->ctx.errors.flag ^= 1;
|
ctx->flag ^= 1;
|
||||||
if (!(appctx->ctx.errors.flag & 1))
|
if (!(ctx->flag & 1))
|
||||||
appctx->ctx.errors.px = appctx->ctx.errors.px->next;
|
ctx->px = ctx->px->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dump complete */
|
/* dump complete */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
cant_send_unlock:
|
cant_send_unlock:
|
||||||
HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock);
|
HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &ctx->px->lock);
|
||||||
cant_send:
|
cant_send:
|
||||||
cs_rx_room_blk(cs);
|
cs_rx_room_blk(cs);
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user