MINOR: cli/pools: add pool name filtering capability to "show pools"

Now it becomes possible to match a pool name's prefix, for example:

  $ socat - /tmp/haproxy.sock <<< "show pools match quic byusage"
  Dumping pools usage. Use SIGQUIT to flush them.
    - Pool quic_conn_r (65560 bytes) : 1337 allocated (87653720 bytes), ...
    - Pool quic_crypto (1048 bytes) : 6685 allocated (7005880 bytes), ...
    - Pool quic_conn (4056 bytes) : 1337 allocated (5422872 bytes), ...
    - Pool quic_rxbuf (262168 bytes) : 8 allocated (2097344 bytes), ...
    - Pool quic_connne (184 bytes) : 9359 allocated (1722056 bytes), ...
    - Pool quic_frame (184 bytes) : 7938 allocated (1460592 bytes), ...
    - Pool quic_tx_pac (152 bytes) : 6454 allocated (981008 bytes), ...
    - Pool quic_tls_ke (56 bytes) : 12033 allocated (673848 bytes), ...
    - Pool quic_rx_pac (408 bytes) : 1596 allocated (651168 bytes), ...
    - Pool quic_tls_se (88 bytes) : 6685 allocated (588280 bytes), ...
    - Pool quic_cstrea (88 bytes) : 4011 allocated (352968 bytes), ...
    - Pool quic_tls_iv (24 bytes) : 12033 allocated (288792 bytes), ...
    - Pool quic_dgram (344 bytes) : 732 allocated (251808 bytes), ...
    - Pool quic_arng (56 bytes) : 4011 allocated (224616 bytes), ...
    - Pool quic_conn_c (152 bytes) : 1337 allocated (203224 bytes), ...
  Total: 15 pools, 109578176 bytes allocated, 109578176 used ...

In this case the reported total only concerns the dumped ones.
This commit is contained in:
Willy Tarreau 2022-11-21 10:02:29 +01:00
parent 2fba08faec
commit 7583c36790
2 changed files with 48 additions and 8 deletions

View File

@ -2897,7 +2897,7 @@ show peers [dict|-] [<peers section>]
table:0x55871b5b46a0 id=stkt update=1 localupdate=0 \ table:0x55871b5b46a0 id=stkt update=1 localupdate=0 \
commitupdate=0 syncing=0 commitupdate=0 syncing=0
show pools [byname|bysize|byusage] [<nb>] show pools [byname|bysize|byusage] [match <pfx>] [<nb>]
Dump the status of internal memory pools. This is useful to track memory Dump the status of internal memory pools. This is useful to track memory
usage when suspecting a memory leak for example. It does exactly the same usage when suspecting a memory leak for example. It does exactly the same
as the SIGQUIT when running in foreground except that it does not flush the as the SIGQUIT when running in foreground except that it does not flush the
@ -2905,7 +2905,29 @@ show pools [byname|bysize|byusage] [<nb>]
sorted by pool name; if "bysize" is specified, it is sorted by item size in sorted by pool name; if "bysize" is specified, it is sorted by item size in
reverse order; if "byusage" is specified, it is sorted by total usage in reverse order; if "byusage" is specified, it is sorted by total usage in
reverse order, and only used entries are shown. It is also possible to limit reverse order, and only used entries are shown. It is also possible to limit
the output to the <nb> first entries (e.g. when sorting by usage). the output to the <nb> first entries (e.g. when sorting by usage). Finally,
if "match" followed by a prefix is specified, then only pools whose name
starts with this prefix will be shown. The reported total only concerns pools
matching the filtering criteria. Example:
$ socat - /tmp/haproxy.sock <<< "show pools match quic byusage"
Dumping pools usage. Use SIGQUIT to flush them.
- Pool quic_conn_r (65560 bytes) : 1337 allocated (87653720 bytes), ...
- Pool quic_crypto (1048 bytes) : 6685 allocated (7005880 bytes), ...
- Pool quic_conn (4056 bytes) : 1337 allocated (5422872 bytes), ...
- Pool quic_rxbuf (262168 bytes) : 8 allocated (2097344 bytes), ...
- Pool quic_connne (184 bytes) : 9359 allocated (1722056 bytes), ...
- Pool quic_frame (184 bytes) : 7938 allocated (1460592 bytes), ...
- Pool quic_tx_pac (152 bytes) : 6454 allocated (981008 bytes), ...
- Pool quic_tls_ke (56 bytes) : 12033 allocated (673848 bytes), ...
- Pool quic_rx_pac (408 bytes) : 1596 allocated (651168 bytes), ...
- Pool quic_tls_se (88 bytes) : 6685 allocated (588280 bytes), ...
- Pool quic_cstrea (88 bytes) : 4011 allocated (352968 bytes), ...
- Pool quic_tls_iv (24 bytes) : 12033 allocated (288792 bytes), ...
- Pool quic_dgram (344 bytes) : 732 allocated (251808 bytes), ...
- Pool quic_arng (56 bytes) : 4011 allocated (224616 bytes), ...
- Pool quic_conn_c (152 bytes) : 1337 allocated (203224 bytes), ...
Total: 15 pools, 109578176 bytes allocated, 109578176 used ...
show profiling [{all | status | tasks | memory}] [byaddr|bytime|aggr|<max_lines>]* show profiling [{all | status | tasks | memory}] [byaddr|bytime|aggr|<max_lines>]*
Dumps the current profiling settings, one per line, as well as the command Dumps the current profiling settings, one per line, as well as the command

View File

@ -95,6 +95,7 @@ struct pool_dump_info {
/* context used by "show pools" */ /* context used by "show pools" */
struct show_pools_ctx { struct show_pools_ctx {
char *prefix; /* if non-null, match this prefix name for the pool */
int by_what; /* 0=no sort, 1=by name, 2=by item size, 3=by total alloc */ int by_what; /* 0=no sort, 1=by name, 2=by item size, 3=by total alloc */
int maxcnt; /* 0=no limit, other=max number of output entries */ int maxcnt; /* 0=no limit, other=max number of output entries */
}; };
@ -929,9 +930,10 @@ static int cmp_dump_pools_usage(const void *a, const void *b)
/* This function dumps memory usage information into the trash buffer. /* This function dumps memory usage information into the trash buffer.
* It may sort by a criterion if <by_what> is non-zero, and limit the * It may sort by a criterion if <by_what> is non-zero, and limit the
* number of output lines if <max> is non-zero. * number of output lines if <max> is non-zero. It may limit only to
* pools whose names start with <pfx> if <pfx> is non-null.
*/ */
void dump_pools_to_trash(int by_what, int max) void dump_pools_to_trash(int by_what, int max, const char *pfx)
{ {
struct pool_dump_info pool_info[POOLS_MAX_DUMPED_ENTRIES]; struct pool_dump_info pool_info[POOLS_MAX_DUMPED_ENTRIES];
struct pool_head *entry; struct pool_head *entry;
@ -950,6 +952,10 @@ void dump_pools_to_trash(int by_what, int max)
if (by_what == 3 && !entry->allocated) if (by_what == 3 && !entry->allocated)
continue; continue;
/* verify the pool name if a prefix is requested */
if (pfx && strncmp(entry->name, pfx, strlen(pfx)) != 0)
continue;
if (!(pool_debugging & POOL_DBG_NO_CACHE)) { if (!(pool_debugging & POOL_DBG_NO_CACHE)) {
for (cached = i = 0; i < global.nbthread; i++) for (cached = i = 0; i < global.nbthread; i++)
cached += entry->cache[i].count; cached += entry->cache[i].count;
@ -1004,7 +1010,7 @@ void dump_pools_to_trash(int by_what, int max)
/* Dump statistics on pools usage. */ /* Dump statistics on pools usage. */
void dump_pools(void) void dump_pools(void)
{ {
dump_pools_to_trash(0, 0); dump_pools_to_trash(0, 0, NULL);
qfprintf(stderr, "%s", trash.area); qfprintf(stderr, "%s", trash.area);
} }
@ -1136,15 +1142,27 @@ static int cli_parse_show_pools(char **args, char *payload, struct appctx *appct
else if (strcmp(args[arg], "byusage") == 0) { else if (strcmp(args[arg], "byusage") == 0) {
ctx->by_what = 3; // sort output by total allocated size ctx->by_what = 3; // sort output by total allocated size
} }
else if (strcmp(args[arg], "match") == 0 && *args[arg+1]) {
ctx->prefix = strdup(args[arg+1]); // only pools starting with this
arg++;
}
else if (isdigit((unsigned char)*args[arg])) { else if (isdigit((unsigned char)*args[arg])) {
ctx->maxcnt = atoi(args[arg]); // number of entries to dump ctx->maxcnt = atoi(args[arg]); // number of entries to dump
} }
else else
return cli_err(appctx, "Expects either 'byname', 'bysize', 'byusage', or a max number of output lines.\n"); return cli_err(appctx, "Expects either 'byname', 'bysize', 'byusage', 'match <pfx>', or a max number of output lines.\n");
} }
return 0; return 0;
} }
/* release the "show pools" context */
static void cli_release_show_pools(struct appctx *appctx)
{
struct show_pools_ctx *ctx = appctx->svcctx;
ha_free(&ctx->prefix);
}
/* This function dumps memory usage information onto the stream connector's /* This function dumps memory usage information onto the stream connector's
* read buffer. It returns 0 as long as it does not complete, non-zero upon * read buffer. It returns 0 as long as it does not complete, non-zero upon
* completion. No state is used. * completion. No state is used.
@ -1153,7 +1171,7 @@ static int cli_io_handler_dump_pools(struct appctx *appctx)
{ {
struct show_pools_ctx *ctx = appctx->svcctx; struct show_pools_ctx *ctx = appctx->svcctx;
dump_pools_to_trash(ctx->by_what, ctx->maxcnt); dump_pools_to_trash(ctx->by_what, ctx->maxcnt, ctx->prefix);
if (applet_putchk(appctx, &trash) == -1) if (applet_putchk(appctx, &trash) == -1)
return 0; return 0;
return 1; return 1;
@ -1200,7 +1218,7 @@ INITCALL0(STG_REGISTER, pools_register_build_options);
/* register cli keywords */ /* register cli keywords */
static struct cli_kw_list cli_kws = {{ },{ static struct cli_kw_list cli_kws = {{ },{
{ { "show", "pools", NULL }, "show pools [byname|bysize|byusage] [nb] : report information about the memory pools usage", cli_parse_show_pools, cli_io_handler_dump_pools }, { { "show", "pools", NULL }, "show pools [by*] [match <pfx>] [nb] : report information about the memory pools usage", cli_parse_show_pools, cli_io_handler_dump_pools, cli_release_show_pools },
{{},} {{},}
}}; }};