From 296b0c2a205cc32317315a9c1f898892e19b3786 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Apr 2007 16:20:32 +1000 Subject: [PATCH] - send the record header from the client to the daemon when doing a fetch, to avoid the daemon re-reading it - suffix the database name with the node name so that testing on loopback doesn't result in a name collision in the database open (This used to be ctdb commit ad30a4db75450643ff146c40faa306a021de3dd2) --- ctdb/common/ctdb_call.c | 103 +++++++++++++++++++++--------------- ctdb/common/ctdb_client.c | 6 ++- ctdb/common/ctdb_daemon.c | 10 ++-- ctdb/common/ctdb_ltdb.c | 4 ++ ctdb/include/ctdb_private.h | 5 ++ ctdb/tests/ctdb_fetch.c | 2 - 6 files changed, 77 insertions(+), 53 deletions(-) diff --git a/ctdb/common/ctdb_call.c b/ctdb/common/ctdb_call.c index 8cc97c8269e..1969a3704d9 100644 --- a/ctdb/common/ctdb_call.c +++ b/ctdb/common/ctdb_call.c @@ -592,11 +592,66 @@ 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. */ -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; + struct ctdb_context *ctdb = ctdb_db->ctdb; + + state = talloc_zero(ctdb_db, struct ctdb_call_state); + 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); + 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; + state->c->hdr.ctdb_version = CTDB_VERSION; + state->c->hdr.operation = CTDB_REQ_CALL; + 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->c->flags = call->flags; + state->c->db_id = ctdb_db->db_id; + state->c->callid = call->call_id; + state->c->keylen = call->key.dsize; + state->c->calldatalen = call->call_data.dsize; + memcpy(&state->c->data[0], call->key.dptr, call->key.dsize); + memcpy(&state->c->data[call->key.dsize], + call->call_data.dptr, call->call_data.dsize); + state->call = *call; + 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->state = CTDB_CALL_WAIT; + state->header = *header; + state->ctdb_db = ctdb_db; + + talloc_set_destructor(state, ctdb_call_destructor); + + ctdb_queue_packet(ctdb, &state->c->hdr); + + event_add_timed(ctdb->ev, state, timeval_current_ofs(CTDB_REQ_TIMEOUT, 0), + ctdb_call_timeout, state); + 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; @@ -615,49 +670,9 @@ struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db, 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_free(data.dptr); - 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); - 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; - state->c->hdr.ctdb_version = CTDB_VERSION; - state->c->hdr.operation = CTDB_REQ_CALL; - 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->c->flags = call->flags; - state->c->db_id = ctdb_db->db_id; - state->c->callid = call->call_id; - state->c->keylen = call->key.dsize; - state->c->calldatalen = call->call_data.dsize; - memcpy(&state->c->data[0], call->key.dptr, call->key.dsize); - memcpy(&state->c->data[call->key.dsize], - call->call_data.dptr, call->call_data.dsize); - state->call = *call; - 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->state = CTDB_CALL_WAIT; - state->header = header; - state->ctdb_db = ctdb_db; - - talloc_set_destructor(state, ctdb_call_destructor); - - ctdb_queue_packet(ctdb, &state->c->hdr); - - event_add_timed(ctdb->ev, state, timeval_current_ofs(CTDB_REQ_TIMEOUT, 0), - ctdb_call_timeout, state); - return state; + return ctdb_daemon_call_send_remote(ctdb_db, call, &header); } diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index 94dec19d56d..48c22acf57b 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -432,7 +432,8 @@ void ctdb_connect_wait(struct ctdb_context *ctdb) 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; @@ -468,6 +469,7 @@ static struct ctdb_fetch_lock_state *ctdb_client_fetch_lock_send(struct ctdb_db_ 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); @@ -572,7 +574,7 @@ struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALL } /* 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); diff --git a/ctdb/common/ctdb_daemon.c b/ctdb/common/ctdb_daemon.c index 67653202af2..aa1f12474a1 100644 --- a/ctdb/common/ctdb_daemon.c +++ b/ctdb/common/ctdb_daemon.c @@ -125,7 +125,8 @@ static void daemon_request_register_message_handler(struct ctdb_client *client, 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; @@ -141,13 +142,12 @@ static struct ctdb_call_state *ctdb_daemon_fetch_lock_send(struct ctdb_db_contex 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; @@ -192,7 +192,7 @@ static void daemon_fetch_lock_complete(struct ctdb_call_state *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; @@ -226,7 +226,7 @@ static void daemon_request_fetch_lock(struct ctdb_client *client, 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); diff --git a/ctdb/common/ctdb_ltdb.c b/ctdb/common/ctdb_ltdb.c index e2aa47e4cdd..a1e45efb025 100644 --- a/ctdb/common/ctdb_ltdb.c +++ b/ctdb/common/ctdb_ltdb.c @@ -82,6 +82,10 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb, const char *name, } } + /* add the node id to the database name, so when we run on loopback + we don't conflict in the local filesystem */ + name = talloc_asprintf(ctdb_db, "%s.%u", name, ctdb_get_vnn(ctdb)); + /* when we have a separate daemon this will need to be a real file, not a TDB_INTERNAL, so the parent can access it to for ltdb bypass */ diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 181200e485c..be0fbf85ae0 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -306,6 +306,7 @@ struct ctdb_reply_connect_wait { struct ctdb_req_fetch_lock { struct ctdb_req_header hdr; + struct ctdb_ltdb_header header; uint32_t db_id; uint32_t keylen; uint8_t key[1]; /* key[] */ @@ -439,4 +440,8 @@ struct ctdb_call_state *ctdb_daemon_call_send(struct ctdb_db_context *ctdb_db, int ctdb_daemon_call_recv(struct ctdb_call_state *state, 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); + #endif diff --git a/ctdb/tests/ctdb_fetch.c b/ctdb/tests/ctdb_fetch.c index 35ab9892994..1ae8e8aafda 100644 --- a/ctdb/tests/ctdb_fetch.c +++ b/ctdb/tests/ctdb_fetch.c @@ -94,8 +94,6 @@ static void bench_fetch_1node(struct ctdb_context *ctdb) 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 */