The branch, master has been updated via d7f552c ctdb-client: Add missing initialisation of calldata via 6444765 ctdb-client: Keep trying to migrate till record lock is obtained via fbd3fd3 ctdb-client: Remove TALLOC_CTX argument from sync functions via d23c5a6 ctdb-client: Add async version of set/remove message handler functions via 1f2c990 ctdb-client: Add sync API for waiting for recovery via cf3a0aa ctdb-client: Drop TALLOC_CTX argument from ctdb_attach via 69113fa ctdb-client: Add new API for ctdb_client_wait_timeout() via d8c28fc ctdb-client: Do not use sync functions in async computation via e8d4b5d ctdb-client: Do not use sync functions in async computation from b4239ca idmap_script: Parallelize script calls
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit d7f552cbbd173db941ef752fb70609eb1b0d0e70 Author: Amitay Isaacs <ami...@gmail.com> Date: Sat Nov 21 23:36:00 2015 +1100 ctdb-client: Add missing initialisation of calldata Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> Autobuild-User(master): Martin Schwenke <mart...@samba.org> Autobuild-Date(master): Wed Feb 24 11:57:23 CET 2016 on sn-devel-144 commit 64447653ed793f9935b7495a7d0e594983288bdd Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 20 16:22:41 2015 +1100 ctdb-client: Keep trying to migrate till record lock is obtained If a record is not on a local node, then it is migrated from remote node. However, before the client can get a lock on the record, it's possible for the record to get migrated away. In that case, repeat migration. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit fbd3fd343bd0d1c6c03f8ae82ae79ad5580af421 Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 18 15:15:16 2015 +1100 ctdb-client: Remove TALLOC_CTX argument from sync functions There is no allocated memory returned from these functions. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit d23c5a6c2f365b249233f9a1c6d42d220b2b7c67 Author: Amitay Isaacs <ami...@gmail.com> Date: Wed Nov 18 15:11:37 2015 +1100 ctdb-client: Add async version of set/remove message handler functions Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 1f2c9903723e84416e0cd44f1c4da6fcd8464ea6 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 17 16:58:26 2015 +1100 ctdb-client: Add sync API for waiting for recovery Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit cf3a0aa4102fd0e0417edfbb51785e2c04625a76 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 17 16:52:54 2015 +1100 ctdb-client: Drop TALLOC_CTX argument from ctdb_attach The database context returned is allocated off the client and is not allocated from user-supplied TALLOC_CTX. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 69113fa02efb9f21592b25a46d000f7fff173453 Author: Amitay Isaacs <ami...@gmail.com> Date: Tue Nov 10 16:59:21 2015 +1100 ctdb-client: Add new API for ctdb_client_wait_timeout() This is similar to ctdb_client_wait() with additional timeout argument. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit d8c28fc9729b371a9521f959054985749248be26 Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 6 17:08:48 2015 +1100 ctdb-client: Do not use sync functions in async computation This leads to nested event loops. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit e8d4b5d58399aac7ed57a14b92193606499baf7f Author: Amitay Isaacs <ami...@gmail.com> Date: Fri Nov 6 15:44:27 2015 +1100 ctdb-client: Do not use sync functions in async computation This leads to nested event loops. Signed-off-by: Amitay Isaacs <ami...@gmail.com> Reviewed-by: Martin Schwenke <mar...@meltin.net> ----------------------------------------------------------------------- Summary of changes: ctdb/client/client.h | 32 +++++-- ctdb/client/client_connect.c | 131 ++++++++++++++++++++++------ ctdb/client/client_db.c | 108 ++++++++++++++++++----- ctdb/client/client_message.c | 199 ++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 414 insertions(+), 56 deletions(-) Changeset truncated at 500 lines: diff --git a/ctdb/client/client.h b/ctdb/client/client.h index f2f8d6b..df0b9b8 100644 --- a/ctdb/client/client.h +++ b/ctdb/client/client.h @@ -45,12 +45,18 @@ uint32_t ctdb_client_pnn(struct ctdb_client_context *client); void ctdb_client_wait(struct tevent_context *ev, bool *done); +int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, + struct timeval timeout); + struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client); bool ctdb_recovery_wait_recv(struct tevent_req *req, int *perr); +bool ctdb_recovery_wait(struct tevent_context *ev, + struct ctdb_client_context *client); + /* from client/client_call.c */ struct tevent_req *ctdb_client_call_send(TALLOC_CTX *mem_ctx, @@ -76,14 +82,30 @@ int ctdb_client_message(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct ctdb_client_context *client, uint32_t destnode, struct ctdb_req_message *message); -int ctdb_client_set_message_handler(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, +struct tevent_req *ctdb_client_set_message_handler_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ctdb_client_context *client, + uint64_t srvid, + srvid_handler_fn handler, + void *private_data); +bool ctdb_client_set_message_handler_recv(struct tevent_req *req, int *perr); + +struct tevent_req *ctdb_client_remove_message_handler_send( + TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct ctdb_client_context *client, + uint64_t srvid, + void *private_data); +bool ctdb_client_remove_message_handler_recv(struct tevent_req *req, + int *perr); + +int ctdb_client_set_message_handler(struct tevent_context *ev, struct ctdb_client_context *client, uint64_t srvid, srvid_handler_fn handler, void *private_data); -int ctdb_client_remove_message_handler(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, +int ctdb_client_remove_message_handler(struct tevent_context *ev, struct ctdb_client_context *client, uint64_t srvid, void *private_data); @@ -715,7 +737,7 @@ struct tevent_req *ctdb_attach_send(TALLOC_CTX *mem_ctx, bool ctdb_attach_recv(struct tevent_req *req, int *perr, struct ctdb_db_context **out); -int ctdb_attach(TALLOC_CTX *mem_ctx, struct tevent_context *ev, +int ctdb_attach(struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, const char *db_name, uint8_t db_flags, diff --git a/ctdb/client/client_connect.c b/ctdb/client/client_connect.c index d433f7d..f2fe673 100644 --- a/ctdb/client/client_connect.c +++ b/ctdb/client/client_connect.c @@ -239,11 +239,55 @@ void ctdb_client_wait(struct tevent_context *ev, bool *done) } } +static void ctdb_client_wait_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval t, + void *private_data) +{ + bool *timed_out = (bool *)private_data; + + *timed_out = true; +} + +int ctdb_client_wait_timeout(struct tevent_context *ev, bool *done, + struct timeval timeout) +{ + TALLOC_CTX *mem_ctx; + struct tevent_timer *timer; + bool timed_out = false; + + mem_ctx = talloc_new(ev); + if (mem_ctx == NULL) { + return ENOMEM; + } + + timer = tevent_add_timer(ev, mem_ctx, timeout, + ctdb_client_wait_timeout_handler, + &timed_out); + if (timer == NULL) { + talloc_free(mem_ctx); + return ENOMEM; + } + + while (! (*done) && ! timed_out) { + tevent_loop_once(ev); + } + + talloc_free(mem_ctx); + + if (timed_out) { + return ETIME; + } + + return 0; +} + struct ctdb_recovery_wait_state { struct tevent_context *ev; struct ctdb_client_context *client; }; +static void ctdb_recovery_wait_recmode(struct tevent_req *subreq); static void ctdb_recovery_wait_retry(struct tevent_req *subreq); struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx, @@ -252,8 +296,7 @@ struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx, { struct tevent_req *req, *subreq; struct ctdb_recovery_wait_state *state; - int recmode; - int ret; + struct ctdb_req_control request; req = tevent_req_create(mem_ctx, &state, struct ctdb_recovery_wait_state); @@ -264,47 +307,36 @@ struct tevent_req *ctdb_recovery_wait_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->client = client; - ret = ctdb_ctrl_get_recmode(client, ev, client, client->pnn, - tevent_timeval_zero(), &recmode); - if (ret != 0) { - tevent_req_error(req, ret); - return tevent_req_post(req, ev); - } - - if (recmode == CTDB_RECOVERY_NORMAL) { - tevent_req_done(req); - return tevent_req_post(req, ev); - } - - subreq = tevent_wakeup_send(state, ev, - tevent_timeval_current_ofs(1, 0)); + ctdb_req_control_get_recmode(&request); + subreq = ctdb_client_control_send(state, ev, client, client->pnn, + tevent_timeval_zero(), &request); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } - tevent_req_set_callback(subreq, ctdb_recovery_wait_retry, req); + tevent_req_set_callback(subreq, ctdb_recovery_wait_recmode, req); return req; } -static void ctdb_recovery_wait_retry(struct tevent_req *subreq) +static void ctdb_recovery_wait_recmode(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( subreq, struct tevent_req); struct ctdb_recovery_wait_state *state = tevent_req_data( req, struct ctdb_recovery_wait_state); - int ret, recmode; + struct ctdb_reply_control *reply; + int recmode; + int ret; bool status; - status = tevent_wakeup_recv(subreq); + status = ctdb_client_control_recv(subreq, &ret, state, &reply); TALLOC_FREE(subreq); if (! status) { - tevent_req_error(req, ENOMEM); + tevent_req_error(req, ret); return; } - ret = ctdb_ctrl_get_recmode(state, state->ev, state->client, - ctdb_client_pnn(state->client), - tevent_timeval_zero(), &recmode); + ret = ctdb_reply_control_get_recmode(reply, &recmode); if (ret != 0) { tevent_req_error(req, ret); return; @@ -323,6 +355,32 @@ static void ctdb_recovery_wait_retry(struct tevent_req *subreq) tevent_req_set_callback(subreq, ctdb_recovery_wait_retry, req); } +static void ctdb_recovery_wait_retry(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct ctdb_recovery_wait_state *state = tevent_req_data( + req, struct ctdb_recovery_wait_state); + struct ctdb_req_control request; + bool status; + + status = tevent_wakeup_recv(subreq); + TALLOC_FREE(subreq); + if (! status) { + tevent_req_error(req, ENOMEM); + return; + } + + ctdb_req_control_get_recmode(&request); + subreq = ctdb_client_control_send(state, state->ev, state->client, + state->client->pnn, + tevent_timeval_zero(), &request); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, ctdb_recovery_wait_recmode, req); +} + bool ctdb_recovery_wait_recv(struct tevent_req *req, int *perr) { int err; @@ -336,3 +394,28 @@ bool ctdb_recovery_wait_recv(struct tevent_req *req, int *perr) return true; } + +bool ctdb_recovery_wait(struct tevent_context *ev, + struct ctdb_client_context *client) +{ + TALLOC_CTX *mem_ctx; + struct tevent_req *req; + bool status; + + mem_ctx = talloc_new(client); + if (mem_ctx == NULL) { + return false; + } + + req = ctdb_recovery_wait_send(mem_ctx, ev, client); + if (req == NULL) { + return false; + } + + tevent_req_poll(req, ev); + + status = ctdb_recovery_wait_recv(req, NULL); + + talloc_free(mem_ctx); + return status; +} diff --git a/ctdb/client/client_db.c b/ctdb/client/client_db.c index 287efd6..d95e89e 100644 --- a/ctdb/client/client_db.c +++ b/ctdb/client/client_db.c @@ -515,19 +515,26 @@ bool ctdb_attach_recv(struct tevent_req *req, int *perr, return true; } -int ctdb_attach(TALLOC_CTX *mem_ctx, struct tevent_context *ev, +int ctdb_attach(struct tevent_context *ev, struct ctdb_client_context *client, struct timeval timeout, const char *db_name, uint8_t db_flags, struct ctdb_db_context **out) { + TALLOC_CTX *mem_ctx; struct tevent_req *req; bool status; int ret; + mem_ctx = talloc_new(client); + if (mem_ctx == NULL) { + return ENOMEM; + } + req = ctdb_attach_send(mem_ctx, ev, client, timeout, db_name, db_flags); if (req == NULL) { + talloc_free(mem_ctx); return ENOMEM; } @@ -535,6 +542,7 @@ int ctdb_attach(TALLOC_CTX *mem_ctx, struct tevent_context *ev, status = ctdb_attach_recv(req, &ret, out); if (! status) { + talloc_free(mem_ctx); return ret; } @@ -544,6 +552,7 @@ int ctdb_attach(TALLOC_CTX *mem_ctx, struct tevent_context *ev, ctdb_set_call(db, CTDB_FETCH_WITH_HEADER_FUNC, ctdb_fetch_with_header_func); */ + talloc_free(mem_ctx); return 0; } @@ -860,6 +869,7 @@ static void ctdb_fetch_lock_migrate(struct tevent_req *req) request.db_id = state->h->db->db_id; request.callid = CTDB_NULL_FUNC; request.key = state->h->key; + request.calldata = tdb_null; subreq = ctdb_client_call_send(state, state->ev, state->client, &request); @@ -895,7 +905,9 @@ static void ctdb_fetch_lock_migrate_done(struct tevent_req *subreq) ret = ctdb_fetch_lock_check(req); if (ret != 0) { - tevent_req_error(req, ret); + if (ret != EAGAIN) { + tevent_req_error(req, ret); + } return; } @@ -1942,8 +1954,10 @@ struct ctdb_transaction_commit_state { uint64_t seqnum; }; -static void ctdb_transaction_commit_done(struct tevent_req *subreq); +static void ctdb_transaction_commit_seqnum_done(struct tevent_req *subreq); static void ctdb_transaction_commit_try(struct tevent_req *subreq); +static void ctdb_transaction_commit_done(struct tevent_req *subreq); +static void ctdb_transaction_commit_seqnum2_done(struct tevent_req *subreq); struct tevent_req *ctdb_transaction_commit_send( TALLOC_CTX *mem_ctx, @@ -1952,7 +1966,7 @@ struct tevent_req *ctdb_transaction_commit_send( { struct tevent_req *req, *subreq; struct ctdb_transaction_commit_state *state; - int ret; + struct ctdb_req_control request; req = tevent_req_create(mem_ctx, &state, struct ctdb_transaction_commit_state); @@ -1963,27 +1977,53 @@ struct tevent_req *ctdb_transaction_commit_send( state->ev = ev; state->h = h; - ret = ctdb_ctrl_get_db_seqnum(state, ev, h->client, - h->client->pnn, tevent_timeval_zero(), - h->db->db_id, &state->seqnum); + ctdb_req_control_get_db_seqnum(&request, h->db->db_id); + subreq = ctdb_client_control_send(state, ev, h->client, + h->client->pnn, + tevent_timeval_zero(), &request); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, ctdb_transaction_commit_seqnum_done, + req); + + return req; +} + +static void ctdb_transaction_commit_seqnum_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct ctdb_transaction_commit_state *state = tevent_req_data( + req, struct ctdb_transaction_commit_state); + struct ctdb_reply_control *reply; + int ret; + bool status; + + status = ctdb_client_control_recv(subreq, &ret, state, &reply); + TALLOC_FREE(subreq); + if (! status) { + tevent_req_error(req, ret); + return; + } + + ret = ctdb_reply_control_get_db_seqnum(reply, &state->seqnum); if (ret != 0) { tevent_req_error(req, ret); - return tevent_req_post(req, ev); + return; } - ret = ctdb_transaction_store_db_seqnum(h, state->seqnum+1); + ret = ctdb_transaction_store_db_seqnum(state->h, state->seqnum+1); if (ret != 0) { tevent_req_error(req, ret); - return tevent_req_post(req, ev); + return; } - subreq = ctdb_recovery_wait_send(state, ev, h->client); + subreq = ctdb_recovery_wait_send(state, state->ev, state->h->client); if (tevent_req_nomem(subreq, req)) { - return tevent_req_post(req, ev); + return; } tevent_req_set_callback(subreq, ctdb_transaction_commit_try, req); - - return req; } static void ctdb_transaction_commit_try(struct tevent_req *subreq) @@ -2020,7 +2060,7 @@ static void ctdb_transaction_commit_done(struct tevent_req *subreq) struct ctdb_transaction_commit_state *state = tevent_req_data( req, struct ctdb_transaction_commit_state); struct ctdb_reply_control *reply; - uint64_t seqnum; + struct ctdb_req_control request; int ret; bool status; @@ -2044,10 +2084,36 @@ static void ctdb_transaction_commit_done(struct tevent_req *subreq) return; } - ret = ctdb_ctrl_get_db_seqnum(state, state->ev, state->h->client, - state->h->client->pnn, - tevent_timeval_zero(), - state->h->db->db_id, &seqnum); + ctdb_req_control_get_db_seqnum(&request, state->h->db->db_id); + subreq = ctdb_client_control_send(state, state->ev, state->h->client, + state->h->client->pnn, + tevent_timeval_zero(), &request); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, ctdb_transaction_commit_seqnum2_done, + req); +} + +static void ctdb_transaction_commit_seqnum2_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct ctdb_transaction_commit_state *state = tevent_req_data( + req, struct ctdb_transaction_commit_state); + struct ctdb_reply_control *reply; + uint64_t seqnum; + int ret; + bool status; + + status = ctdb_client_control_recv(subreq, &ret, state, &reply); + TALLOC_FREE(subreq); + if (! status) { + tevent_req_error(req, ret); + return; + } + + ret = ctdb_reply_control_get_db_seqnum(reply, &seqnum); if (ret != 0) { tevent_req_error(req, ret); return; @@ -2074,19 +2140,15 @@ static void ctdb_transaction_commit_done(struct tevent_req *subreq) bool ctdb_transaction_commit_recv(struct tevent_req *req, int *perr) { - struct ctdb_transaction_commit_state *state = tevent_req_data( - req, struct ctdb_transaction_commit_state); int err; if (tevent_req_is_unix_error(req, &err)) { if (perr != NULL) { *perr = err; } - TALLOC_FREE(state->h); return false; } - TALLOC_FREE(state->h); return true; } diff --git a/ctdb/client/client_message.c b/ctdb/client/client_message.c index bfa9ba2..d533842 100644 --- a/ctdb/client/client_message.c +++ b/ctdb/client/client_message.c @@ -192,16 +192,201 @@ int ctdb_client_message(TALLOC_CTX *mem_ctx, struct tevent_context *ev, return 0; } -int ctdb_client_set_message_handler(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, +struct ctdb_client_set_message_handler_state { + struct ctdb_client_context *client; + uint64_t srvid; + srvid_handler_fn handler; + void *private_data; +}; + +static void ctdb_client_set_message_handler_done(struct tevent_req *subreq); + +struct tevent_req *ctdb_client_set_message_handler_send( -- Samba Shared Repository