From 478d5650619dc981586a2bc953d55dde8a8e0c6e Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Thu, 5 Jan 2017 15:05:56 +1100 Subject: [PATCH] ctdb-tests: Do not attempt to unregister the join handler multiple times MSG_ID_SYNC is broadcast to each node when a MSG_ID_JOIN has been received from all nodes. After MSG_ID_SYNC is successfully broadcast, the join handler is unregistered. However, if another MSG_ID_JOIN is received before the join handler is unregistered then MSG_ID_SYNC is re-broadcast. This results in multiple attempts to unregister the join handler. Once all MSG_ID_JOIN messages are received, unregister the join handler to ignore any extra MSG_ID_JOIN messages. Also, make sure that while join handler is being unregistered, MSG_ID_JOIN messages are ignored. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12500 Identified-by: Martin Schwenke Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke Autobuild-User(master): Martin Schwenke Autobuild-Date(master): Fri Jan 6 12:27:23 CET 2017 on sn-devel-144 (cherry picked from commit 4635c22411a7864dd70703f854ec9844816e0294) --- ctdb/tests/src/cluster_wait.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/ctdb/tests/src/cluster_wait.c b/ctdb/tests/src/cluster_wait.c index ddc3e02..1405738 100644 --- a/ctdb/tests/src/cluster_wait.c +++ b/ctdb/tests/src/cluster_wait.c @@ -36,6 +36,7 @@ struct cluster_wait_state { struct ctdb_client_context *client; int num_nodes; bool *ready; + bool join_done; }; static void cluster_wait_join_registered(struct tevent_req *subreq); @@ -44,8 +45,8 @@ static void cluster_wait_join(struct tevent_req *subreq); static void cluster_wait_join_sent(struct tevent_req *subreq); static void cluster_wait_join_handler(uint64_t srvid, TDB_DATA data, void *private_data); -static void cluster_wait_sync_sent(struct tevent_req *subreq); static void cluster_wait_join_unregistered(struct tevent_req *subreq); +static void cluster_wait_sync_sent(struct tevent_req *subreq); static void cluster_wait_sync_handler(uint64_t srvid, TDB_DATA data, void *private_data); static void cluster_wait_sync_unregistered(struct tevent_req *subreq); @@ -67,6 +68,8 @@ struct tevent_req *cluster_wait_send(TALLOC_CTX *mem_ctx, state->client = client; state->num_nodes = num_nodes; + state->join_done = false; + if (ctdb_client_pnn(client) == 0) { state->ready = talloc_zero_array(state, bool, num_nodes); if (tevent_req_nomem(state->ready, req)) { @@ -201,7 +204,6 @@ static void cluster_wait_join_handler(uint64_t srvid, TDB_DATA data, private_data, struct tevent_req); struct cluster_wait_state *state = tevent_req_data( req, struct cluster_wait_state); - struct ctdb_req_message msg; struct tevent_req *subreq; uint32_t pnn; int i; @@ -228,50 +230,56 @@ static void cluster_wait_join_handler(uint64_t srvid, TDB_DATA data, } } - msg.srvid = MSG_ID_SYNC; - msg.data.data = tdb_null; + if (state->join_done) { + return; + } - subreq = ctdb_client_message_send(state, state->ev, state->client, - CTDB_BROADCAST_ALL, &msg); + state->join_done = true; + subreq = ctdb_client_remove_message_handler_send( + state, state->ev, state->client, + MSG_ID_JOIN, req); if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cluster_wait_sync_sent, req); + tevent_req_set_callback(subreq, cluster_wait_join_unregistered, req); } -static void cluster_wait_sync_sent(struct tevent_req *subreq) +static void cluster_wait_join_unregistered(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct cluster_wait_state *state = tevent_req_data( req, struct cluster_wait_state); + struct ctdb_req_message msg; bool status; int ret; - status = ctdb_client_message_recv(subreq, &ret); - TALLOC_FREE(subreq); + status = ctdb_client_remove_message_handler_recv(subreq, &ret); if (! status) { tevent_req_error(req, ret); return; } - subreq = ctdb_client_remove_message_handler_send( - state, state->ev, state->client, - MSG_ID_JOIN, req); + msg.srvid = MSG_ID_SYNC; + msg.data.data = tdb_null; + + subreq = ctdb_client_message_send(state, state->ev, state->client, + CTDB_BROADCAST_ALL, &msg); if (tevent_req_nomem(subreq, req)) { return; } - tevent_req_set_callback(subreq, cluster_wait_join_unregistered, req); + tevent_req_set_callback(subreq, cluster_wait_sync_sent, req); } -static void cluster_wait_join_unregistered(struct tevent_req *subreq) +static void cluster_wait_sync_sent(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); bool status; int ret; - status = ctdb_client_remove_message_handler_recv(subreq, &ret); + status = ctdb_client_message_recv(subreq, &ret); + TALLOC_FREE(subreq); if (! status) { tevent_req_error(req, ret); return; -- 2.9.3