From 33fba6f78f2e9e9f1274bde10ac1cd86f2804d64 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 13 Aug 2013 16:44:40 +0200 Subject: [PATCH] BUG/MINOR: cli: "clear table" must not kill entries that don't match condition Mark Brooks reported the following issue : "My table looks like this - 0x24a8294: key=192.168.136.10 use=0 exp=1761492 server_id=3 0x24a8344: key=192.168.136.11 use=0 exp=1761506 server_id=2 0x24a83f4: key=192.168.136.12 use=0 exp=1761520 server_id=3 0x24a84a4: key=192.168.136.13 use=0 exp=1761534 server_id=2 0x24a8554: key=192.168.136.14 use=0 exp=1761548 server_id=3 0x24a8604: key=192.168.136.15 use=0 exp=1761563 server_id=2 0x24a86b4: key=192.168.136.16 use=0 exp=1761580 server_id=3 0x24a8764: key=192.168.136.17 use=0 exp=1761592 server_id=2 0x24a8814: key=192.168.136.18 use=0 exp=1761607 server_id=3 0x24a88c4: key=192.168.136.19 use=0 exp=1761622 server_id=2 0x24a8974: key=192.168.136.20 use=0 exp=1761636 server_id=3 0x24a8a24: key=192.168.136.21 use=0 exp=1761649 server_id=2 im running the command - socat unix-connect:/var/run/haproxy.stat stdio <<< 'clear table VIP_Name-2 data.server_id eq 2' Id assume that the entries with server_id = 2 would be removed but its removing everything each time." The cause of the issue is a missing test for skip_entry when deciding whether to clear the key or not. The test was present when only the last node is to be removed, so removing only the first node from a list of two always did the right thing, explaining why it remained unnoticed in basic unit tests. The bug was introduced by commit 8fa52f4e which attempted to fix a previous issue with this feature where only the last node was removed. This bug is 1.5-specific and does not require any backport. --- src/dumpstats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dumpstats.c b/src/dumpstats.c index 46066b5e2..8707e22ba 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -4170,7 +4170,7 @@ static int stats_table_request(struct stream_interface *si, int action) si->applet.ctx.table.entry = ebmb_entry(eb, struct stksess, key); if (show) stksess_kill_if_expired(&si->applet.ctx.table.proxy->table, old); - else + else if (!skip_entry && !si->applet.ctx.table.entry->ref_cnt) stksess_kill(&si->applet.ctx.table.proxy->table, old); si->applet.ctx.table.entry->ref_cnt++; break;