]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cli: keep track of the initcall context since kw registration
authorWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 08:35:16 +0000 (09:35 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 12 Mar 2026 17:06:38 +0000 (18:06 +0100)
Now CLI keywords registered via an initcall will be tracked during
execution, by keeping a link to their initcall location. "show threads"
now shows "exec_ctx: kw registered at @debug.c:3093" which indeed
corresponds to the initcall for the debugging commands.

include/haproxy/cli-t.h
src/cli.c

index 3332b6da68ca2d602527e13520593798cefbd6da..76e935dbbd20f5f187652e44c0a030a115eeafc2 100644 (file)
@@ -23,6 +23,7 @@
 #define _HAPROXY_CLI_T_H
 
 #include <haproxy/applet-t.h>
+#include <haproxy/tinfo-t.h>
 
 /* Access level for a stats socket (appctx->cli_ctx.level) */
 #define ACCESS_LVL_NONE     0x0000
@@ -120,6 +121,8 @@ struct cli_kw {
        void (*io_release)(struct appctx *appctx);
        void *private;
        int level; /* this is the level needed to show the keyword usage and to use it */
+       /* 4-byte hole here */
+       struct thread_exec_ctx exec_ctx;          /* execution context */
 };
 
 struct cli_kw_list {
index f49cca2100302b669318d684dfdb30bfd70b6895..a289f1d425c6889ea60089ee661ad5931c080b8c 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -400,6 +400,18 @@ struct cli_kw* cli_find_kw_exact(char **args)
 
 void cli_register_kw(struct cli_kw_list *kw_list)
 {
+       struct cli_kw *kw;
+
+       for (kw = &kw_list->kw[0]; kw->str_kw[0]; kw++) {
+               /* store declaration file/line if known */
+               if (kw->exec_ctx.type)
+                       continue;
+
+               if (caller_initcall) {
+                       kw->exec_ctx.type = TH_EX_CTX_INITCALL;
+                       kw->exec_ctx.initcall = caller_initcall;
+               }
+       }
        LIST_APPEND(&cli_keywords.list, &kw_list->list);
 }
 
@@ -1211,11 +1223,11 @@ void cli_io_handler(struct appctx *appctx)
 
                        case CLI_ST_CALLBACK: /* use custom pointer */
                                if (appctx->cli_ctx.io_handler)
-                                       if (appctx->cli_ctx.io_handler(appctx)) {
+                                       if (EXEC_CTX_WITH_RET(appctx->cli_ctx.kw->exec_ctx, appctx->cli_ctx.io_handler(appctx))) {
                                                appctx->t->expire = TICK_ETERNITY;
                                                appctx->st0 = CLI_ST_PROMPT;
                                                if (appctx->cli_ctx.io_release) {
-                                                       appctx->cli_ctx.io_release(appctx);
+                                                       EXEC_CTX_NO_RET(appctx->cli_ctx.kw->exec_ctx, appctx->cli_ctx.io_release(appctx));
                                                        appctx->cli_ctx.io_release = NULL;
                                                        appctx->cli_ctx.kw = NULL;
                                                        /* some release handlers might have
@@ -1329,7 +1341,7 @@ static void cli_release_handler(struct appctx *appctx)
        free_trash_chunk(appctx->cli_ctx.cmdline);
 
        if (appctx->cli_ctx.io_release) {
-               appctx->cli_ctx.io_release(appctx);
+               EXEC_CTX_NO_RET(appctx->cli_ctx.kw->exec_ctx, appctx->cli_ctx.io_release(appctx));
                appctx->cli_ctx.io_release = NULL;
                appctx->cli_ctx.kw = NULL;
        }