diff options
author | Ronnie Sahlberg <sahlberg@ronnie> | 2007-04-24 00:06:48 +1000 |
---|---|---|
committer | Ronnie Sahlberg <sahlberg@ronnie> | 2007-04-24 00:06:48 +1000 |
commit | dabf61075f261c0aa40e700e6463de377a3eba08 (patch) | |
tree | 8ffb5f1c51fdba65fa1321904b64a1dc59ded695 /ctdb | |
parent | bd62c78154836da65524e76ac580d703edea9c67 (diff) | |
download | samba-dabf61075f261c0aa40e700e6463de377a3eba08.tar.gz samba-dabf61075f261c0aa40e700e6463de377a3eba08.tar.xz samba-dabf61075f261c0aa40e700e6463de377a3eba08.zip |
add pdu's that the client can use to query the ctdb daemon of the path
to the database it created (so the client can open and access the same
file)
(This used to be ctdb commit c2eda19499b3263b2248c41bd531fb73c7b42212)
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/common/ctdb_client.c | 86 | ||||
-rw-r--r-- | ctdb/common/ctdb_daemon.c | 49 | ||||
-rw-r--r-- | ctdb/include/ctdb.h | 2 | ||||
-rw-r--r-- | ctdb/include/ctdb_private.h | 15 | ||||
-rw-r--r-- | ctdb/tests/ctdb_test.c | 6 |
5 files changed, 153 insertions, 5 deletions
diff --git a/ctdb/common/ctdb_client.c b/ctdb/common/ctdb_client.c index f00697bc26..5acce1ee30 100644 --- a/ctdb/common/ctdb_client.c +++ b/ctdb/common/ctdb_client.c @@ -92,6 +92,7 @@ static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_he } static void ctdb_reply_status(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); +static void ctdb_reply_getdbpath(struct ctdb_context *ctdb, struct ctdb_req_header *hdr); /* this is called in the client, when data comes in from the daemon @@ -151,6 +152,10 @@ static void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args) ctdb_reply_status(ctdb, hdr); break; + case CTDB_REPLY_GETDBPATH: + ctdb_reply_getdbpath(ctdb, hdr); + break; + default: DEBUG(0,("bogus operation code:%d\n",hdr->operation)); } @@ -649,10 +654,6 @@ static void ctdb_reply_status(struct ctdb_context *ctdb, struct ctdb_req_header state->state = CTDB_STATUS_DONE; } -/* - wait until we're the only node left. - this function never returns -*/ int ctdb_status(struct ctdb_context *ctdb, struct ctdb_status *status) { struct ctdb_req_status r; @@ -693,3 +694,80 @@ int ctdb_status(struct ctdb_context *ctdb, struct ctdb_status *status) return 0; } + +enum ctdb_getdbpath_states {CTDB_GETDBPATH_WAIT, CTDB_GETDBPATH_DONE}; + +struct ctdb_getdbpath_state { + uint32_t reqid; + TDB_DATA path; + enum ctdb_getdbpath_states state; +}; + +/* + handle a ctdb_reply_getdbpath reply + */ +static void ctdb_reply_getdbpath(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) +{ + struct ctdb_reply_getdbpath *r = (struct ctdb_reply_getdbpath *)hdr; + struct ctdb_getdbpath_state *state; + + state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_getdbpath_state); + if (state == NULL) { + DEBUG(0,(__location__ " reqid %d not found\n", hdr->reqid)); + return; + } + + if (hdr->reqid != state->reqid) { + /* we found a record but it was the wrong one */ + DEBUG(0, ("Dropped orphaned reply with reqid:%d\n",hdr->reqid)); + return; + } + + state->path.dsize = r->datalen; + state->path.dptr = talloc_memdup(state, &r->data[0], r->datalen); + + state->state = CTDB_GETDBPATH_DONE; +} + +int ctdb_getdbpath(struct ctdb_db_context *ctdb_db, TDB_DATA *path) +{ + struct ctdb_req_getdbpath r; + int ret; + struct ctdb_getdbpath_state *state; + + /* if the domain socket is not yet open, open it */ + if (ctdb_db->ctdb->daemon.sd==-1) { + ctdb_socket_connect(ctdb_db->ctdb); + } + + state = talloc(ctdb_db, struct ctdb_getdbpath_state); +/* CTDB_NO_MEMORY(ctdb_db, state);*/ + + state->reqid = ctdb_reqid_new(ctdb_db->ctdb, state); + state->state = CTDB_GETDBPATH_WAIT; + + ZERO_STRUCT(r); + r.hdr.length = sizeof(r); + r.hdr.ctdb_magic = CTDB_MAGIC; + r.hdr.ctdb_version = CTDB_VERSION; + r.hdr.operation = CTDB_REQ_GETDBPATH; + r.hdr.reqid = state->reqid; + r.db_id = ctdb_db->db_id; + + ret = ctdb_client_queue_pkt(ctdb_db->ctdb, &r.hdr); + if (ret != 0) { + talloc_free(state); + return -1; + } + + while (state->state == CTDB_GETDBPATH_WAIT) { + event_loop_once(ctdb_db->ctdb->ev); + } + + path->dsize = state->path.dsize; + path->dptr = talloc_steal(path, state->path.dptr); + talloc_free(state); + + return 0; +} + diff --git a/ctdb/common/ctdb_daemon.c b/ctdb/common/ctdb_daemon.c index ff3431a392..4fcaadb6bb 100644 --- a/ctdb/common/ctdb_daemon.c +++ b/ctdb/common/ctdb_daemon.c @@ -249,6 +249,51 @@ static void daemon_request_status(struct ctdb_client *client, } /* + called when the daemon gets a getdbpath request from a client + */ +static void daemon_request_getdbpath(struct ctdb_client *client, + struct ctdb_req_getdbpath *c) +{ + struct ctdb_reply_getdbpath *r; + struct ctdb_db_context *ctdb_db; + char *path; + int res, len; + + 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)); + ctdb_db->ctdb->status.pending_calls--; + return; + } + + path = talloc_asprintf(c, "%s/%s", ctdb_db->ctdb->db_directory, ctdb_db->db_name); + + /* now send the reply */ + len = offsetof(struct ctdb_reply_getdbpath, data) + strlen(path); + r = ctdbd_allocate_pkt(ctdb_db->ctdb, len); + + talloc_set_name_const(r, "reply_getdbpath packet"); + + memset(r, 0, offsetof(struct ctdb_reply_getdbpath, data)); + + r->hdr.length = len; + r->hdr.ctdb_magic = CTDB_MAGIC; + r->hdr.ctdb_version = CTDB_VERSION; + r->hdr.operation = CTDB_REPLY_GETDBPATH; + r->hdr.reqid = c->hdr.reqid; + r->datalen = strlen(path); + memcpy(&r->data[0], path, r->datalen); + + res = daemon_queue_send(client, &(r->hdr)); + if (res != 0) { + DEBUG(0,(__location__ " Failed to queue a getdbpath response\n")); + return; + } +} + + +/* destroy a ctdb_client */ static int ctdb_client_destructor(struct ctdb_client *client) @@ -493,6 +538,10 @@ static void daemon_incoming_packet(void *p, uint8_t *data, uint32_t nread) daemon_request_status(client, (struct ctdb_req_status *)hdr); break; + case CTDB_REQ_GETDBPATH: + daemon_request_getdbpath(client, (struct ctdb_req_getdbpath *)hdr); + break; + default: DEBUG(0,(__location__ " daemon: unrecognized operation %d\n", hdr->operation)); diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index cb765884b6..79de16f33b 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -213,4 +213,6 @@ struct ctdb_context *ctdb_cmdline_client(struct event_context *ev, const char *c struct ctdb_status; int ctdb_status(struct ctdb_context *ctdb, struct ctdb_status *status); +int ctdb_getdbpath(struct ctdb_db_context *ctdb_db, TDB_DATA *path); + #endif diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index 9feb098a62..98fc10bb2c 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -265,7 +265,9 @@ enum ctdb_operation { CTDB_REPLY_CONNECT_WAIT = 1002, CTDB_REQ_SHUTDOWN = 1003, CTDB_REQ_STATUS = 1004, - CTDB_REPLY_STATUS = 1005 + CTDB_REPLY_STATUS = 1005, + CTDB_REQ_GETDBPATH = 1006, + CTDB_REPLY_GETDBPATH = 1007 }; #define CTDB_MAGIC 0x43544442 /* CTDB */ @@ -358,6 +360,17 @@ struct ctdb_reply_connect_wait { uint32_t num_connected; }; +struct ctdb_req_getdbpath { + struct ctdb_req_header hdr; + uint32_t db_id; +}; + +struct ctdb_reply_getdbpath { + struct ctdb_req_header hdr; + uint32_t datalen; + uint8_t data[1]; +}; + struct ctdb_req_status { struct ctdb_req_header hdr; }; diff --git a/ctdb/tests/ctdb_test.c b/ctdb/tests/ctdb_test.c index dec1ea5100..0167fcd3a8 100644 --- a/ctdb/tests/ctdb_test.c +++ b/ctdb/tests/ctdb_test.c @@ -91,6 +91,7 @@ int main(int argc, const char *argv[]) poptContext pc; struct event_context *ev; struct ctdb_call call; + TDB_DATA *path; pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); @@ -135,6 +136,11 @@ int main(int argc, const char *argv[]) ctdb_connect_wait(ctdb); + /* find the full path to the database file */ + path = talloc_zero(ctdb_db, TDB_DATA); + ctdb_getdbpath(ctdb_db, path); + printf("path to database:[%s]\n",path->dptr); + ZERO_STRUCT(call); call.key.dptr = discard_const("test"); call.key.dsize = strlen("test")+1; |