create an async version of the control to get the path top a ctdb database file
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Fri, 14 May 2010 05:29:05 +0000 (15:29 +1000)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Fri, 14 May 2010 05:29:05 +0000 (15:29 +1000)
for libctdb

client/ctdb_client.c
include/ctdb.h
libctdb/libctdb.c

index 14005bca36c69f5cf7a5b22055e8e18d0c3fa9da..0840cfd295ffb51ac96f1668353c22e279f79f95 100644 (file)
@@ -791,25 +791,38 @@ int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint3
                   const char **path)
 {
        int ret;
-       int32_t res;
-       TDB_DATA data;
+       const char *tmppath = NULL;
+       ctdb_handle *handle;
 
-       data.dptr = (uint8_t *)&dbid;
-       data.dsize = sizeof(dbid);
+       handle = ctdb_getdbpath_send(ctdb, destnode, dbid, NULL, NULL);
+       if (handle == NULL) {
+               DEBUG(DEBUG_ERR, (__location__  " Failed to send getdbpath control\n"));
+               return -1;
+       }
 
-       ret = ctdb_control(ctdb, destnode, 0, 
-                          CTDB_CONTROL_GETDBPATH, 0, data, 
-                          mem_ctx, &data, &res, &timeout, NULL);
-       if (ret != 0 || res != 0) {
+       if (!timeval_is_zero(&timeout)) {
+               event_add_timed(ctdb->ev, handle, timeout, ctdb_control_timeout_func, handle);
+       }
+
+       ret = ctdb_getdbpath_recv(ctdb, handle, &tmppath);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb control for getdbpath failed\n"));
+               if (tmppath != NULL) {
+                       free(discard_const(tmppath));
+               }
                return -1;
        }
 
-       (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
-       if ((*path) == NULL) {
+       if (tmppath == NULL) {
                return -1;
        }
 
-       talloc_free(data.dptr);
+       *path = talloc_strdup(mem_ctx, (const char *)tmppath);
+       free(discard_const(tmppath));
+
+       if (*path == NULL) {
+               return -1;
+       }
 
        return 0;
 }
index 9f87f0b3aaa46c1d4e001bace1f3b6e12e6cce4e..7b2d5c04e91289be3febd8a61afce710dc590363 100644 (file)
@@ -171,6 +171,25 @@ int ctdb_createdb(struct ctdb_context *ctdb, uint32_t destnode,
 
 
 
+
+/*
+ * functions to find the filename of a database
+ * the caller is responsible to free() path
+ */
+typedef void (*ctdb_getdbpath_cb)(int32_t status, const char *path, void *private_data);
+
+ctdb_handle *
+ctdb_getdbpath_send(struct ctdb_context *ctdb, uint32_t destnode,
+                   uint32_t db_id,
+                   ctdb_getdbpath_cb callback,
+                   void *private_data);
+int ctdb_getdbpath_recv(struct ctdb_context *ctdb,
+                       ctdb_handle *handle, const char **path);
+int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t destnode,
+                  uint32_t db_id,
+                  const char **path);
+
+
 /*
  * cancel a request/call
  */
index 02c596277cdb12a1f947f32c2438f0b7ece1069c..fa76559afe133f8a0f61a2eaf97d911fa5a1d594 100644 (file)
@@ -504,17 +504,19 @@ ctdb_createdb_recv_cb(struct ctdb_client_control_state *state)
        ctdb_createdb_cb callback = (ctdb_createdb_cb)cb_data->callback;
        uint32_t db_id;
 
-       if (state->state == CTDB_CONTROL_DONE && state->status == 0) {
-               if (state->outdata.dsize != sizeof(uint32_t)) {
-                       DEBUG(DEBUG_ERR, (" Wrond size of data returned for CREATEDB control. Got %zd bytes but expected %zd\n", state->outdata.dsize, sizeof(uint32_t)));
-                       
-                       callback(-1, 0, cb_data->private_data);
-                       return;
-               }
+       if (state->state != CTDB_CONTROL_DONE) {
+               DEBUG(DEBUG_ERR,(__location__ " control failed with state:%d and status:%d\n", state->state, state->status));
+               callback(-1, 0, cb_data->private_data);
+               return;
+       }
 
-               db_id = *(uint32_t *)state->outdata.dptr;
+       if (state->outdata.dsize != sizeof(uint32_t)) {
+               DEBUG(DEBUG_ERR, (" Wrong size of data returned for CREATEDB control. Got %zd bytes but expected %zd\n", state->outdata.dsize, sizeof(uint32_t)));
+               callback(-1, 0, cb_data->private_data);
+               return;
        }
 
+       db_id = *(uint32_t *)state->outdata.dptr;
        callback(state->status, db_id, cb_data->private_data);
 }
 
@@ -600,3 +602,98 @@ int ctdb_createdb(struct ctdb_context *ctdb, uint32_t destnode, const char *name
 
 
 
+
+
+/*
+ * find the path to the tdb file of a database
+ */
+static void
+ctdb_getdbpath_recv_cb(struct ctdb_client_control_state *state)
+{
+       struct ctdb_control_cb_data *cb_data = state->async.private_data;
+       ctdb_getdbpath_cb callback = (ctdb_getdbpath_cb)cb_data->callback;
+
+       if (state->state != CTDB_CONTROL_DONE || state->status != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " control failed with state:%d and status:%d\n", state->state, state->status));
+               callback(-1, NULL, cb_data->private_data);
+               return;
+       }
+
+       callback(state->status, strdup((char *)state->outdata.dptr), cb_data->private_data);
+}
+
+ctdb_handle *
+ctdb_getdbpath_send(struct ctdb_context *ctdb, uint32_t destnode,
+                   uint32_t db_id,
+                   ctdb_getdbpath_cb callback,
+                   void *private_data)
+{
+       struct ctdb_client_control_state *state;
+       struct ctdb_control_cb_data *cb_data;
+       TDB_DATA data;
+
+       data.dptr = (uint8_t *)&db_id;
+       data.dsize = sizeof(uint32_t);
+
+       state = ctdb_control_send(ctdb, destnode, 0,
+                       CTDB_CONTROL_GETDBPATH, 0, data,
+                       ctdb, NULL);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to send GETDBPATH control\n"));
+               return NULL;
+       }
+
+       if (callback != NULL) {
+               cb_data = talloc(state, struct ctdb_control_cb_data);
+               cb_data->callback     = callback;
+               cb_data->private_data = private_data;
+
+               state->async.fn           = ctdb_getdbpath_recv_cb;
+               state->async.private_data = cb_data;
+       }
+
+       return (ctdb_handle *)state;
+}
+
+int ctdb_getdbpath_recv(struct ctdb_context *ctdb, ctdb_handle *handle, const char **path)
+{
+       struct ctdb_client_control_state *state = talloc_get_type(handle, struct ctdb_client_control_state);
+       int ret;
+       int32_t res;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+       TDB_DATA data;
+
+       if (path) {
+               *path = NULL;
+       }
+
+       ret = ctdb_control_recv(ctdb, state, tmp_ctx, &data, &res, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_recv failed\n"));
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+
+       if (state->status == 0 && path != NULL) {
+               *path = strdup((char *)data.dptr);
+       }
+
+       talloc_free(tmp_ctx);
+       return state->status;
+}
+
+int ctdb_getdbpath(struct ctdb_context *ctdb, uint32_t destnode,
+                  uint32_t db_id,
+                  const char **path)
+{
+       struct ctdb_client_control_state *state;
+       
+       state = ctdb_getdbpath_send(ctdb, destnode, db_id, NULL, NULL);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_getdbpath_send() failed.\n"));
+               return -1;
+       }
+
+       return ctdb_getdbpath_recv(ctdb, state, path);
+}
+