mirror of
https://github.com/samba-team/samba.git
synced 2025-01-08 21:18:16 +03:00
- 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)
This commit is contained in:
parent
fde5a66531
commit
b79e29c779
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
talloc_steal(client, dstate);
|
||||
talloc_steal(dstate, dstate->call);
|
||||
|
||||
res = ctdb_daemon_call_recv(state, dstate->call);
|
||||
if (res != 0) {
|
||||
DEBUG(0, (__location__ " ctdbd_call_recv() returned error\n"));
|
||||
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;
|
||||
|
||||
/* XXX this must be converted to fully async */
|
||||
res = ctdb_daemon_call_recv(state, &call);
|
||||
if (res != 0) {
|
||||
DEBUG(0, (__location__ " ctdbd_call_recv() returned error\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user