From 952a50485f68b3cffdf57da84aa9bb9fde630b7e Mon Sep 17 00:00:00 2001 From: Martin Schwenke Date: Fri, 24 Jul 2015 15:32:42 +1000 Subject: [PATCH] ctdb-daemon: Check if updates are in flight when releasing all IPs Some code involved in releasing IPs is not re-entrant. Memory corruption can occur if, for example, overlapping attempts are made to ban a node. We haven't been able to recreate the corruption but this should protect against it. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- ctdb/server/ctdb_takeover.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index d5d2b39e4d8..efc80b1ab8c 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -3128,9 +3128,6 @@ void ctdb_takeover_client_destructor_hook(struct ctdb_client *client) } -/* - release all IPs on shutdown - */ void ctdb_release_all_ips(struct ctdb_context *ctdb) { struct ctdb_vnn *vnn; @@ -3149,6 +3146,20 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb) continue; } + /* Don't allow multiple releases at once. Some code, + * particularly ctdb_tickle_sentenced_connections() is + * not re-entrant */ + if (vnn->update_in_flight) { + DEBUG(DEBUG_WARNING, + (__location__ + " Not releasing IP %s/%u on interface %s, an update is already in progess\n", + ctdb_addr_to_str(&vnn->public_address), + vnn->public_netmask_bits, + ctdb_vnn_iface_string(vnn))); + continue; + } + vnn->update_in_flight = true; + DEBUG(DEBUG_INFO,("Release of IP %s/%u on interface %s node:-1\n", ctdb_addr_to_str(&vnn->public_address), vnn->public_netmask_bits, @@ -3160,6 +3171,7 @@ void ctdb_release_all_ips(struct ctdb_context *ctdb) vnn->public_netmask_bits); release_kill_clients(ctdb, &vnn->public_address); ctdb_vnn_unassign_iface(ctdb, vnn); + vnn->update_in_flight = false; count++; } -- 2.11.4.GIT