From: Willy Tarreau Date: Tue, 3 May 2022 09:24:24 +0000 (+0200) Subject: CLEANUP: proxy/cli: take the "show errors" context definition out of the appctx X-Git-Tag: v2.6-dev9~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0fd8f0e23609f1ac466199d75cf9308649aa0f2c;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/include/haproxy/applet-t.h b/include/haproxy/applet-t.h index 39479368d2..409a83f23e 100644 --- a/include/haproxy/applet-t.h +++ b/include/haproxy/applet-t.h @@ -149,14 +149,6 @@ struct appctx { 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 */ } 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 { void *target; /* table we want to dump, or NULL for all */ struct stktable *t; /* table being currently dumped (first if NULL) */ diff --git a/src/proxy.c b/src/proxy.c index 555422b38e..fd8161401e 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include @@ -3083,11 +3083,23 @@ static int cli_parse_enable_frontend(char **args, char *payload, struct appctx * 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 * now. */ 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)) 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); if (px) - appctx->ctx.errors.iid = px->uuid; + ctx->iid = px->uuid; 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"); } 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) - appctx->ctx.errors.flag |= 4; // ignore response + ctx->flag |= 4; // ignore response else if (strcmp(args[3], "response") == 0) - appctx->ctx.errors.flag |= 2; // ignore request - appctx->ctx.errors.px = NULL; + ctx->flag |= 2; // ignore request + ctx->px = NULL; 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) { + struct show_errors_ctx *ctx = appctx->svcctx; struct conn_stream *cs = appctx->owner; extern const char *monthname[12]; @@ -3129,7 +3142,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx) chunk_reset(&trash); - if (!appctx->ctx.errors.px) { + if (!ctx->px) { /* the function had not been called yet, let's prepare the * 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) goto cant_send; - appctx->ctx.errors.px = proxies_list; - appctx->ctx.errors.bol = 0; - appctx->ctx.errors.ptr = -1; + ctx->px = proxies_list; + ctx->bol = 0; + ctx->ptr = -1; } /* we have two inner loops here, one for the proxy, the other one for * the buffer. */ - while (appctx->ctx.errors.px) { + while (ctx->px) { 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) { - es = appctx->ctx.errors.px->invalid_req; - if (appctx->ctx.errors.flag & 2) // skip req + if ((ctx->flag & 1) == 0) { + es = ctx->px->invalid_req; + if (ctx->flag & 2) // skip req goto next; } else { - es = appctx->ctx.errors.px->invalid_rep; - if (appctx->ctx.errors.flag & 4) // skip resp + es = ctx->px->invalid_rep; + if (ctx->flag & 4) // skip resp goto next; } if (!es) goto next; - if (appctx->ctx.errors.iid >= 0 && - appctx->ctx.errors.px->uuid != appctx->ctx.errors.iid && - (!es->oe || es->oe->uuid != appctx->ctx.errors.iid)) + if (ctx->iid >= 0 && + ctx->px->uuid != ctx->iid && + (!es->oe || es->oe->uuid != ctx->iid)) goto next; - if (appctx->ctx.errors.ptr < 0) { + if (ctx->ptr < 0) { /* just print headers now */ char pn[INET6_ADDRSTRLEN]; @@ -3197,12 +3210,12 @@ static int cli_io_handler_show_errors(struct appctx *appctx) port = 0; } - switch (appctx->ctx.errors.flag & 1) { + switch (ctx->flag & 1) { case 0: chunk_appendf(&trash, " frontend %s (#%d): invalid request\n" " 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 : "", (es->oe && es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1); break; @@ -3210,7 +3223,7 @@ static int cli_io_handler_show_errors(struct appctx *appctx) chunk_appendf(&trash, " backend %s (#%d): invalid response\n" " frontend %s (#%d)", - appctx->ctx.errors.px->id, appctx->ctx.errors.px->uuid, + ctx->px->id, ctx->px->uuid, es->oe ? es->oe->id : "" , es->oe ? es->oe->uuid : -1); break; } @@ -3234,11 +3247,11 @@ static int cli_io_handler_show_errors(struct appctx *appctx) if (ci_putchk(cs_ic(cs), &trash) == -1) goto cant_send_unlock; - appctx->ctx.errors.ptr = 0; - appctx->ctx.errors.ev_id = es->ev_id; + ctx->ptr = 0; + 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 */ chunk_appendf(&trash, " 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 */ - 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 newline; - newline = appctx->ctx.errors.bol; - newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, appctx->ctx.errors.ptr); - if (newptr == appctx->ctx.errors.ptr) + newline = ctx->bol; + newptr = dump_text_line(&trash, es->buf, global.tune.bufsize, es->buf_len, &newline, ctx->ptr); + if (newptr == ctx->ptr) goto cant_send_unlock; if (ci_putchk(cs_ic(cs), &trash) == -1) goto cant_send_unlock; - appctx->ctx.errors.ptr = newptr; - appctx->ctx.errors.bol = newline; + ctx->ptr = newptr; + ctx->bol = newline; }; next: - HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock); - appctx->ctx.errors.bol = 0; - appctx->ctx.errors.ptr = -1; - appctx->ctx.errors.flag ^= 1; - if (!(appctx->ctx.errors.flag & 1)) - appctx->ctx.errors.px = appctx->ctx.errors.px->next; + HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &ctx->px->lock); + ctx->bol = 0; + ctx->ptr = -1; + ctx->flag ^= 1; + if (!(ctx->flag & 1)) + ctx->px = ctx->px->next; } /* dump complete */ return 1; cant_send_unlock: - HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &appctx->ctx.errors.px->lock); + HA_RWLOCK_RDUNLOCK(PROXY_LOCK, &ctx->px->lock); cant_send: cs_rx_room_blk(cs); return 0;