- make he packet allocation routines take a mem_ctx, which allows
authorAndrew Tridgell <tridge@samba.org>
Thu, 19 Apr 2007 00:37:44 +0000 (10:37 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 19 Apr 2007 00:37:44 +0000 (10:37 +1000)
  us to put memory directly in the right context, avoiding quite a few
  talloc_steal calls, and simplifying the code

- make the fetch lock code in the daemon fully async

(This used to be ctdb commit d98b4b4fcadad614861c0d44a3854d97b01d0f74)

ctdb/common/ctdb_call.c
ctdb/common/ctdb_client.c
ctdb/common/ctdb_daemon.c
ctdb/ib/ibw_ctdb_init.c
ctdb/include/ctdb_private.h
ctdb/tcp/tcp_init.c

index e719318e60849f45249858a8547da8a601f40063..f002a9c7628d508ab98112a71eb836fd5102f02a 100644 (file)
@@ -141,7 +141,7 @@ static void ctdb_send_error(struct ctdb_context *ctdb,
 
        msglen = strlen(msg)+1;
        len = offsetof(struct ctdb_reply_error, msg);
-       r = ctdb->methods->allocate_pkt(ctdb, len + msglen);
+       r = ctdb->methods->allocate_pkt(msg, len + msglen);
        CTDB_NO_MEMORY_FATAL(ctdb, r);
        talloc_set_name_const(r, "send_error packet");
 
@@ -156,11 +156,9 @@ static void ctdb_send_error(struct ctdb_context *ctdb,
        r->msglen        = msglen;
        memcpy(&r->msg[0], msg, msglen);
 
-       talloc_free(msg);
-
        ctdb_queue_packet(ctdb, &r->hdr);
 
-       talloc_free(r);
+       talloc_free(msg);
 }
 
 
@@ -297,15 +295,14 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
                }
        }
 
-       /* send the CTDB_REPLY_DMASTER */
-       len = offsetof(struct ctdb_reply_dmaster, data) + data.dsize;
-       r = ctdb->methods->allocate_pkt(ctdb, len);
-       CTDB_NO_MEMORY_FATAL(ctdb, r);
-
        /* put the packet on a temporary context, allowing us to safely free
           it below even if ctdb_reply_dmaster() has freed it already */
        tmp_ctx = talloc_new(ctdb);
-       talloc_steal(tmp_ctx, r);
+
+       /* send the CTDB_REPLY_DMASTER */
+       len = offsetof(struct ctdb_reply_dmaster, data) + data.dsize;
+       r = ctdb->methods->allocate_pkt(tmp_ctx, len);
+       CTDB_NO_MEMORY_FATAL(ctdb, r);
 
        talloc_set_name_const(r, "reply_dmaster packet");
        r->hdr.length    = len;
@@ -653,10 +650,9 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(struct ctdb_db_context *ctd
        CTDB_NO_MEMORY_NULL(ctdb, state);
 
        len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
-       state->c = ctdb->methods->allocate_pkt(ctdb, len);
+       state->c = ctdb->methods->allocate_pkt(state, len);
        CTDB_NO_MEMORY_NULL(ctdb, state->c);
        talloc_set_name_const(state->c, "req_call packet");
-       talloc_steal(state, state->c);
 
        state->c->hdr.length    = len;
        state->c->hdr.ctdb_magic = CTDB_MAGIC;
index 1a846175ddb439f9925aa3ba1763ba9ad8553f32..dbf620372c75076da0f1616191621a72648fd53b 100644 (file)
@@ -295,13 +295,12 @@ struct ctdb_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db,
        talloc_steal(state, data.dptr);
 
        len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
-       state->c = ctdbd_allocate_pkt(ctdb, len);
+       state->c = ctdbd_allocate_pkt(state, len);
        if (state->c == NULL) {
                DEBUG(0, (__location__ " failed to allocate packet\n"));
                return NULL;
        }
        talloc_set_name_const(state->c, "ctdbd req_call packet");
-       talloc_steal(state, state->c);
 
        state->c->hdr.length    = len;
        state->c->hdr.ctdb_magic = CTDB_MAGIC;
@@ -489,14 +488,13 @@ static struct ctdb_fetch_lock_state *ctdb_client_fetch_lock_send(struct ctdb_db_
        state->state   = CTDB_FETCH_LOCK_WAIT;
        state->ctdb_db = ctdb_db;
        len = offsetof(struct ctdb_req_fetch_lock, key) + key.dsize;
-       state->req = req = ctdbd_allocate_pkt(ctdb, len);
+       state->req = req = ctdbd_allocate_pkt(state, len);
        if (req == NULL) {
                DEBUG(0, (__location__ " failed to allocate packet\n"));
                return NULL;
        }
        ZERO_STRUCT(*req);
        talloc_set_name_const(req, "ctdbd req_fetch_lock packet");
-       talloc_steal(state, req);
 
        req->hdr.length      = len;
        req->hdr.ctdb_magic  = CTDB_MAGIC;
index a9398029472d2306c9300075c5f1a1e77f7a07df..6ef988906661e8af1b851bfb1249ca7156909c79 100644 (file)
@@ -86,7 +86,6 @@ static void daemon_message_handler(struct ctdb_context *ctdb, uint32_t srvid,
        len = offsetof(struct ctdb_req_message, data) + data.dsize;
        r = ctdbd_allocate_pkt(ctdb, len);
 
-/*XXX cant use this since it returns an int    CTDB_NO_MEMORY(ctdb, r);*/
        talloc_set_name_const(r, "req_message packet");
 
        memset(r, 0, offsetof(struct ctdb_req_message, data));
@@ -102,7 +101,6 @@ static void daemon_message_handler(struct ctdb_context *ctdb, uint32_t srvid,
        ctdb_queue_send(client->queue, (uint8_t *)&r->hdr, len);
 
        talloc_free(r);
-       return;
 }
                                           
 
@@ -371,47 +369,36 @@ static void daemon_request_message_from_client(struct ctdb_client *client,
        }
 }
 
-/*
-  this is called when the ctdb daemon received a ctdb request call
-  from a local client over the unix domain socket
- */
-static void daemon_request_call_from_client(struct ctdb_client *client, 
-                                           struct ctdb_req_call *c)
+
+struct daemon_call_state {
+       struct ctdb_client *client;
+       uint32_t reqid;
+       struct ctdb_call *call;
+};
+
+/* 
+   complete a call from a client 
+*/
+static void daemon_call_from_client_callback(struct ctdb_call_state *state)
 {
-       struct ctdb_call_state *state;
-       struct ctdb_db_context *ctdb_db;
-       struct ctdb_call call;
+       struct daemon_call_state *dstate = talloc_get_type(state->async.private_data, 
+                                                          struct daemon_call_state);
        struct ctdb_reply_call *r;
        int res;
        uint32_t length;
+       struct ctdb_client *client = dstate->client;
 
-       ctdb_db = find_ctdb_db(client->ctdb, c->db_id);
-       if (!ctdb_db) {
-               DEBUG(0, (__location__ " Unknown database in request. db_id==0x%08x",
-                         c->db_id));
-               return;
-       }
-
-       ZERO_STRUCT(call);
-       call.call_id = c->callid;
-       call.key.dptr = c->data;
-       call.key.dsize = c->keylen;
-       call.call_data.dptr = c->data + c->keylen;
-       call.call_data.dsize = c->calldatalen;
-
-       state = ctdb_daemon_call_send(ctdb_db, &call);
-//     state->async.fn = daemon_call_from_client_callback;
-//     state->async.private_data = state;
+       talloc_steal(client, dstate);
+       talloc_steal(dstate, dstate->call);
 
-/* XXX this must be converted to fully async */
-       res = ctdb_daemon_call_recv(state, &call);
+       res = ctdb_daemon_call_recv(state, dstate->call);
        if (res != 0) {
                DEBUG(0, (__location__ " ctdbd_call_recv() returned error\n"));
-               exit(1);
+               return;
        }
 
-       length = offsetof(struct ctdb_reply_call, data) + call.reply_data.dsize;
-       r = ctdbd_allocate_pkt(client->ctdb, length);
+       length = offsetof(struct ctdb_reply_call, data) + dstate->call->reply_data.dsize;
+       r = ctdbd_allocate_pkt(dstate, length);
        if (r == NULL) {
                DEBUG(0, (__location__ " Failed to allocate reply_call in ctdb daemon\n"));
                return;
@@ -421,17 +408,67 @@ static void daemon_request_call_from_client(struct ctdb_client *client,
        r->hdr.ctdb_magic   = CTDB_MAGIC;
        r->hdr.ctdb_version = CTDB_VERSION;
        r->hdr.operation    = CTDB_REPLY_CALL;
-       r->hdr.reqid        = c->hdr.reqid;
-       r->datalen          = call.reply_data.dsize;
-       memcpy(&r->data[0], call.reply_data.dptr, r->datalen);
+       r->hdr.reqid        = dstate->reqid;
+       r->datalen          = dstate->call->reply_data.dsize;
+       memcpy(&r->data[0], dstate->call->reply_data.dptr, r->datalen);
 
        res = ctdb_queue_send(client->queue, (uint8_t *)&r->hdr, r->hdr.length);
        if (res != 0) {
                DEBUG(0, (__location__ "Failed to queue packet from daemon to client\n"));
        }
-       talloc_free(r);
+       talloc_free(dstate);
 }
 
+/*
+  this is called when the ctdb daemon received a ctdb request call
+  from a local client over the unix domain socket
+ */
+static void daemon_request_call_from_client(struct ctdb_client *client, 
+                                           struct ctdb_req_call *c)
+{
+       struct ctdb_call_state *state;
+       struct ctdb_db_context *ctdb_db;
+       struct daemon_call_state *dstate;
+       struct ctdb_call *call;
+
+       ctdb_db = find_ctdb_db(client->ctdb, c->db_id);
+       if (!ctdb_db) {
+               DEBUG(0, (__location__ " Unknown database in request. db_id==0x%08x",
+                         c->db_id));
+               return;
+       }
+
+       dstate = talloc(client, struct daemon_call_state);
+       if (dstate == NULL) {
+               DEBUG(0,(__location__ " Unable to allocate dstate\n"));
+               return;
+       }
+       dstate->client = client;
+       dstate->reqid  = c->hdr.reqid;
+
+       call = dstate->call = talloc_zero(dstate, struct ctdb_call);
+       if (call == NULL) {
+               DEBUG(0,(__location__ " Unable to allocate call\n"));
+               return;
+       }
+
+       call->call_id = c->callid;
+       call->key.dptr = c->data;
+       call->key.dsize = c->keylen;
+       call->call_data.dptr = c->data + c->keylen;
+       call->call_data.dsize = c->calldatalen;
+
+       state = ctdb_daemon_call_send(ctdb_db, call);
+       if (state == NULL) {
+               DEBUG(0,(__location__ " Unable to setup call send\n"));
+               return;
+       }
+       talloc_steal(state, dstate);
+       talloc_steal(client, state);
+
+       state->async.fn = daemon_call_from_client_callback;
+       state->async.private_data = dstate;
+}
 
 /* data contains a packet from the client */
 static void daemon_incoming_packet(struct ctdb_client *client, void *data, size_t nread)
@@ -674,12 +711,12 @@ int ctdb_start(struct ctdb_context *ctdb)
 /*
   allocate a packet for use in client<->daemon communication
  */
-void *ctdbd_allocate_pkt(struct ctdb_context *ctdb, size_t len)
+void *ctdbd_allocate_pkt(TALLOC_CTX *mem_ctx, size_t len)
 {
        int size;
 
        size = (len+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
-       return talloc_size(ctdb, size);
+       return talloc_size(mem_ctx, size);
 }
 
 /*
index 3b0c6ad28fb102fb569b10d4878319dbd91f5877..b4adfe6f124a50cc3329dd38cfeb4ee801143fa7 100644 (file)
@@ -158,10 +158,10 @@ static int ctdb_ibw_queue_pkt(struct ctdb_node *node, uint8_t *data, uint32_t le
 /*
  * transport packet allocator - allows transport to control memory for packets
  */
-static void *ctdb_ibw_allocate_pkt(struct ctdb_context *ctdb, size_t size)
+static void *ctdb_ibw_allocate_pkt(TALLOC_CTX *mem_ctx, size_t size)
 {
        /* TODO: use ibw_alloc_send_buf instead... */
-       return talloc_size(ctdb, size);
+       return talloc_size(mem_ctx, size);
 }
 
 #ifdef __NOTDEF__
index 4b97c669cb4a49415b18eaadb803b900193008b4..ee5b78269391c95fd3180301a7cb2b87b825578c 100644 (file)
@@ -80,7 +80,7 @@ struct ctdb_methods {
        int (*start)(struct ctdb_context *); /* start protocol processing */    
        int (*add_node)(struct ctdb_node *); /* setup a new node */     
        int (*queue_pkt)(struct ctdb_node *, uint8_t *data, uint32_t length);
-       void *(*allocate_pkt)(struct ctdb_context *, size_t );
+       void *(*allocate_pkt)(TALLOC_CTX *mem_ctx, size_t );
 };
 
 /*
@@ -393,7 +393,7 @@ struct ctdb_queue *ctdb_queue_setup(struct ctdb_context *ctdb,
 /*
   allocate a packet for use in client<->daemon communication
  */
-void *ctdbd_allocate_pkt(struct ctdb_context *ctdb, size_t len);
+void *ctdbd_allocate_pkt(TALLOC_CTX *mem_ctx, size_t len);
 
 
 /*
index 20b9bc9e33ef2e4cf1ebc24c9477fb800ce623f7..7b5a7b1f43d75a7470f1de03df89699fd3ab7306 100644 (file)
@@ -78,13 +78,13 @@ static int ctdb_tcp_add_node(struct ctdb_node *node)
 /*
   transport packet allocator - allows transport to control memory for packets
 */
-static void *ctdb_tcp_allocate_pkt(struct ctdb_context *ctdb, size_t size)
+static void *ctdb_tcp_allocate_pkt(TALLOC_CTX *mem_ctx, size_t size)
 {
        /* tcp transport needs to round to 8 byte alignment to ensure
           that we can use a length header and 64 bit elements in
           structures */
        size = (size+(CTDB_TCP_ALIGNMENT-1)) & ~(CTDB_TCP_ALIGNMENT-1);
-       return talloc_size(ctdb, size);
+       return talloc_size(mem_ctx, size);
 }