This constructs a ctdb_call request and queues it for processing.
This call never blocks.
*/
-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_remote(struct ctdb_db_context *ctdb_db,
+ struct ctdb_call *call,
+ struct ctdb_ltdb_header *header)
{
uint32_t len;
struct ctdb_call_state *state;
- int ret;
- struct ctdb_ltdb_header header;
- TDB_DATA data;
struct ctdb_context *ctdb = ctdb_db->ctdb;
- /*
- if we are the dmaster for this key then we don't need to
- send it off at all, we can bypass the network and handle it
- locally. To find out if we are the dmaster we need to look
- in our ltdb
- */
- ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
- if (ret != 0) return NULL;
-
- if (header.dmaster == ctdb->vnn && !(ctdb->flags & CTDB_FLAG_SELF_CONNECT)) {
- return ctdb_call_local_send(ctdb_db, call, &header, &data);
- }
-
state = talloc_zero(ctdb_db, struct ctdb_call_state);
CTDB_NO_MEMORY_NULL(ctdb, state);
- talloc_steal(state, data.dptr);
-
len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
state->c = ctdb->methods->allocate_pkt(ctdb, len);
CTDB_NO_MEMORY_NULL(ctdb, state->c);
state->c->hdr.ctdb_magic = CTDB_MAGIC;
state->c->hdr.ctdb_version = CTDB_VERSION;
state->c->hdr.operation = CTDB_REQ_CALL;
- state->c->hdr.destnode = header.dmaster;
+ state->c->hdr.destnode = header->dmaster;
state->c->hdr.srcnode = ctdb->vnn;
/* this limits us to 16k outstanding messages - not unreasonable */
state->c->hdr.reqid = idr_get_new(ctdb->idr, state, 0xFFFF);
state->call.call_data.dptr = &state->c->data[call->key.dsize];
state->call.key.dptr = &state->c->data[0];
- state->node = ctdb->nodes[header.dmaster];
+ state->node = ctdb->nodes[header->dmaster];
state->state = CTDB_CALL_WAIT;
- state->header = header;
+ state->header = *header;
state->ctdb_db = ctdb_db;
talloc_set_destructor(state, ctdb_call_destructor);
return state;
}
+/*
+ make a remote ctdb call - async send. Called in daemon context.
+
+ This constructs a ctdb_call request and queues it for processing.
+ This call never blocks.
+*/
+struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db,
+ struct ctdb_call *call)
+{
+ int ret;
+ struct ctdb_ltdb_header header;
+ TDB_DATA data;
+ struct ctdb_context *ctdb = ctdb_db->ctdb;
+
+ /*
+ if we are the dmaster for this key then we don't need to
+ send it off at all, we can bypass the network and handle it
+ locally. To find out if we are the dmaster we need to look
+ in our ltdb
+ */
+ ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
+ if (ret != 0) return NULL;
+
+ if (header.dmaster == ctdb->vnn && !(ctdb->flags & CTDB_FLAG_SELF_CONNECT)) {
+ return ctdb_call_local_send(ctdb_db, call, &header, &data);
+ }
+
+ talloc_free(data.dptr);
+
+ return ctdb_daemon_call_send_remote(ctdb_db, call, &header);
+}
+
/*
make a remote ctdb call - async recv - called in daemon context
static struct ctdb_fetch_lock_state *ctdb_client_fetch_lock_send(struct ctdb_db_context *ctdb_db,
TALLOC_CTX *mem_ctx,
- TDB_DATA key)
+ TDB_DATA key,
+ struct ctdb_ltdb_header *header)
{
struct ctdb_fetch_lock_state *state;
struct ctdb_context *ctdb = ctdb_db->ctdb;
req->hdr.reqid = idr_get_new(ctdb->idr, state, 0xFFFF);
req->db_id = ctdb_db->db_id;
req->keylen = key.dsize;
+ req->header = *header;
memcpy(&req->key[0], key.dptr, key.dsize);
res = ctdb_client_queue_pkt(ctdb, &req->hdr);
}
/* we're not the dmaster - ask the ctdb daemon to make us dmaster */
- state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key);
+ state = ctdb_client_fetch_lock_send(ctdb_db, mem_ctx, key, &h->header);
ret = ctdb_client_fetch_lock_recv(state, mem_ctx, key, &h->header, data);
if (ret != 0) {
talloc_free(h);
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)
+ TDB_DATA key, struct ctdb_ltdb_header *header,
+ TDB_DATA *data)
{
struct ctdb_call *call;
struct ctdb_record_handle *rec;
call->key = key;
call->flags = CTDB_IMMEDIATE_MIGRATION;
-
rec->ctdb_db = ctdb_db;
rec->key = key;
rec->key.dptr = talloc_memdup(rec, key.dptr, key.dsize);
rec->data = data;
- state = ctdb_daemon_call_send(ctdb_db, call);
+ state = ctdb_daemon_call_send_remote(ctdb_db, call, header);
state->fetch_private = rec;
return state;
called when the daemon gets a fetch lock request from a client
*/
static void daemon_request_fetch_lock(struct ctdb_client *client,
- struct ctdb_req_fetch_lock *f)
+ struct ctdb_req_fetch_lock *f)
{
struct ctdb_call_state *state;
TDB_DATA key, *data;
data->dptr = NULL;
data->dsize = 0;
- state = ctdb_daemon_fetch_lock_send(ctdb_db, client, key, data);
+ state = ctdb_daemon_fetch_lock_send(ctdb_db, client, key, &f->header, data);
talloc_steal(state, data);
fl_data = talloc(state, struct client_fetch_lock_data);