}
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
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));
}
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;
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;
+}
+
}
}
+/*
+ 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
*/
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));
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
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 */
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;
};
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);
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;