diff --git a/doc/management.txt b/doc/management.txt index 0f15e06458..dc60d4cdbc 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -2897,7 +2897,7 @@ show peers [dict|-] [] table:0x55871b5b46a0 id=stkt update=1 localupdate=0 \ commitupdate=0 syncing=0 -show pools [byname|bysize|byusage] [] +show pools [byname|bysize|byusage] [match ] [] 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 as the SIGQUIT when running in foreground except that it does not flush the @@ -2905,7 +2905,29 @@ show pools [byname|bysize|byusage] [] 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, and only used entries are shown. It is also possible to limit - the output to the first entries (e.g. when sorting by usage). + the output to the 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|]* Dumps the current profiling settings, one per line, as well as the command diff --git a/src/pool.c b/src/pool.c index abdfafddaf..1c177cafd2 100644 --- a/src/pool.c +++ b/src/pool.c @@ -95,6 +95,7 @@ struct pool_dump_info { /* context used by "show pools" */ 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 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. * It may sort by a criterion if is non-zero, and limit the - * number of output lines if is non-zero. + * number of output lines if is non-zero. It may limit only to + * pools whose names start with if 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_head *entry; @@ -950,6 +952,10 @@ void dump_pools_to_trash(int by_what, int max) if (by_what == 3 && !entry->allocated) 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)) { for (cached = i = 0; i < global.nbthread; i++) cached += entry->cache[i].count; @@ -1004,7 +1010,7 @@ void dump_pools_to_trash(int by_what, int max) /* Dump statistics on pools usage. */ void dump_pools(void) { - dump_pools_to_trash(0, 0); + dump_pools_to_trash(0, 0, NULL); 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) { 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])) { ctx->maxcnt = atoi(args[arg]); // number of entries to dump } 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 ', or a max number of output lines.\n"); } 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 * read buffer. It returns 0 as long as it does not complete, non-zero upon * 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; - 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) return 0; return 1; @@ -1200,7 +1218,7 @@ INITCALL0(STG_REGISTER, pools_register_build_options); /* register cli keywords */ 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 ] [nb] : report information about the memory pools usage", cli_parse_show_pools, cli_io_handler_dump_pools, cli_release_show_pools }, {{},} }};