diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-01-05 15:05:56 +1100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2017-01-11 17:51:17 +0100 |
commit | d60e583fa2ad03fd98618a9a51ed1fbc6325365f (patch) | |
tree | bb5354a62d8ff0578c0f483ce222272c3098e184 | |
parent | ceaafa7cdb187da5db4c6e63af64a17e6c0b88ae (diff) | |
download | samba-d60e583fa2ad03fd98618a9a51ed1fbc6325365f.tar.gz |
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 <martin@meltin.net>
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Fri Jan 6 12:27:23 CET 2017 on sn-devel-144
(cherry picked from commit 4635c22411a7864dd70703f854ec9844816e0294)
-rw-r--r-- | ctdb/tests/src/cluster_wait.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/ctdb/tests/src/cluster_wait.c b/ctdb/tests/src/cluster_wait.c index ddc3e02cbff..1405738ac47 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; |