From: William Lallemand Date: Tue, 21 Nov 2017 19:01:26 +0000 (+0100) Subject: MEDIUM: cache: "show cache" on the cli X-Git-Tag: v1.8.0~67 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1f49a366fd94f4c9f68c942c66e27ac4279d6370;p=thirdparty%2Fhaproxy.git MEDIUM: cache: "show cache" on the cli The cli command "show cache" displays the status of the cache, the first displayed line is the shctx informations with how much blocks available blocks it contains (blocks are 1k by default). The next lines are the objects stored in the cache tree, the pointer, the size of the object and how much blocks it uses, a refcount for the number of users of the object, and the remaining expiration time (which can be negative if expired) Example: $ echo "show cache" | socat - /run/haproxy.sock 0x7fa54e9ab03a: foobar (shctx:0x7fa54e9ab000, available blocks:3921) 0x7fa54ed65b8c (size: 43190 (43 blocks), refcount:2, expire: 2) 0x7fa54ecf1b4c (size: 45238 (45 blocks), refcount:0, expire: 2) 0x7fa54ed70cec (size: 61622 (61 blocks), refcount:0, expire: 2) 0x7fa54ecdbcac (size: 42166 (42 blocks), refcount:1, expire: 2) 0x7fa54ec9736c (size: 44214 (44 blocks), refcount:2, expire: 2) 0x7fa54eca28ec (size: 46262 (46 blocks), refcount:2, expire: -2) --- diff --git a/src/cache.c b/src/cache.c index 19a91b4a58..0d726c7291 100644 --- a/src/cache.c +++ b/src/cache.c @@ -13,11 +13,13 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -835,6 +837,74 @@ struct flt_ops cache_ops = { }; +static int cli_parse_show_cache(char **args, struct appctx *appctx, void *private) +{ + if (!cli_has_level(appctx, ACCESS_LVL_ADMIN)) + return 1; + + return 0; +} + +static int cli_io_handler_show_cache(struct appctx *appctx) +{ + struct cache* cache = appctx->ctx.cli.p0; + struct stream_interface *si = appctx->owner; + + chunk_reset(&trash); + + + if (cache == NULL) { + cache = LIST_ELEM((caches).n, typeof(struct cache *), list); + } + + list_for_each_entry_from(cache, &caches, list) { + struct eb32_node *node = NULL; + unsigned int next_key; + struct cache_entry *entry; + + chunk_appendf(&trash, "%p: %s (shctx:%p, available blocks:%d)\n", cache, cache->id, shctx_ptr(cache), shctx_ptr(cache)->nbav); + + next_key = appctx->ctx.cli.i0; + + appctx->ctx.cli.p0 = cache; + + while (1) { + + shctx_lock(shctx_ptr(cache)); + node = eb32_lookup_ge(&cache->entries, next_key); + if (!node) { + shctx_unlock(shctx_ptr(cache)); + break; + } + + entry = container_of(node, struct cache_entry, eb); + chunk_appendf(&trash, "%p (size: %u (%u blocks), refcount:%u, expire: %d)\n", entry, block_ptr(entry)->len, block_ptr(entry)->block_count, block_ptr(entry)->refcount, entry->expire - (int)now.tv_sec); + + next_key = node->key + 1; + appctx->ctx.cli.i0 = next_key; + + shctx_unlock(shctx_ptr(cache)); + + if (ci_putchk(si_ic(si), &trash) == -1) { + si_applet_cant_put(si); + return 0; + } + } + + } + + return 1; + +} + +static struct cli_kw_list cli_kws = {{},{ + { { "show", "cache", NULL }, + "show cache : show cache status", + cli_parse_show_cache, cli_io_handler_show_cache, NULL, + }, +}}; + + static struct action_kw_list http_res_actions = { .kw = { { "cache-store", parse_cache_store }, @@ -861,6 +931,7 @@ static void __cache_init(void) { cfg_register_section("cache", cfg_parse_cache, cfg_post_parse_section_cache); cfg_register_postparser("cache", cfg_cache_postparser); + cli_register_kw(&cli_kws); http_res_keywords_register(&http_res_actions); http_req_keywords_register(&http_req_actions); pool2_cache_st = create_pool("cache_st", sizeof(struct cache_st), MEM_F_SHARED);