---

When dump_all_vars() was called without arguments or with an emtpy scope,
it failed at config parsing time.

This patch makes an empty or omitted scope argument iterate over all available 
scopes (sess, txn, req, res, proc) in order. This provides the most useful 
behavior for debugging, as users typically want to see all variables regardless 
of scope.

Changes:
  - smp_check_dump_all_vars(): treat empty string and ARGT_STOP as "all scopes" 
by setting scope_id to -1
    - smp_fetch_dump_all_vars(): when scope is -1, loop through all scopes from 
SCOPE_SESS to SCOPE_PROC
---
 src/vars.c | 191 +++++++++++++++++++++++++++++------------------------
 1 file changed, 106 insertions(+), 85 deletions(-)

diff --git a/src/vars.c b/src/vars.c
index b65d19665..74db44b9a 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -381,6 +381,8 @@ static int smp_fetch_dump_all_vars(const struct arg *args, 
struct sample *smp, c
        size_t delim_len = 2;
        int first = 1;
        int i;
+       int start_scope, end_scope;
+       int cur_scope;
 
        /* Get output buffer */
        output = get_trash_chunk();
@@ -388,15 +390,20 @@ static int smp_fetch_dump_all_vars(const struct arg 
*args, struct sample *smp, c
 
        /* Parse arguments */
        if (args[0].type == ARGT_SINT) {
-               desc.scope = args[0].data.sint;
+               if (args[0].data.sint == -1) {
+                       start_scope = SCOPE_SESS;
+                       end_scope = SCOPE_PROC;
+               } else {
+                       start_scope = end_scope = args[0].data.sint;
+               }
        } else {
-               /* Auto-detect scope from context*/
+               /* Auto-detect scope from context */
                if (smp->strm)
-                       desc.scope = SCOPE_TXN;
+                       start_scope = end_scope = SCOPE_TXN;
                else if (smp->sess)
-                       desc.scope = SCOPE_SESS;
+                       start_scope = end_scope = SCOPE_SESS;
                else
-                       desc.scope = SCOPE_PROC;
+                       start_scope = end_scope = SCOPE_PROC;
        }
 
        /* Optional prefix filter */
@@ -414,104 +421,108 @@ static int smp_fetch_dump_all_vars(const struct arg 
*args, struct sample *smp, c
        desc.flags = 0;
        desc.name_hash = 0;
 
-       vars = get_vars(smp->sess, smp->strm, &desc);
-       if (!vars || vars->scope != desc.scope)
-               return 0;
+       for (cur_scope = start_scope; cur_scope <= end_scope; cur_scope++) {
+               desc.scope = cur_scope;
 
-       vars_rdlock(vars);
+               vars = get_vars(smp->sess, smp->strm, &desc);
+               if (!vars || vars->scope != desc.scope)
+                       continue;
 
-       /* Iterate through all variable roots */
-       for (i = 0; i < VAR_NAME_ROOTS; i++) {
-               var = cebu64_item_first(&vars->name_root[i], name_node, 
name_hash, struct var);
+               vars_rdlock(vars);
+       
+               /* Iterate through all variable roots */
+               for (i = 0; i < VAR_NAME_ROOTS; i++) {
+                       var = cebu64_item_first(&vars->name_root[i], name_node, 
name_hash, struct var);
 
-               while (var) {
-                       const char *scope_prefix;
+                       while (var) {
+                               const char *scope_prefix;
 
-                       /* Check prefix filter */
-                       if (prefix) {
-                               if (!var->name || strncmp(var->name, prefix, 
prefix_len) != 0) {
-                                       var = 
cebu64_item_next(&vars->name_root[i], name_node, name_hash, var);
-                                       continue;
+                               /* Check prefix filter */
+                               if (prefix) {
+                                       if (!var->name || strncmp(var->name, 
prefix, prefix_len) != 0) {
+                                               var = 
cebu64_item_next(&vars->name_root[i], name_node, name_hash, var);
+                                               continue;
+                                       }
                                }
-                       }
 
-                       /* Add delimiter */
-                       if (!first) {
-                               if (output->data + delim_len >= output->size)
-                                       goto fail_unlock;
-                               chunk_memcat(output, delim, delim_len);
-                       }
-                       first = 0;
-
-                       /* Add variable name with scope prefix */
-                       scope_prefix = var_scope_names[desc.scope];
-                       if (var->name) {
-                               if (chunk_appendf(output, "%s%s=", 
scope_prefix, var->name) < 0)
-                                       goto fail_unlock;
-                       } else {
-                               if (chunk_appendf(output, "var_%016llx=", 
(unsigned long long)var->name_hash) < 0)
-                                       goto fail_unlock;
-                       }
+                               /* Add delimiter */
+                               if (!first) {
+                                       if (output->data + delim_len >= 
output->size)
+                                               goto fail_unlock;
+                                       chunk_memcat(output, delim, delim_len);
+                               }
+                               first = 0;
 
-                       /* Convert value based on type */
-                       if (var->data.type == SMP_T_STR) {
-                               /* String: quote and escape */
-                               if (chunk_escape_string(output, 
var->data.u.str.area, var->data.u.str.data) < 0)
-                                       goto fail_unlock;
-
-                       } else if (var-> data.type == SMP_T_BIN) {
-                               /* Binary: hex encode */
-                               if (dump_binary(output, var->data.u.str.area, 
var->data.u.str.data) != var->data.u.str.data)
-                                       goto fail_unlock;
-                       } else if (var->data.type == SMP_T_SINT) {
-                               /* Integer */
-                               if (chunk_appendf(output, "%lld", (long 
long)var->data.u.sint) < 0)
-                                       goto fail_unlock;
-
-                       } else if (var->data.type == SMP_T_BOOL) {
-                               /* Boolean */
-                               const char *bool_str = var->data.u.sint ? 
"true" : "false";
-                               if (chunk_appendf(output, "%s", bool_str) < 0)
-                                       goto fail_unlock;
-
-                       } else if (var->data.type == SMP_T_IPV4 || 
var->data.type == SMP_T_IPV6) {
-                               /* Address */
-                               char addr_str[INET6_ADDRSTRLEN];
-                               const char *res;
-
-                               if (var->data.type == SMP_T_IPV4)
-                                       res = inet_ntop(AF_INET, 
&var->data.u.ipv4, addr_str, sizeof(addr_str));
-                               else
-                                       res = inet_ntop(AF_INET6, 
&var->data.u.ipv6, addr_str, sizeof(addr_str));
-
-                               if (!res) {
-                                       if (chunk_appendf(output, "(addr)") < 0)
+                               /* Add variable name with scope prefix */
+                               scope_prefix = var_scope_names[desc.scope];
+                               if (var->name) {
+                                       if (chunk_appendf(output, "%s%s=", 
scope_prefix, var->name) < 0)
                                                goto fail_unlock;
                                } else {
-                                       if (chunk_appendf(output, "%s", 
addr_str) < 0)
+                                       if (chunk_appendf(output, 
"var_%016llx=", (unsigned long long)var->name_hash) < 0)
                                                goto fail_unlock;
                                }
-                       } else if (var->data.type == SMP_T_METH) {
-                               /* HTTP Method */
-                               if (var->data.u.meth.meth == HTTP_METH_OTHER) {
-                                       if (chunk_escape_string(output, 
var->data.u.meth.str.area, var->data.u.meth.str.data) < 0)
+
+                               /* Convert value based on type */
+                               if (var->data.type == SMP_T_STR) {
+                                       /* String: quote and escape */
+                                       if (chunk_escape_string(output, 
var->data.u.str.area, var->data.u.str.data) < 0)
+                                               goto fail_unlock;
+
+                               } else if (var->data.type == SMP_T_BIN) {
+                                       /* Binary: hex encode */
+                                       if (dump_binary(output, 
var->data.u.str.area, var->data.u.str.data) != var->data.u.str.data)
                                                goto fail_unlock;
+                               } else if (var->data.type == SMP_T_SINT) {
+                                       /* Integer */
+                                       if (chunk_appendf(output, "%lld", (long 
long)var->data.u.sint) < 0)
+                                               goto fail_unlock;
+
+                               } else if (var->data.type == SMP_T_BOOL) {
+                                       /* Boolean */
+                                       const char *bool_str = var->data.u.sint 
? "true" : "false";
+                                       if (chunk_appendf(output, "%s", 
bool_str) < 0)
+                                               goto fail_unlock;
+
+                               } else if (var->data.type == SMP_T_IPV4 || 
var->data.type == SMP_T_IPV6) {
+                                       /* Address */
+                                       char addr_str[INET6_ADDRSTRLEN];
+                                       const char *res;
+
+                                       if (var->data.type == SMP_T_IPV4)
+                                               res = inet_ntop(AF_INET, 
&var->data.u.ipv4, addr_str, sizeof(addr_str));
+                                       else
+                                               res = inet_ntop(AF_INET6, 
&var->data.u.ipv6, addr_str, sizeof(addr_str));
+
+                                       if (!res) {
+                                               if (chunk_appendf(output, 
"(addr)") < 0)
+                                                       goto fail_unlock;
+                                       } else {
+                                               if (chunk_appendf(output, "%s", 
addr_str) < 0)
+                                                       goto fail_unlock;
+                                       }
+                               } else if (var->data.type == SMP_T_METH) {
+                                       /* HTTP Method */
+                                       if (var->data.u.meth.meth == 
HTTP_METH_OTHER) {
+                                               if (chunk_escape_string(output, 
var->data.u.meth.str.area, var->data.u.meth.str.data) < 0)
+                                                       goto fail_unlock;
+                                       } else {
+                                               const char *method_str = 
http_known_methods[var->data.u.meth.meth].ptr;
+                                               if (chunk_appendf(output, 
"\"%s\"", method_str) < 0)
+                                                       goto fail_unlock;
+                                       }
                                } else {
-                                       const char *method_str = 
http_known_methods[var->data.u.meth.meth].ptr;
-                                       if (chunk_appendf(output, "\"%s\"", 
method_str) < 0)
+                                       /* Other types: show type number */
+                                       if (chunk_appendf(output, "(type:%d)", 
var->data.type) < 0)
                                                goto fail_unlock;
                                }
-                       } else {
-                               /* Other types: show type number */
-                               if (chunk_appendf(output, "(type:%d)", 
var->data.type) < 0)
-                                       goto fail_unlock;
-                       }
 
-                       var = cebu64_item_next(&vars->name_root[i], name_node, 
name_hash, var);
+                               var = cebu64_item_next(&vars->name_root[i], 
name_node, name_hash, var);
+                       }
                }
-       }
 
-       vars_rdunlock(vars);
+               vars_rdunlock(vars);
+       }
 
        /* Set output sample */
        smp->data.type = SMP_T_STR;
@@ -1105,6 +1116,13 @@ static int smp_check_dump_all_vars(struct arg *args, 
char **err)
                int i;
                char buf[16];
 
+               if (args[0].data.str.data == 0) {
+                       chunk_destroy(&args[0].data.str);
+                       args[0].type = ARGT_SINT;
+                       args[0].data.sint = scope_id;
+                       return 1;
+               }
+
                if (args[0].data.str.data < sizeof(buf) - 1) {
                        snprintf(buf, sizeof(buf), "%s.", scope);
 
@@ -1128,6 +1146,9 @@ static int smp_check_dump_all_vars(struct arg *args, char 
**err)
        else if (args[0].type != ARGT_STOP) {
                memprintf(err, "first argument must be a string (scope) or 
omitted");
                return 0;
+       } else {
+               args[0].type = ARGT_SINT;
+               args[0].data.sint = -1;
        }
 
        /* Second argument (prefix) is optional */
-- 
2.48.1



Reply via email to