- removed the non-daemon mode from ctdb, in order to simplify the
authorAndrew Tridgell <tridge@samba.org>
Tue, 17 Apr 2007 04:52:51 +0000 (14:52 +1000)
committerAndrew Tridgell <tridge@samba.org>
Tue, 17 Apr 2007 04:52:51 +0000 (14:52 +1000)
  code. It may be added back later once everything is working nicely,
  or simulated using a in-process pipe instead of a unix domain socket

- rewrote the ctdb_fetch_lock() code to follow the new design

(This used to be ctdb commit 5024dd1f305fe1ecc262db2240c56f773b4f28f0)

14 files changed:
ctdb/common/ctdb.c
ctdb/common/ctdb_call.c
ctdb/common/ctdb_client.c
ctdb/common/ctdb_daemon.c
ctdb/common/ctdb_message.c
ctdb/direct/ctdbd.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/tests/cmdline.c
ctdb/tests/ctdb_fetch.c
ctdb/tests/ctdb_fetch1.c
ctdb/tests/fetch1.sh
ctdb/tests/test.sh
ctdb/tests/test1.sh

index 559b0ed9a637683b0a10aba717d3ed921e2de1be..0ccbecd905ef3530e03bfd109bf81bdcdb883c0a 100644 (file)
@@ -338,11 +338,3 @@ struct ctdb_context *ctdb_init(struct event_context *ev)
        return ctdb;
 }
 
-int ctdb_start(struct ctdb_context *ctdb)
-{
-       if (ctdb->flags&CTDB_FLAG_DAEMON_MODE) {
-               return ctdbd_start(ctdb);
-       }
-
-       return ctdb->methods->start(ctdb);
-}
index 224798aecb19272b63ec4ddc05641370ceb6dc7c..8cc97c8269ec63e67e69b9a4c850083f28cfea1f 100644 (file)
@@ -451,7 +451,8 @@ void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
           and data */
        state->header.dmaster = ctdb->vnn;
 
-       if (ctdb_ltdb_store(ctdb_db, state->call.key, &state->header, data) != 0) {
+       if (!state->fetch_private &&
+           ctdb_ltdb_store(ctdb_db, state->call.key, &state->header, data) != 0) {
                ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
                return;
        }
@@ -591,8 +592,8 @@ struct ctdb_call_state *ctdb_call_local_send(struct ctdb_db_context *ctdb_db,
   This constructs a ctdb_call request and queues it for processing. 
   This call never blocks.
 */
-static struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db, 
-                                                    struct ctdb_call *call)
+struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db, 
+                                             struct ctdb_call *call)
 {
        uint32_t len;
        struct ctdb_call_state *state;
@@ -659,19 +660,6 @@ static struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctd
        return state;
 }
 
-/*
-  make a remote ctdb call - async send
-
-  This constructs a ctdb_call request and queues it for processing. 
-  This call never blocks.
-*/
-struct ctdb_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
-{
-       if (ctdb_db->ctdb->flags & CTDB_FLAG_DAEMON_MODE) {
-               return ctdb_client_call_send(ctdb_db, call);
-       }
-       return ctdb_daemon_call_send(ctdb_db, call);
-}
 
 /*
   make a remote ctdb call - async recv - called in daemon context
@@ -679,7 +667,7 @@ struct ctdb_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db, struct c
   This is called when the program wants to wait for a ctdb_call to complete and get the 
   results. This call will block unless the call has already completed.
 */
-static int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
+int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
 {
        struct ctdb_record_handle *rec;
 
@@ -696,6 +684,7 @@ static int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call
 
        /* ugly hack to manage forced migration */
        if (rec != NULL) {
+               rec->header = state->header;
                rec->data->dptr = talloc_steal(rec, state->call.reply_data.dptr);
                rec->data->dsize = state->call.reply_data.dsize;
                talloc_free(state);
@@ -717,68 +706,3 @@ static int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call
 }
 
 
-/*
-  make a remote ctdb call - async recv. 
-
-  This is called when the program wants to wait for a ctdb_call to complete and get the 
-  results. This call will block unless the call has already completed.
-*/
-int ctdb_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
-{
-       if (state->ctdb_db->ctdb->flags & CTDB_FLAG_DAEMON_MODE) {
-               return ctdb_client_call_recv(state, call);
-       }
-       return ctdb_daemon_call_recv(state, call);
-}
-
-/*
-  full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
-*/
-int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
-{
-       struct ctdb_call_state *state;
-
-       state = ctdb_call_send(ctdb_db, call);
-       return ctdb_call_recv(state, call);
-}
-
-
-
-int ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
-                                          TDB_DATA key, TDB_DATA *data)
-{
-       struct ctdb_call call;
-       struct ctdb_record_handle *rec;
-       struct ctdb_call_state *state;
-       int ret;
-
-       if (ctdb_db->ctdb->flags & CTDB_FLAG_DAEMON_MODE) {
-               return ctdb_client_fetch_lock(ctdb_db, mem_ctx, key, data);
-       }
-
-       ZERO_STRUCT(call);
-       call.call_id = CTDB_FETCH_FUNC;
-       call.key = key;
-       call.flags = CTDB_IMMEDIATE_MIGRATION;
-
-       rec = talloc(mem_ctx, struct ctdb_record_handle);
-       CTDB_NO_MEMORY_NULL(ctdb_db->ctdb, rec);
-
-       rec->ctdb_db = ctdb_db;
-       rec->key = key;
-       rec->key.dptr = talloc_memdup(rec, key.dptr, key.dsize);
-       rec->data = data;
-
-       state = ctdb_call_send(ctdb_db, &call);
-       state->fetch_private = rec;
-
-       ret = ctdb_call_recv(state, &call);
-       if (ret != 0) {
-               talloc_free(rec);
-               return FETCH_LOCK_DMASTERFAILED;
-       }
-
-       return FETCH_LOCK_SUCCESS;
-}
-
-
index 4f63da5e6cdc99c4e764474555adc261cbe58caa..94dec19d56dbac4d6b78d05794363a1eb1884f12 100644 (file)
@@ -48,6 +48,20 @@ static void ctdb_reply_connect_wait(struct ctdb_context *ctdb,
        ctdb->num_connected = r->num_connected;
 }
 
+enum fetch_lock_state { CTDB_FETCH_LOCK_WAIT, CTDB_FETCH_LOCK_DONE, CTDB_FETCH_LOCK_ERROR };
+
+/*
+  state of a in-progress ctdb call
+*/
+struct ctdb_fetch_lock_state {
+       enum fetch_lock_state state;
+       struct ctdb_db_context *ctdb_db;
+       struct ctdb_reply_fetch_lock *r;
+       struct ctdb_ltdb_header header;
+};
+
+
+
 /*
   called in the client when we receive a CTDB_REPLY_FETCH_LOCK from the daemon
 
@@ -56,26 +70,19 @@ static void ctdb_reply_connect_wait(struct ctdb_context *ctdb,
 */
 void ctdb_reply_fetch_lock(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
 {
-       struct ctdb_reply_fetch_lock *c = (struct ctdb_reply_fetch_lock *)hdr;
-       struct ctdb_call_state *state;
+       struct ctdb_reply_fetch_lock *r = (struct ctdb_reply_fetch_lock *)hdr;
+       struct ctdb_fetch_lock_state *state;
 
        state = idr_find(ctdb->idr, hdr->reqid);
        if (state == NULL) return;
 
-       state->call.reply_data.dptr = c->data;
-       state->call.reply_data.dsize = c->datalen;
-       state->call.status = c->state;
-
-       talloc_steal(state, c);
+       state->r = talloc_steal(state, r);
 
        /* get an extra reference here - this prevents the free in ctdb_recv_pkt()
           from freeing the data */
-       (void)talloc_reference(state, c);
+       (void)talloc_reference(state, r);
 
-       state->state = CTDB_CALL_DONE;
-       if (state->async.fn) {
-               state->async.fn(state);
-       }
+       state->state = CTDB_FETCH_LOCK_DONE;
 }
 
 /*
@@ -165,7 +172,7 @@ static int ux_socket_connect(struct ctdb_context *ctdb)
   This is called when the program wants to wait for a ctdb_call to complete and get the 
   results. This call will block unless the call has already completed.
 */
-int ctdb_client_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
+int ctdb_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
 {
        struct ctdb_record_handle *rec;
 
@@ -223,8 +230,8 @@ static int ctdb_client_call_destructor(struct ctdb_call_state *state)
   This constructs a ctdb_call request and queues it for processing. 
   This call never blocks.
 */
-struct ctdb_call_state *ctdb_client_call_send(struct ctdb_db_context *ctdb_db, 
-                                             struct ctdb_call *call)
+struct ctdb_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db, 
+                                      struct ctdb_call *call)
 {
        struct ctdb_call_state *state;
        struct ctdb_context *ctdb = ctdb_db->ctdb;
@@ -316,14 +323,25 @@ struct ctdb_call_state *ctdb_client_call_send(struct ctdb_db_context *ctdb_db,
 }
 
 
+/*
+  full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
+*/
+int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
+{
+       struct ctdb_call_state *state;
+
+       state = ctdb_call_send(ctdb_db, call);
+       return ctdb_call_recv(state, call);
+}
+
 
 /*
   tell the daemon what messaging srvid we will use, and register the message
   handler function in the client
 */
-int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint32_t srvid, 
-                                   ctdb_message_fn_t handler,
-                                   void *private_data)
+int ctdb_set_message_handler(struct ctdb_context *ctdb, uint32_t srvid, 
+                            ctdb_message_fn_t handler,
+                            void *private_data)
                                    
 {
        struct ctdb_req_register c;
@@ -352,26 +370,10 @@ int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint32_t srvid,
 }
 
 
-
-/*
-  setup handler for receipt of ctdb messages from ctdb_send_message()
-*/
-int ctdb_set_message_handler(struct ctdb_context *ctdb, 
-                            uint32_t srvid, 
-                            ctdb_message_fn_t handler,
-                            void *private_data)
-{
-       if (ctdb->flags & CTDB_FLAG_DAEMON_MODE) {
-               return ctdb_client_set_message_handler(ctdb, srvid, handler, private_data);
-       }
-       return ctdb_daemon_set_message_handler(ctdb, srvid, handler, private_data);
-}
-
-
 /*
   send a message - from client context
  */
-int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t vnn,
+int ctdb_send_message(struct ctdb_context *ctdb, uint32_t vnn,
                      uint32_t srvid, TDB_DATA data)
 {
        struct ctdb_req_message *r;
@@ -405,7 +407,7 @@ int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t vnn,
 /*
   wait for all nodes to be connected - from client
  */
-static void ctdb_client_connect_wait(struct ctdb_context *ctdb)
+void ctdb_connect_wait(struct ctdb_context *ctdb)
 {
        struct ctdb_req_connect_wait r;
        int res;
@@ -428,25 +430,11 @@ static void ctdb_client_connect_wait(struct ctdb_context *ctdb)
        ctdb_daemon_connect_wait(ctdb);
 }
 
-/*
-  wait for all nodes to be connected
-*/
-void ctdb_connect_wait(struct ctdb_context *ctdb)
-{
-       if (!(ctdb->flags & CTDB_FLAG_DAEMON_MODE)) {
-               ctdb_daemon_connect_wait(ctdb);
-               return;
-       }
-
-       ctdb_client_connect_wait(ctdb);
-}
-
-
-struct ctdb_call_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb_db, 
-                                                 TALLOC_CTX *mem_ctx, 
-                                                 TDB_DATA key)
+static struct ctdb_fetch_lock_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb_db, 
+                                                                TALLOC_CTX *mem_ctx, 
+                                                                TDB_DATA key)
 {
-       struct ctdb_call_state *state;
+       struct ctdb_fetch_lock_state *state;
        struct ctdb_context *ctdb = ctdb_db->ctdb;
        struct ctdb_req_fetch_lock *req;
        int len, res;
@@ -456,24 +444,23 @@ struct ctdb_call_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb
                ux_socket_connect(ctdb);
        }
 
-       state = talloc_zero(ctdb_db, struct ctdb_call_state);
+       state = talloc_zero(ctdb_db, struct ctdb_fetch_lock_state);
        if (state == NULL) {
                printf("failed to allocate state\n");
                return NULL;
        }
-       state->state   = CTDB_CALL_WAIT;
+       state->state   = CTDB_FETCH_LOCK_WAIT;
        state->ctdb_db = ctdb_db;
        len = offsetof(struct ctdb_req_fetch_lock, key) + key.dsize;
-       state->c = ctdbd_allocate_pkt(ctdb, len);
-       if (state->c == NULL) {
+       req = ctdbd_allocate_pkt(ctdb, len);
+       if (req == NULL) {
                printf("failed to allocate packet\n");
                return NULL;
        }
-       bzero(state->c, len);
-       talloc_set_name_const(state->c, "ctdbd req_fetch_lock packet");
-       talloc_steal(state, state->c);
+       ZERO_STRUCT(*req);
+       talloc_set_name_const(req, "ctdbd req_fetch_lock packet");
+       talloc_steal(state, req);
 
-       req = (struct ctdb_req_fetch_lock *)state->c;
        req->hdr.length      = len;
        req->hdr.ctdb_magic  = CTDB_MAGIC;
        req->hdr.ctdb_version = CTDB_VERSION;
@@ -488,8 +475,6 @@ struct ctdb_call_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb
                return NULL;
        }
 
-       talloc_free(req);
-
        return state;
 }
 
@@ -500,77 +485,119 @@ struct ctdb_call_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb
   This is called when the program wants to wait for a ctdb_fetch_lock to complete and get the 
   results. This call will block unless the call has already completed.
 */
-int ctdb_client_fetch_lock_recv(struct ctdb_call_state *state, TALLOC_CTX *mem_ctx, TDB_DATA key, TDB_DATA *data)
+int ctdb_client_fetch_lock_recv(struct ctdb_fetch_lock_state *state, TALLOC_CTX *mem_ctx, 
+                               TDB_DATA key, struct ctdb_ltdb_header *header, TDB_DATA *data)
 {
-       while (state->state < CTDB_CALL_DONE) {
+       while (state->state < CTDB_FETCH_LOCK_DONE) {
                event_loop_once(state->ctdb_db->ctdb->ev);
        }
-       if (state->state != CTDB_CALL_DONE) {
-               ctdb_set_error(state->node->ctdb, "%s", state->errmsg);
+       if (state->state != CTDB_FETCH_LOCK_DONE) {
                talloc_free(state);
                return -1;
        }
 
-       data->dsize = state->call.reply_data.dsize;
-       data->dptr  = talloc_memdup(mem_ctx, state->call.reply_data.dptr, data->dsize);
+       *header = state->r->header;
+       data->dsize = state->r->datalen;
+       data->dptr  = talloc_memdup(mem_ctx, state->r->data, data->dsize);
+
+       talloc_free(state);
 
        return 0;
 }
 
-int ctdb_client_fetch_lock(struct ctdb_db_context *ctdb_db, 
-                          TALLOC_CTX *mem_ctx, 
-                          TDB_DATA key,
-                          TDB_DATA *data)
+/*
+  cancel a ctdb_fetch_lock operation, releasing the lock
+ */
+static int fetch_lock_destructor(struct ctdb_record_handle *h)
+{
+       ctdb_ltdb_unlock(h->ctdb_db, h->key);
+       return 0;
+}
+
+/*
+  get a lock on a record, and return the records data. Blocks until it gets the lock
+ */
+struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
+                                          TDB_DATA key, TDB_DATA *data)
 {
-       struct ctdb_ltdb_header header;
        int ret;
+       struct ctdb_record_handle *h;
+       struct ctdb_fetch_lock_state *state;
+
+       /*
+         procedure is as follows:
+
+         1) get the chain lock. 
+         2) check if we are dmaster
+         3) if we are the dmaster then return handle 
+         4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
+            reply from ctdbd
+         5) when we get the reply, we are now dmaster, update vnn in header
+         6) return handle
+        */
+
+       h = talloc_zero(mem_ctx, struct ctdb_record_handle);
+       if (h == NULL) {
+               return NULL;
+       }
 
+       h->ctdb_db = ctdb_db;
+       h->key     = key;
+       h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
+       if (h->key.dptr == NULL) {
+               talloc_free(h);
+               return NULL;
+       }
+       h->data    = data;
+
+       /* step 1 - get the chain lock */
        ret = ctdb_ltdb_lock(ctdb_db, key);
        if (ret != 0) {
                printf("failed to lock ltdb record\n");
-               return FETCH_LOCK_LOCKFAILED;
+               talloc_free(h);
+               return NULL;
        }
 
-       ret = ctdb_ltdb_fetch(ctdb_db, key, &header, ctdb_db, data);
+       talloc_set_destructor(h, fetch_lock_destructor);
+
+       ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, ctdb_db, data);
        if (ret != 0) {
-               ctdb_ltdb_unlock(ctdb_db, key);
-               return FETCH_LOCK_FETCHFAILED;
+               talloc_free(h);
+               return NULL;
        }
 
+       /* step 2 - check if we are the dmaster */
+       if (h->header.dmaster == ctdb_db->ctdb->vnn) {
+               return h;
+       }
 
-       if (header.dmaster != ctdb_db->ctdb->vnn) {
-               struct ctdb_call_state *state;
+       /* we're not the dmaster - ask the ctdb daemon to make us dmaster */
+       state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key);
+       ret = ctdb_client_fetch_lock_recv(state, mem_ctx, key, &h->header, data);
+       if (ret != 0) {
+               talloc_free(h);
+               return NULL;
+       }
 
-               state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key);
-               ret = ctdb_client_fetch_lock_recv(state, mem_ctx, key, data);
-               if (ret != 0) {
-                       ctdb_ltdb_unlock(ctdb_db, key);
-                       return FETCH_LOCK_DMASTERFAILED;
-               }
+       /* the record is now local, and locked. update the record on disk
+          to mark us as the dmaster*/
+       h->header.dmaster = ctdb_db->ctdb->vnn;
+       ret = ctdb_ltdb_store(ctdb_db, key, &h->header, *data);
+       if (ret != 0) {
+               printf("bugger - we're in real trouble now! can't update record to mark us as dmasterx\n");
+               talloc_free(h);
+               return NULL;
        }
 
-       return 0;
+       /* give the caller a handle to be used for ctdb_record_store() or a cancel via
+          a talloc_free() */
+       return h;
 }
 
 /*
-   a helper function for the client that will store the new data for the
-   record and release the tdb chainlock
+  store some data to the record that was locked with ctdb_fetch_lock()
 */
-int ctdb_client_store_unlock(struct ctdb_db_context *ctdb_db, TDB_DATA key, TDB_DATA data)
+int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
 {
-       int ret;
-       struct ctdb_ltdb_header header;
-
-       /* should be avoided if possible    hang header off rec ? */
-       ret = ctdb_ltdb_fetch(ctdb_db, key, &header, NULL, NULL);
-       if (ret) {
-               ctdb_set_error(ctdb_db->ctdb, "Fetch of locally held record failed");
-               return ret;
-       }
-
-       ret = ctdb_ltdb_store(ctdb_db, key, &header, data);
-
-       ctdb_ltdb_unlock(ctdb_db, key);
-       
-       return ret;
+       return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
 }
index 1813b8083b5e861914718ec7f1dc6f24640afb35..5a90003bc0ddfe8b5bee34f3ddab68c0a4e70aae 100644 (file)
@@ -110,9 +110,9 @@ static void daemon_request_register_message_handler(struct ctdb_client *client,
 }
 
 
-static struct ctdb_call_state *ctdb_fetch_lock_send(struct ctdb_db_context *ctdb_db, 
-                                                   TALLOC_CTX *mem_ctx, 
-                                                   TDB_DATA key, TDB_DATA *data)
+static struct ctdb_call_state *ctdb_daemon_fetch_lock_send(struct ctdb_db_context *ctdb_db, 
+                                                          TALLOC_CTX *mem_ctx, 
+                                                          TDB_DATA key, TDB_DATA *data)
 {
        struct ctdb_call *call;
        struct ctdb_record_handle *rec;
@@ -134,7 +134,7 @@ static struct ctdb_call_state *ctdb_fetch_lock_send(struct ctdb_db_context *ctdb
        rec->key.dptr = talloc_memdup(rec, key.dptr, key.dsize);
        rec->data = data;
 
-       state = ctdb_call_send(ctdb_db, call);
+       state = ctdb_daemon_call_send(ctdb_db, call);
        state->fetch_private = rec;
 
        return state;
@@ -144,6 +144,7 @@ struct client_fetch_lock_data {
        struct ctdb_client *client;
        uint32_t reqid;
 };
+
 static void daemon_fetch_lock_complete(struct ctdb_call_state *state)
 {
        struct ctdb_reply_fetch_lock *r;
@@ -212,7 +213,7 @@ static void daemon_request_fetch_lock(struct ctdb_client *client,
        data->dptr  = NULL;
        data->dsize = 0;
 
-       state = ctdb_fetch_lock_send(ctdb_db, client, key, data);
+       state = ctdb_daemon_fetch_lock_send(ctdb_db, client, key, data);
        talloc_steal(state, data);
 
        fl_data = talloc(state, struct client_fetch_lock_data);
@@ -316,10 +317,12 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        call.call_data.dptr = c->data + c->keylen;
        call.call_data.dsize = c->calldatalen;
 
-       state = ctdb_call_send(ctdb_db, &call);
+       state = ctdb_daemon_call_send(ctdb_db, &call);
+//     state->async.fn = daemon_call_from_client_callback;
+//     state->async.private_data = state;
 
 /* XXX this must be converted to fully async */
-       res = ctdb_call_recv(state, &call);
+       res = ctdb_daemon_call_recv(state, &call);
        if (res != 0) {
                printf("ctdbd_call_recv() returned error\n");
                exit(1);
@@ -340,7 +343,7 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        r->datalen          = call.reply_data.dsize;
        memcpy(&r->data[0], call.reply_data.dptr, r->datalen);
 
-       res = ctdb_queue_send(client->queue, (uint8_t *)&r, r->hdr.length);
+       res = ctdb_queue_send(client->queue, (uint8_t *)&r->hdr, r->hdr.length);
        if (res != 0) {
                printf("Failed to queue packet from daemon to client\n");
        }
@@ -349,7 +352,7 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
 
 
 /* data contains a packet from the client */
-static void client_incoming_packet(struct ctdb_client *client, void *data, size_t nread)
+static void daemon_incoming_packet(struct ctdb_client *client, void *data, size_t nread)
 {
        struct ctdb_req_header *hdr = data;
 
@@ -391,7 +394,7 @@ done:
 }
 
 
-static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
+static void ctdb_daemon_read_cb(uint8_t *data, size_t cnt, void *args)
 {
        struct ctdb_client *client = talloc_get_type(args, struct ctdb_client);
        struct ctdb_req_header *hdr;
@@ -423,7 +426,7 @@ static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
        }
 
        /* it is the responsibility of the incoming packet function to free 'data' */
-       client_incoming_packet(client, data, cnt);
+       daemon_incoming_packet(client, data, cnt);
 }
 
 static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde, 
@@ -448,7 +451,7 @@ static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde,
        client->fd = fd;
 
        client->queue = ctdb_queue_setup(ctdb, client, fd, CTDB_DS_ALIGNMENT, 
-                                        ctdb_client_read_cb, client);
+                                        ctdb_daemon_read_cb, client);
 
        talloc_set_destructor(client, ctdb_client_destructor);
 }
@@ -517,7 +520,7 @@ static int unlink_destructor(const char *name)
 /*
   start the protocol going
 */
-int ctdbd_start(struct ctdb_context *ctdb)
+int ctdb_start(struct ctdb_context *ctdb)
 {
        pid_t pid;
        static int fd[2];
@@ -560,7 +563,7 @@ int ctdbd_start(struct ctdb_context *ctdb)
        talloc_set_destructor(domain_socket_name, unlink_destructor);   
        
        close(fd[1]);
-       ctdb_clear_flags(ctdb, CTDB_FLAG_DAEMON_MODE);
+
        ctdb->ev = event_context_init(NULL);
        fde = event_add_fd(ctdb->ev, ctdb, fd[0], EVENT_FD_READ, ctdb_read_from_parent, &fd[0]);
        fde = event_add_fd(ctdb->ev, ctdb, ctdb->daemon.sd, EVENT_FD_READ, ctdb_accept_client, ctdb);
@@ -580,10 +583,3 @@ void *ctdbd_allocate_pkt(struct ctdb_context *ctdb, size_t len)
        return talloc_size(ctdb, size);
 }
 
-int ctdb_daemon_set_message_handler(struct ctdb_context *ctdb, uint32_t srvid, 
-                            ctdb_message_fn_t handler,
-                            void *private_data)
-{
-       return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
-}
-
index ad88ec22d265d792de0109b97bb8b8da4d624cc9..88fe04df50345e40d56e67a6226b6bba0de2e902 100644 (file)
@@ -147,18 +147,6 @@ int ctdb_daemon_send_message(struct ctdb_context *ctdb, uint32_t vnn,
        return 0;
 }
 
-/*
-  send a ctdb message
-*/
-int ctdb_send_message(struct ctdb_context *ctdb, uint32_t vnn,
-                     uint32_t srvid, TDB_DATA data)
-{
-       if (ctdb->flags & CTDB_FLAG_DAEMON_MODE) {
-               return ctdb_client_send_message(ctdb, vnn, srvid, data);
-       }
-       return ctdb_daemon_send_message(ctdb, vnn, srvid, data);
-}
-
 
 /*
   when a client goes away, we need to remove its srvid handler from the list
index 700416e5e95fa9f2d73c387aed8da23febe0c261..9e13c4c825a8665a74f727effdf6538ace3442eb 100644 (file)
@@ -105,9 +105,6 @@ int main(int argc, const char *argv[])
        if (self_connect) {
                ctdb_set_flags(ctdb, CTDB_FLAG_SELF_CONNECT);
        }
-       if (daemon_mode) {
-               ctdb_set_flags(ctdb, CTDB_FLAG_DAEMON_MODE);
-       }
 
        ret = ctdb_set_transport(ctdb, transport);
        if (ret == -1) {
index a41e5152075c8bb0d375ccfc43b5dfe876c16cc2..9203cdc07461e1d49e0507f2fb857a1d5e6d781f 100644 (file)
@@ -50,8 +50,6 @@ struct ctdb_call_info {
   ctdb flags
 */
 #define CTDB_FLAG_SELF_CONNECT (1<<0)
-/* fork off a separate ctdb daemon */
-#define CTDB_FLAG_DAEMON_MODE  (1<<1)
 /* for test code only: make ctdb_start() block until all nodes are connected */
 #define CTDB_FLAG_CONNECT_WAIT (1<<2)
 
@@ -177,7 +175,9 @@ int ctdb_send_message(struct ctdb_context *ctdb, uint32_t vnn,
    dmaster for the record to be moved to the local node. 
 
 */
-int ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, TDB_DATA key, TDB_DATA *data);
+struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
+                                          TDB_DATA key, TDB_DATA *data);
+
 
 /*
   do a fetch lock from a client to the local daemon
@@ -192,8 +192,7 @@ int ctdb_client_fetch_lock(struct ctdb_db_context *ctdb_db,
                                                  TDB_DATA key, TDB_DATA *data);
 
 
-int ctdb_client_store_unlock(struct ctdb_db_context *ctdb_db, TDB_DATA key, TDB_DATA data);
-
+int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data);
 
 int ctdb_register_message_handler(struct ctdb_context *ctdb, 
                                  TALLOC_CTX *mem_ctx,
index a11ebf5ad4c09f8346e42a1159f3b385b1f245d1..181200e485c13cc4d0403aa1ed6cf6293efe0bf0 100644 (file)
@@ -199,9 +199,9 @@ struct ctdb_record_handle {
        struct ctdb_db_context *ctdb_db;
        TDB_DATA key;
        TDB_DATA *data;
+       struct ctdb_ltdb_header header;
 };
 
-
 /*
   operation IDs
 */
@@ -314,6 +314,7 @@ struct ctdb_req_fetch_lock {
 struct ctdb_reply_fetch_lock {
        struct ctdb_req_header hdr;
        uint32_t state;
+       struct ctdb_ltdb_header header;
        uint32_t datalen;
        uint8_t data[1]; /* data[] */
 };
@@ -433,4 +434,9 @@ struct lockwait_handle *ctdb_lockwait(struct ctdb_db_context *ctdb_db,
                                      TDB_DATA key,
                                      void (*callback)(void *), void *private_data);
 
+struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db, 
+                                             struct ctdb_call *call);
+
+int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call);
+
 #endif
index 57829b9e9bde687fc35de1ca9f2b14550976988d..94d488a084a40441e0aedafcbb961d5e83e78d4e 100644 (file)
@@ -31,13 +31,11 @@ static struct {
        const char *transport;
        const char *myaddress;
        int self_connect;
-       int daemon_mode;
 } ctdb_cmdline = {
        .nlist = NULL,
        .transport = "tcp",
        .myaddress = NULL,
        .self_connect = 0,
-       .daemon_mode = 0
 };
 
 
@@ -46,7 +44,6 @@ struct poptOption popt_ctdb_cmdline[] = {
        { "listen", 0, POPT_ARG_STRING, &ctdb_cmdline.myaddress, 0, "address to listen on", "address" },
        { "transport", 0, POPT_ARG_STRING, &ctdb_cmdline.transport, 0, "protocol transport", NULL },
        { "self-connect", 0, POPT_ARG_NONE, &ctdb_cmdline.self_connect, 0, "enable self connect", "boolean" },
-       { "daemon", 0, POPT_ARG_NONE, &ctdb_cmdline.daemon_mode, 0, "spawn a ctdb daemon", "boolean" },
        { NULL }
 };
 
@@ -74,9 +71,6 @@ struct ctdb_context *ctdb_cmdline_init(struct event_context *ev)
        if (ctdb_cmdline.self_connect) {
                ctdb_set_flags(ctdb, CTDB_FLAG_SELF_CONNECT);
        }
-       if (ctdb_cmdline.daemon_mode) {
-               ctdb_set_flags(ctdb, CTDB_FLAG_DAEMON_MODE);
-       }
 
        ret = ctdb_set_transport(ctdb, ctdb_cmdline.transport);
        if (ret == -1) {
index ebb7292c73bc2907089341fbce40845e2366788d..a292dfb44322a4ec68c17f029dc55614501bbdcb 100644 (file)
@@ -61,14 +61,15 @@ static void bench_fetch_1node(struct ctdb_context *ctdb)
        struct ctdb_db_context *ctdb_db;
        TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
        int dest, ret;
+       struct ctdb_record_handle *h;
 
        key.dptr = discard_const("testkey");
        key.dsize = strlen((const char *)key.dptr);
 
        ctdb_db = ctdb_db_handle(ctdb, "test.tdb");
 
-       ret = ctdb_client_fetch_lock(ctdb_db, tmp_ctx, key, &data);
-       if (ret != 0) {
+       h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
+       if (h == NULL) {
                printf("Failed to fetch record '%s' on node %d\n", 
                       (const char *)key.dptr, ctdb_get_vnn(ctdb));
                talloc_free(tmp_ctx);
@@ -87,11 +88,13 @@ static void bench_fetch_1node(struct ctdb_context *ctdb)
                                                      msg_count, ctdb_get_vnn(ctdb));
        data.dsize = strlen((const char *)data.dptr)+1;
 
-       ret = ctdb_client_store_unlock(ctdb_db, key, data);
+       ret = ctdb_record_store(h, data);
        if (ret != 0) {
                printf("Failed to store record\n");
        }
 
+       printf("DATA IS NOW:%s\n", (const char *)data.dptr);
+
        talloc_free(tmp_ctx);
 
        /* tell the next node to do the same */
index afae8c53cf12818b472036e594227b712f313c54..635311c9980925ad45f6f179de077c578dc2acb8 100644 (file)
@@ -47,6 +47,7 @@ void test1(struct ctdb_db_context *ctdb_db)
 {
        TDB_DATA key, data, data2, store_data;
        int ret;
+       struct ctdb_record_handle *h;
  
        /* 
           test 1 : write data and read it back.   should all be the same
@@ -54,23 +55,24 @@ void test1(struct ctdb_db_context *ctdb_db)
        printf("Test1: write and verify we can read it back: ");
        key.dptr  = discard_const("Record");
        key.dsize = strlen((const char *)key.dptr)+1;
-       ret = ctdb_client_fetch_lock(ctdb_db, ctdb_db, key, &data);
-       if (ret!=0) {
-               printf("test1: ctdb_client_fetch_lock() failed\n");
+       h = ctdb_fetch_lock(ctdb_db, ctdb_db, key, &data);
+       if (h == NULL) {
+               printf("test1: ctdb_fetch_lock() failed\n");
                exit(1);
        }
 
        store_data.dptr  = discard_const("data to store");
        store_data.dsize = strlen((const char *)store_data.dptr)+1;
-       ret = ctdb_client_store_unlock(ctdb_db, key, store_data);
+       ret = ctdb_record_store(h, store_data);
+       talloc_free(h);
        if (ret!=0) {
-               printf("test1: ctdb_client_store_unlock() failed\n");
+               printf("test1: ctdb_record_store() failed\n");
                exit(1);
        }
 
-       ret = ctdb_client_fetch_lock(ctdb_db, ctdb_db, key, &data2);
-       if (ret!=0) {
-               printf("test1: ctdb_client_fetch_lock() failed\n");
+       h = ctdb_fetch_lock(ctdb_db, ctdb_db, key, &data2);
+       if (h == NULL) {
+               printf("test1: ctdb_fetch_lock() failed\n");
                exit(1);
        }
 
@@ -83,9 +85,10 @@ void test1(struct ctdb_db_context *ctdb_db)
        }
        
        /* just write it back to unlock it */
-       ret = ctdb_client_store_unlock(ctdb_db, key, store_data);
+       ret = ctdb_record_store(h, store_data);
+       talloc_free(h);
        if (ret!=0) {
-               printf("test1: ctdb_client_store_unlock() failed\n");
+               printf("test1: ctdb_record_store() failed\n");
                exit(1);
        }
 }
@@ -94,7 +97,7 @@ void child(int srvid, struct event_context *ev, struct ctdb_context *ctdb, struc
 {
        TDB_DATA data;
        TDB_DATA key, data2;
-       int ret;
+       struct ctdb_record_handle *h;
 
        data.dptr=discard_const("dummy message");
        data.dsize=strlen((const char *)data.dptr)+1;
@@ -110,13 +113,13 @@ void child(int srvid, struct event_context *ev, struct ctdb_context *ctdb, struc
        /* fetch and lock the record */
        key.dptr  = discard_const("Record");
        key.dsize = strlen((const char *)key.dptr)+1;
-       ret = ctdb_client_fetch_lock(ctdb_db, ctdb_db, key, &data2);
-       if (ret!=0) {
-               printf("client: ctdb_client_fetch_lock() failed\n");
+       h = ctdb_fetch_lock(ctdb_db, ctdb_db, key, &data2);
+       if (h == NULL) {
+               printf("client: ctdb_fetch_lock() failed\n");
                exit(1);
        }
        ctdb_send_message(ctdb, ctdb_get_vnn(ctdb), PARENT_SRVID, data);
-
+       talloc_free(h);
 
        while (1) {
                event_loop_once(ev);
index 4331a57d3e02103a9b65e74814629ffd774e4519..3562ca867e614e84e3d0561c180aa2150ad8bc21 100755 (executable)
@@ -3,6 +3,6 @@
 killall -q ctdb_fetch1
 
 echo "Trying node"
-bin/ctdb_fetch1 --nlist tests/1node.txt --listen 127.0.0.1:9001 --daemon $* 
+bin/ctdb_fetch1 --nlist tests/1node.txt --listen 127.0.0.1:9001 $* 
 
 killall -q ctdb_fetch1
index 6197ce9616d414a8a4dc3235330aecfd450332bb..de7d8a342fbd415323f0944d97bd3d659419da3e 100755 (executable)
@@ -19,17 +19,4 @@ sleep 3
 
 killall ctdb_test
 
-echo "Trying 2 nodes in daemon mode"
-bin/ctdb_test --nlist tests/nodes.txt --listen 127.0.0.1:9001 --daemon &
-bin/ctdb_test --nlist tests/nodes.txt --listen 127.0.0.2:9001 --daemon &
 
-sleep 3
-killall ctdb_test
-
-echo "Trying 4 nodes in daemon mode"
-bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.1:9001 --daemon &
-bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.2:9001 --daemon &
-bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.3:9001 --daemon &
-bin/ctdb_test --nlist tests/4nodes.txt --listen 127.0.0.4:9001 --daemon &
-sleep 3
-killall ctdb_test
index 64d5c9fc8735172110a99baca6ea7ba4879dfc69..f13799b45c75f69cfedc1e028136c442cee93fd2 100755 (executable)
@@ -1,8 +1,6 @@
 #!/bin/sh
 
-echo "Testing local send"
-bin/ctdb_test --nlist tests/1node.txt --listen 127.0.0.1:9001 
 echo "Testing daemon mode"
-bin/ctdb_test --nlist tests/1node.txt --listen 127.0.0.1:9001 --daemon
+bin/ctdb_test --nlist tests/1node.txt --listen 127.0.0.1:9001
 echo "Testing self connect"
 bin/ctdb_test --nlist tests/1node.txt --listen 127.0.0.1:9001 --self-connect