diff --git a/addons/ot/src/cli.c b/addons/ot/src/cli.c index f9feeca15..9132fe907 100644 --- a/addons/ot/src/cli.c +++ b/addons/ot/src/cli.c @@ -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(); } diff --git a/include/haproxy/applet-t.h b/include/haproxy/applet-t.h index f2dfc6dbe..678742ce3 100644 --- a/include/haproxy/applet-t.h +++ b/include/haproxy/applet-t.h @@ -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 */ }; diff --git a/include/haproxy/cli-t.h b/include/haproxy/cli-t.h index 4f5e358de..3a61656ce 100644 --- a/include/haproxy/cli-t.h +++ b/include/haproxy/cli-t.h @@ -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 diff --git a/include/haproxy/cli.h b/include/haproxy/cli.h index f202a4f43..444c09b66 100644 --- a/include/haproxy/cli.h +++ b/include/haproxy/cli.h @@ -23,7 +23,7 @@ #ifndef _HAPROXY_CLI_H #define _HAPROXY_CLI_H -#include +#include #include #include #include @@ -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 */ - diff --git a/src/cli.c b/src/cli.c index 7853a5b1b..1618aaec5 100644 --- a/src/cli.c +++ b/src/cli.c @@ -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); } }