------------------------------------------------------------ revno: 90 revision-id: [EMAIL PROTECTED] parent: [EMAIL PROTECTED] committer: Andrew Tridgell <[EMAIL PROTECTED]> branch nick: tridge timestamp: Wed 2007-04-11 14:26:14 +1000 message: fixed sending messages to ourselves in non-daemon mode modified: common/ctdb_message.c ctdb_message.c-20070208224107-9dnio7x7z33prrmt-1 include/ctdb_private.h ctdb_private.h-20061117234101-o3qt14umlg9en8z0-13 === modified file 'common/ctdb_message.c' --- a/common/ctdb_message.c 2007-04-11 04:05:01 +0000 +++ b/common/ctdb_message.c 2007-04-11 04:26:14 +0000 @@ -30,42 +30,101 @@ /* - called when a CTDB_REQ_MESSAGE packet comes in - this dispatches the messages to the registered ctdb message handler */ -void ctdb_request_message(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) +static int ctdb_dispatch_message(struct ctdb_context *ctdb, uint32_t srvid, TDB_DATA data) { - struct ctdb_req_message *c = (struct ctdb_req_message *)hdr; struct ctdb_message_list *ml; - TDB_DATA data; /* 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->srvid == srvid) break; } if (ml == NULL) { - printf("no msg handler\n"); + printf("no msg handler for srvid=%u\n", srvid); /* no registered message handler */ - return; + return -1; } + ml->message_handler(ctdb, srvid, data, ml->message_private); + return 0; +} + + +/* + called when a CTDB_REQ_MESSAGE packet comes in +*/ +void ctdb_request_message(struct ctdb_context *ctdb, struct ctdb_req_header *hdr) +{ + struct ctdb_req_message *c = (struct ctdb_req_message *)hdr; + TDB_DATA data; + data.dptr = &c->data[0]; data.dsize = c->datalen; - ml->message_handler(ctdb, c->srvid, data, ml->message_private); -} - + + ctdb_dispatch_message(ctdb, c->srvid, data); +} + +/* + this local messaging handler is ugly, but is needed to prevent + recursion in ctdb_send_message() when the destination node is the + same as the source node + */ +struct ctdb_local_message { + struct ctdb_context *ctdb; + uint32_t srvid; + TDB_DATA data; +}; + +static void ctdb_local_message_trigger(struct event_context *ev, struct timed_event *te, + struct timeval t, void *private) +{ + struct ctdb_local_message *m = talloc_get_type(private, + struct ctdb_local_message); + int res; + + res = ctdb_dispatch_message(m->ctdb, m->srvid, m->data); + if (res != 0) { + printf("Failed to dispatch message for srvid=%u\n", m->srvid); + } + talloc_free(m); +} + +static int ctdb_local_message(struct ctdb_context *ctdb, uint32_t srvid, TDB_DATA data) +{ + struct ctdb_local_message *m; + m = talloc(ctdb, struct ctdb_local_message); + CTDB_NO_MEMORY(ctdb, m); + + m->ctdb = ctdb; + m->srvid = srvid; + m->data = data; + m->data.dptr = talloc_memdup(m, m->data.dptr, m->data.dsize); + if (m->data.dptr == NULL) { + talloc_free(m); + return -1; + } + + /* this needs to be done as an event to prevent recursion */ + event_add_timed(ctdb->ev, m, timeval_zero(), ctdb_local_message_trigger, m); + return 0; +} /* send a ctdb message */ int ctdb_daemon_send_message(struct ctdb_context *ctdb, uint32_t vnn, - uint32_t srvid, TDB_DATA data) + uint32_t srvid, TDB_DATA data) { struct ctdb_req_message *r; int len; + /* see if this is a message to ourselves */ + if (vnn == ctdb->vnn && !(ctdb->flags & CTDB_FLAG_SELF_CONNECT)) { + return ctdb_local_message(ctdb, srvid, data); + } + len = offsetof(struct ctdb_req_message, data) + data.dsize; r = ctdb->methods->allocate_pkt(ctdb, len); CTDB_NO_MEMORY(ctdb, r);
=== modified file 'include/ctdb_private.h' --- a/include/ctdb_private.h 2007-04-11 04:05:01 +0000 +++ b/include/ctdb_private.h 2007-04-11 04:26:14 +0000 @@ -381,4 +381,5 @@ int ctdb_daemon_send_message(struct ctdb_context *ctdb, uint32_t vnn, uint32_t srvid, TDB_DATA data); + #endif