]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
fixed sending messages to ourselves in non-daemon mode
authorAndrew Tridgell <tridge@samba.org>
Wed, 11 Apr 2007 04:26:14 +0000 (14:26 +1000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 11 Apr 2007 04:26:14 +0000 (14:26 +1000)
(This used to be ctdb commit 325afd2de2f5a96fb4f8ec624e04f253c712c97d)

ctdb/common/ctdb_message.c
ctdb/include/ctdb_private.h

index 088f882dbd51338822a4a6c8ed4537180bd2c0f1..ebba1d8faa24bf7418218547ae8ef0ffe0bcb14b 100644 (file)
 
 
 /*
-  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);
index af183168dddcf46dffb962e56b9a0ee1609f5c34..0f6f57e50a14dbbd90234a45228b4284f50b22df 100644 (file)
@@ -381,4 +381,5 @@ int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t vnn,
 int ctdb_daemon_send_message(struct ctdb_context *ctdb, uint32_t vnn,
                             uint32_t srvid, TDB_DATA data);
 
+
 #endif