From: Andrew Tridgell Date: Thu, 19 Apr 2007 00:37:44 +0000 (+1000) Subject: - make he packet allocation routines take a mem_ctx, which allows X-Git-Tag: tevent-0.9.20~348^2~2873 X-Git-Url: http://git.samba.org/samba.git/?p=vlendec%2Fsamba-autobuild%2F.git;a=commitdiff_plain;h=b79e29c779b4e1dc3247b3bb2c1d298e08bc8cdc - make he packet allocation routines take a mem_ctx, which allows 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) --- diff --git a/ctdb/common/ctdb_call.c b/ctdb/common/ctdb_call.c index e719318e608..f002a9c7628 100644 --- a/ctdb/common/ctdb_call.c +++ b/ctdb/common/ctdb_call.c @@ -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; diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 1a846175ddb..dbf620372c7 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -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; diff --git a/ctdb/common/ctdb_daemon.c b/ctdb/common/ctdb_daemon.c index a9398029472..6ef98890666 100644 --- a/ctdb/common/ctdb_daemon.c +++ b/ctdb/common/ctdb_daemon.c @@ -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); } /* diff --git a/ctdb/ib/ibw_ctdb_init.c b/ctdb/ib/ibw_ctdb_init.c index 3b0c6ad28fb..b4adfe6f124 100644 --- a/ctdb/ib/ibw_ctdb_init.c +++ b/ctdb/ib/ibw_ctdb_init.c @@ -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__ diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 4b97c669cb4..ee5b7826939 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -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); /* diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c index 20b9bc9e33e..7b5a7b1f43d 100644 --- a/ctdb/tcp/tcp_init.c +++ b/ctdb/tcp/tcp_init.c @@ -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); }