create a ctdb_attachdb_recv() function for libctdb.
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Mon, 17 May 2010 04:01:49 +0000 (14:01 +1000)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Mon, 17 May 2010 04:01:49 +0000 (14:01 +1000)
libctdb/libctdb.c
libctdb/tst.c

index 3f8ac64f514490123ced448fb5d8eb33b308f5ac..64b35ba2e07ff3c377b9e27286d918d5617b6531 100644 (file)
@@ -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 **);
index 08d515eb3aa6caddcebff203c156f39cc1169742..dc030fe683e7a6015a976a016dc7a8ac89bf40f1 100644 (file)
@@ -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);
        }