}
- struct ctdb_req_message *c)
+ /*
+ this is called when the ctdb daemon received a ctdb request message
+ from a local client over the unix domain socket
+ */
+ static void daemon_request_message_from_client(struct ctdb_client *client,
- } else {
- /* this is for a remote client */
-/*XXX*/
++ struct ctdb_req_message *c)
+ {
++ TDB_DATA data;
++ int res;
++
++ /* maybe the message is for another client on this node */
+ if (ctdb_get_vnn(client->ctdb)==c->hdr.destnode) {
+ ctdb_request_message(client->ctdb, (struct ctdb_req_header *)c);
++ return;
++ }
++
++ /* its for a remote node */
++ data.dptr = &c->data[0];
++ data.dsize = c->datalen;
++ res = ctdb_daemon_send_message(client->ctdb, c->hdr.destnode,
++ c->srvid, data);
++ if (res != 0) {
++ printf("Failed to send message to remote node %u\n",
++ c->hdr.destnode);
+ }
+ }
+
/*
this is called when the ctdb daemon received a ctdb request call
from a local client over the unix domain socket
if (hdr->ctdb_magic != CTDB_MAGIC) {
ctdb_set_error(client->ctdb, "Non CTDB packet rejected\n");
-- return;
++ goto done;
}
if (hdr->ctdb_version != CTDB_VERSION) {
ctdb_set_error(client->ctdb, "Bad CTDB version 0x%x rejected\n", hdr->ctdb_version);
-- return;
++ goto done;
}
switch (hdr->operation) {
daemon_request_register_message_handler(client,
(struct ctdb_req_register *)hdr);
break;
+ case CTDB_REQ_MESSAGE:
+ daemon_request_message_from_client(client, (struct ctdb_req_message *)hdr);
+ break;
}
++done:
talloc_free(data);
}
void ctdb_request_message(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
{
struct ctdb_req_message *c = (struct ctdb_req_message *)hdr;
- struct ctdb_message_list *fml, *ml;
++ struct ctdb_message_list *ml;
TDB_DATA data;
- if (ctdb->message_handler == NULL) {
+
-/* XXX need a much faster method to find the handler */
- ml = ctdb->message_list;
- fml = ml;
- while (ml) {
- if (ml->srvid==c->srvid) {
- break;
- }
- ml = ml->next;
- if (ml==fml) {
- ml = NULL;
- break;
- }
++ /* XXX we need a must faster way of finding the matching srvid
++ - maybe a tree? */
++ for (ml=ctdb->message_list;ml;ml=ml->next) {
++ if (ml->srvid == c->srvid) break;
+ }
-
+ if (ml == NULL) {
printf("no msg handler\n");
/* no registered message handler */
return;
}
++
data.dptr = &c->data[0];
data.dsize = c->datalen;
- ctdb->message_handler(ctdb, c->srvid, data, ctdb->message_private);
+ ml->message_handler(ctdb, c->srvid, data, ml->message_private);
}
*/
int ctdb_client_call_recv(struct ctdb_call_state *state, struct ctdb_call *call);
+ int ctdb_daemon_set_message_handler(struct ctdb_context *ctdb, uint32_t srvid,
+ ctdb_message_fn_t handler,
+ void *private);
+
+ int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t vnn,
+ uint32_t srvid, TDB_DATA data);
+
++/*
++ send a ctdb message
++*/
++int ctdb_daemon_send_message(struct ctdb_context *ctdb, uint32_t vnn,
++ uint32_t srvid, TDB_DATA data);
++
#endif
/* start the protocol running */
ret = ctdb_start(ctdb);
-- ctdb_set_message_handler(ctdb, message_handler, 0, &msg_count);
++ ctdb_set_message_handler(ctdb, 0, message_handler, &msg_count);
/* wait until all nodes are connected (should not be needed
outside of test code) */