CLEANUP: cli: move the status print context into its own context

Now that the CLI's print context is alone in the appctx, it's possible
to refine the appctx's ctx layout so that the cli part matches exactly
a regular svcctx, and as such move the CLI context into an svcctx like
other applets. External code will still build and work because the
struct cli perfectly maps onto the struct cli_print_ctx that's located
into svc.storage. This is of course only to make a smooth transition
during 2.6 and will disappear immediately after.

A tiny change had to be applied to the opentracing addon which performs
direct accesses to the CLI's err pointer in its own print function. The
rest uses the standard cli_print_* which were the only ones that needed
a small change.

The whole "ctx.cli" struct could be tagged as deprecated so that any
possibly existing external code that relies on it will get build
warnings, and the comments in the struct are pretty clear about the
way to fix it, and the lack of future of this old API.
This commit is contained in:
Willy Tarreau 2022-05-06 17:16:35 +02:00
parent aa229ccc4c
commit 1c0715b12a
5 changed files with 53 additions and 27 deletions

View File

@ -38,15 +38,17 @@
*/
static void cmn_cli_set_msg(struct appctx *appctx, char *err, char *msg, int cli_state)
{
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
FLT_OT_FUNC("%p, %p, %p, %d", appctx, err, msg, cli_state);
if ((appctx == NULL) || ((err == NULL) && (msg == NULL)))
FLT_OT_RETURN();
appctx->ctx.cli.err = (err == NULL) ? msg : err;
appctx->st0 = (appctx->ctx.cli.err == NULL) ? CLI_ST_PROMPT : cli_state;
ctx->err = (err == NULL) ? msg : err;
appctx->st0 = (ctx->err == NULL) ? CLI_ST_PROMPT : cli_state;
FLT_OT_DBG(1, "err(%d): \"%s\"", appctx->st0, appctx->ctx.cli.err);
FLT_OT_DBG(1, "err(%d): \"%s\"", appctx->st0, ctx->err);
FLT_OT_RETURN();
}

View File

@ -98,20 +98,29 @@ struct appctx {
void *shadow; /* shadow of svcctx above, do not use! */
char storage[APPLET_MAX_SVCCTX]; /* storage of svcctx above */
} svc; /* generic storage for most commands */
union {
/* The "ctx" part below is kept only to help smooth transition
* of legacy code and will disappear after 2.6. It ensures that
* ctx.cli may safely map to a clean representation of the
* "cli_print_ctx" struct mapped in "svc.storage" above.
*/
struct {
void *shadow; /* shadow of svcctx above for alignment, do not use! */
struct {
/* these 3 first fields must match EXACTLY "struct cli_print_ctx" */
const char *msg; /* pointer to a persistent message to be returned in CLI_ST_PRINT state */
int severity; /* severity of the message to be returned according to (syslog) rfc5424 */
char *err; /* pointer to a 'must free' message to be returned in CLI_ST_PRINT_FREE state */
int severity; /* severity of the message to be returned according to (syslog) rfc5424 */
/* WARNING: the entries below are only kept for compatibility
* with possible external code but will disappear in 2.7, you
* must use the cleaner svcctx now (look at "show fd" for an
* example).
*/
__attribute__((deprecated)) void *p0, *p1, *p2;
__attribute__((deprecated)) size_t o0, o1;
__attribute__((deprecated)) int i0, i1;
} cli; /* context used by the CLI */
void *p0, *p1, *p2;
size_t o0, o1;
int i0, i1;
} cli __attribute__((deprecated)); /* context used by the CLI */
} ctx; /* context-specific variables used by any applet */
}; /* end of anon union */
};

View File

@ -69,6 +69,12 @@ enum {
CLI_SEVERITY_STRING, /* prepend informational cli messages with a severity as string */
};
/* CLI context for printing command responses. */
struct cli_print_ctx {
const char *msg; /* pointer to a persistent message to be returned in CLI_ST_PRINT state */
char *err; /* pointer to a 'must free' message to be returned in CLI_ST_PRINT_FREE state */
int severity; /* severity of the message to be returned according to (syslog) rfc5424 */
};
struct cli_kw {
const char *str_kw[CLI_PREFIX_KW_NB]; /* keywords ended by NULL, limited to CLI_PREFIX_KW_NB

View File

@ -23,7 +23,7 @@
#ifndef _HAPROXY_CLI_H
#define _HAPROXY_CLI_H
#include <haproxy/applet-t.h>
#include <haproxy/applet.h>
#include <haproxy/channel-t.h>
#include <haproxy/cli-t.h>
#include <haproxy/global.h>
@ -57,8 +57,10 @@ int pcli_wait_for_response(struct stream *s, struct channel *rep, int an_bit);
*/
static inline int cli_msg(struct appctx *appctx, int severity, const char *msg)
{
appctx->ctx.cli.severity = severity;
appctx->ctx.cli.msg = msg;
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
ctx->severity = severity;
ctx->msg = msg;
appctx->st0 = CLI_ST_PRINT;
return 1;
}
@ -69,7 +71,9 @@ static inline int cli_msg(struct appctx *appctx, int severity, const char *msg)
*/
static inline int cli_err(struct appctx *appctx, const char *err)
{
appctx->ctx.cli.msg = err;
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
ctx->msg = err;
appctx->st0 = CLI_ST_PRINT_ERR;
return 1;
}
@ -80,8 +84,10 @@ static inline int cli_err(struct appctx *appctx, const char *err)
*/
static inline int cli_dynmsg(struct appctx *appctx, int severity, char *msg)
{
appctx->ctx.cli.severity = severity;
appctx->ctx.cli.err = msg;
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
ctx->severity = severity;
ctx->err = msg;
appctx->st0 = CLI_ST_PRINT_DYN;
return 1;
}
@ -93,11 +99,12 @@ static inline int cli_dynmsg(struct appctx *appctx, int severity, char *msg)
*/
static inline int cli_dynerr(struct appctx *appctx, char *err)
{
appctx->ctx.cli.err = err;
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
ctx->err = err;
appctx->st0 = CLI_ST_PRINT_FREE;
return 1;
}
#endif /* _HAPROXY_CLI_H */

View File

@ -308,10 +308,7 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args)
chunk_dup(&out, tmp);
dynamic_usage_msg = out.area;
appctx->ctx.cli.severity = LOG_INFO;
appctx->ctx.cli.msg = dynamic_usage_msg;
appctx->st0 = CLI_ST_PRINT;
cli_msg(appctx, LOG_INFO, dynamic_usage_msg);
return dynamic_usage_msg;
}
@ -1057,6 +1054,7 @@ static void cli_io_handler(struct appctx *appctx)
req->flags |= CF_READ_DONTWAIT; /* we plan to read small requests */
}
else { /* output functions */
struct cli_print_ctx *ctx;
const char *msg;
int sev;
@ -1067,15 +1065,17 @@ static void cli_io_handler(struct appctx *appctx)
case CLI_ST_PRINT_ERR: /* print const error in msg */
case CLI_ST_PRINT_DYN: /* print dyn message in msg, free */
case CLI_ST_PRINT_FREE: /* print dyn error in err, free */
/* the message is in the svcctx */
ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
if (appctx->st0 == CLI_ST_PRINT || appctx->st0 == CLI_ST_PRINT_ERR) {
sev = appctx->st0 == CLI_ST_PRINT_ERR ?
LOG_ERR : appctx->ctx.cli.severity;
msg = appctx->ctx.cli.msg;
LOG_ERR : ctx->severity;
msg = ctx->msg;
}
else if (appctx->st0 == CLI_ST_PRINT_DYN || appctx->st0 == CLI_ST_PRINT_FREE) {
sev = appctx->st0 == CLI_ST_PRINT_FREE ?
LOG_ERR : appctx->ctx.cli.severity;
msg = appctx->ctx.cli.err;
LOG_ERR : ctx->severity;
msg = ctx->err;
if (!msg) {
sev = LOG_ERR;
msg = "Out of memory.\n";
@ -1089,7 +1089,7 @@ static void cli_io_handler(struct appctx *appctx)
if (cli_output_msg(res, msg, sev, cli_get_severity_output(appctx)) != -1) {
if (appctx->st0 == CLI_ST_PRINT_FREE ||
appctx->st0 == CLI_ST_PRINT_DYN) {
ha_free(&appctx->ctx.cli.err);
ha_free(&ctx->err);
}
appctx->st0 = CLI_ST_PROMPT;
}
@ -1212,7 +1212,9 @@ static void cli_release_handler(struct appctx *appctx)
appctx->io_release = NULL;
}
else if (appctx->st0 == CLI_ST_PRINT_FREE || appctx->st0 == CLI_ST_PRINT_DYN) {
ha_free(&appctx->ctx.cli.err);
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
ha_free(&ctx->err);
}
}