From b70bae2884a1594aea10001975f286e598f34746 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Mon, 17 May 2010 14:01:49 +1000 Subject: [PATCH] create a ctdb_attachdb_recv() function for libctdb. --- libctdb/libctdb.c | 81 ++++++++++++++++++++++++++++++++++++----------- libctdb/tst.c | 13 ++++---- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/libctdb/libctdb.c b/libctdb/libctdb.c index 3f8ac64f..64b35ba2 100644 --- a/libctdb/libctdb.c +++ b/libctdb/libctdb.c @@ -728,6 +728,7 @@ int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t destnode, */ struct ctdb_attachdb_state { + enum control_state state; uint32_t destnode; struct ctdb_context *ctdb; struct ctdb_db_context *ctdb_db; @@ -735,6 +736,7 @@ struct ctdb_attachdb_state { struct ctdb_client_control_state *gdp_state; bool persistent; uint32_t tdb_flags; + ctdb_attachdb_cb callback; void *private_data; }; @@ -760,8 +762,11 @@ ctdb_attachdb_recv2_cb(struct ctdb_client_control_state *state) if (state->state != CTDB_CONTROL_DONE || state->status != 0) { DEBUG(DEBUG_ERR,(__location__ " getdbpath control failed with state:%d and status:%d\n", state->state, state->status)); - callback(-1, NULL, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_ERROR; + if (callback != NULL) { + callback(-1, NULL, adb_state->private_data); + talloc_free(adb_state); + } return; } ctdb_db->db_path = talloc_strdup(ctdb_db, (char *)state->outdata.dptr); @@ -775,8 +780,11 @@ ctdb_attachdb_recv2_cb(struct ctdb_client_control_state *state) ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0); if (ctdb_db->ltdb == NULL) { DEBUG(DEBUG_ERR, (__location__ " Failed to open tdb '%s'\n", ctdb_db->db_path)); - callback(-1, NULL, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_ERROR; + if (callback != NULL) { + callback(-1, NULL, adb_state->private_data); + talloc_free(adb_state); + } return; } @@ -790,9 +798,12 @@ ctdb_attachdb_recv2_cb(struct ctdb_client_control_state *state) talloc_steal(ctdb, ctdb_db); - callback(0, ctdb_db, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_DONE; + if (callback != NULL) { + callback(0, ctdb_db, adb_state->private_data); + talloc_free(adb_state); + } } static void @@ -805,15 +816,21 @@ ctdb_attachdb_recv1_cb(struct ctdb_client_control_state *state) if (state->state != CTDB_CONTROL_DONE) { DEBUG(DEBUG_ERR,(__location__ " createdb control failed with state:%d and status:%d\n", state->state, state->status)); - callback(-1, NULL, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_ERROR; + if (callback != NULL) { + callback(-1, NULL, adb_state->private_data); + talloc_free(adb_state); + } return; } if (state->outdata.dsize != sizeof(uint32_t)) { DEBUG(DEBUG_ERR, (__location__ " Wrong size of data returned for CREATEDB control. Got %zd bytes but expected %zd\n", state->outdata.dsize, sizeof(uint32_t))); - callback(-1, NULL, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_ERROR; + if (callback != NULL) { + callback(-1, NULL, adb_state->private_data); + talloc_free(adb_state); + } return; } @@ -822,8 +839,11 @@ ctdb_attachdb_recv1_cb(struct ctdb_client_control_state *state) adb_state->gdp_state = ctdb_getdbpath_send(adb_state->ctdb, adb_state->destnode, adb_state->ctdb_db->db_id, NULL, NULL); if (state == NULL) { DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_send() failed.\n")); - callback(-1, NULL, adb_state->private_data); - talloc_free(adb_state); + adb_state->state = CTDB_CONTROL_ERROR; + if (callback != NULL) { + callback(-1, NULL, adb_state->private_data); + talloc_free(adb_state); + } return; } talloc_steal(adb_state, adb_state->gdp_state); @@ -841,10 +861,10 @@ ctdb_attachdb_send(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_attachdb_state *state; struct ctdb_db_context *ctdb_db; - ctdb_db = ctdb_db_handle(ctdb, name); if (ctdb_db != NULL) { - return ctdb_db; + DEBUG(DEBUG_ERR, (__location__ " There is already a database with this name. Can not attach twice.\n")); + return NULL; } state = talloc_zero(ctdb, struct ctdb_attachdb_state); @@ -860,6 +880,7 @@ ctdb_attachdb_send(struct ctdb_context *ctdb, uint32_t destnode, return NULL; } + state->state = CTDB_CONTROL_WAIT; state->ctdb = ctdb; state->ctdb_db = ctdb_db; state->destnode = destnode; @@ -884,22 +905,44 @@ ctdb_attachdb_send(struct ctdb_context *ctdb, uint32_t destnode, } talloc_steal(state, state->cdb_state); + state->cdb_state->async.fn = ctdb_attachdb_recv1_cb; + state->cdb_state->async.private_data = state; + if (callback != NULL) { state->callback = callback; state->private_data = private_data; - - state->cdb_state->async.fn = ctdb_attachdb_recv1_cb; - state->cdb_state->async.private_data = state; } return (ctdb_handle *)state; } +int ctdb_attachdb_recv(struct ctdb_context *ctdb, + ctdb_handle *handle, struct ctdb_db_context **ctdb_db) +{ + struct ctdb_attachdb_state *state = talloc_get_type(handle, struct ctdb_attachdb_state); + + while (state->state == CTDB_CONTROL_WAIT) { + event_loop_once(ctdb->ev); + } + + if (state->state != CTDB_CONTROL_DONE) { + if (ctdb_db != NULL) { + *ctdb_db = NULL; + } + return -1; + } + + if (ctdb_db != NULL) { + *ctdb_db = state->ctdb_db; + } + + talloc_free(state); + return 0; +} + -int ctdb_attachdb_recv(struct ctdb_context *ctdb, - ctdb_handle *handle, struct ctdb_db_context **); int ctdb_attachdb(struct ctdb_context *ctdb, uint32_t destnode, const char *name, int persistent, uint32_t tdb_flags, struct ctdb_db_context **); diff --git a/libctdb/tst.c b/libctdb/tst.c index 08d515eb..dc030fe6 100644 --- a/libctdb/tst.c +++ b/libctdb/tst.c @@ -32,6 +32,7 @@ void adb_cb(int32_t status, struct ctdb_db_context *ctdb_db, void *private_data) int main(int argc, char *argv[]) { struct ctdb_context *ctdb_context; + struct ctdb_db_context *ctdb_db_context; ctdb_handle *handle; struct pollfd pfd; int ret; @@ -59,21 +60,21 @@ int main(int argc, char *argv[]) exit(10); } - handle = ctdb_getpnn_send(ctdb_context, CTDB_CURRENT_NODE, pnn_cb, NULL); + handle = ctdb_attachdb_send(ctdb_context, CTDB_CURRENT_NODE, "test_test.tdb", 0, 0, adb_cb, NULL); if (handle == NULL) { - printf("Failed to send get_pnn control\n"); + printf("Failed to send attachdb control\n"); exit(10); } - handle = ctdb_getrecmaster_send(ctdb_context, CTDB_CURRENT_NODE, rm_cb, NULL); + handle = ctdb_getpnn_send(ctdb_context, CTDB_CURRENT_NODE, pnn_cb, NULL); if (handle == NULL) { - printf("Failed to send get_recmaster control\n"); + printf("Failed to send get_pnn control\n"); exit(10); } - handle = ctdb_attachdb_send(ctdb_context, CTDB_CURRENT_NODE, "test_test.tdb", 0,0, adb_cb, NULL); + handle = ctdb_getrecmaster_send(ctdb_context, CTDB_CURRENT_NODE, rm_cb, NULL); if (handle == NULL) { - printf("Failed to send attachdb control\n"); + printf("Failed to send get_recmaster control\n"); exit(10); } -- 2.34.1