]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
CLEANUP: cli: move the status print context into its own context
authorWilly Tarreau <w@1wt.eu>
Fri, 6 May 2022 15:16:35 +0000 (17:16 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 6 May 2022 16:33:22 +0000 (18:33 +0200)
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.

addons/ot/src/cli.c
include/haproxy/applet-t.h
include/haproxy/cli-t.h
include/haproxy/cli.h
src/cli.c

index f9feeca159ea2f16f4e3ccbe1a08809075f8cc5a..9132fe907c7bfa7aa45af5bd02ef93d4355f973b 100644 (file)
  */
 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();
 }
index f2dfc6dbef51fc49e9d4722daef1e33c68d07481..678742ce34d5b171f69ace593af3ea4342f23a7b 100644 (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 */
 };
index 4f5e358de6f514f29a641672ba872f4bad432d39..3a61656ce6eb428afa3b81e956683dc2784fabbe 100644 (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
index f202a4f43583b42bb0c7acdddfafbff90addebcc..444c09b66c2f705929cb4ea77d3fe995e8803457 100644 (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 */
-
index 7853a5b1b7c20abe720517a83e566be3510ac491..1618aaec55eb73e4dcf7937ea084ad1f522f3728 100644 (file)
--- 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);
        }
 }