merge fixes from samba4
authorAndrew Tridgell <tridge@samba.org>
Tue, 23 Jan 2007 00:38:45 +0000 (11:38 +1100)
committerAndrew Tridgell <tridge@samba.org>
Tue, 23 Jan 2007 00:38:45 +0000 (11:38 +1100)
(This used to be ctdb commit fb90a5424348d0b6ed9a1b8da4ceadcc4d1a1cb1)

ctdb/common/ctdb.c
ctdb/common/ctdb_call.c
ctdb/common/ctdb_ltdb.c
ctdb/include/ctdb.h
ctdb/include/ctdb_private.h
ctdb/tcp/tcp_connect.c
ctdb/tcp/tcp_init.c
ctdb/tcp/tcp_io.c

index e4150f83ca92c16ea4327caf1d6fb57ba440e0ba..94715f622698761201ee3522b81d0a32e2eafba1 100644 (file)
 */
 
 #include "includes.h"
+#include "lib/tdb/include/tdb.h"
 #include "lib/events/events.h"
+#include "lib/util/dlinklist.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
+#include "../include/ctdb_private.h"
 
 /*
   choose the transport we will use
@@ -46,6 +48,13 @@ void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags)
        ctdb->flags |= flags;
 }
 
+/*
+  set max acess count before a dmaster migration
+*/
+void ctdb_set_max_lacount(struct ctdb_context *ctdb, unsigned count)
+{
+       ctdb->max_lacount = count;
+}
 
 /*
   add a node to the list of active nodes
@@ -144,6 +153,14 @@ int ctdb_set_call(struct ctdb_context *ctdb, ctdb_fn_t fn, int id)
        return 0;
 }
 
+/*
+  return the vnn of this node
+*/
+uint32_t ctdb_get_vnn(struct ctdb_context *ctdb)
+{
+       return ctdb->vnn;
+}
+
 /*
   start the protocol going
 */
@@ -168,6 +185,7 @@ static void ctdb_recv_pkt(struct ctdb_context *ctdb, uint8_t *data, uint32_t len
                               hdr->length, length);
                return;
        }
+
        switch (hdr->operation) {
        case CTDB_REQ_CALL:
                ctdb_request_call(ctdb, hdr);
@@ -268,6 +286,7 @@ struct ctdb_context *ctdb_init(struct event_context *ev)
        ctdb->ev = ev;
        ctdb->upcalls = &ctdb_upcalls;
        ctdb->idr = idr_init(ctdb);
+       ctdb->max_lacount = CTDB_DEFAULT_MAX_LACOUNT;
 
        return ctdb;
 }
index 81f3cbdea10212c27bb6d24f71e87925a8be6567..9b21ce7cb21ede602c7ff03240fc7d3e358bb24c 100644 (file)
 */
 #include "includes.h"
 #include "lib/events/events.h"
+#include "lib/tdb/include/tdb.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
-
+#include "../include/ctdb_private.h"
 
 /*
   queue a packet or die
@@ -113,6 +113,9 @@ static int ctdb_call_local(struct ctdb_context *ctdb, TDB_DATA key,
 /*
   send an error reply
 */
+static void ctdb_send_error(struct ctdb_context *ctdb, 
+                           struct ctdb_req_header *hdr, uint32_t status,
+                           const char *fmt, ...) PRINTF_ATTRIBUTE(4,5);
 static void ctdb_send_error(struct ctdb_context *ctdb, 
                            struct ctdb_req_header *hdr, uint32_t status,
                            const char *fmt, ...)
@@ -120,7 +123,7 @@ static void ctdb_send_error(struct ctdb_context *ctdb,
        va_list ap;
        struct ctdb_reply_error *r;
        char *msg;
-       int len;
+       int msglen, len;
 
        va_start(ap, fmt);
        msg = talloc_vasprintf(ctdb, fmt, ap);
@@ -129,17 +132,19 @@ static void ctdb_send_error(struct ctdb_context *ctdb,
        }
        va_end(ap);
 
-       len = strlen(msg)+1;
-       r = ctdb->methods->allocate_pkt(ctdb, sizeof(*r) + len);
+       msglen = strlen(msg)+1;
+       len = offsetof(struct ctdb_reply_error, msg);
+       r = ctdb->methods->allocate_pkt(ctdb, len + msglen);
        CTDB_NO_MEMORY_FATAL(ctdb, r);
-       r->hdr.length = sizeof(*r) + len;
+
+       r->hdr.length    = len + msglen;
        r->hdr.operation = CTDB_REPLY_ERROR;
        r->hdr.destnode  = hdr->srcnode;
        r->hdr.srcnode   = ctdb->vnn;
        r->hdr.reqid     = hdr->reqid;
        r->status        = status;
-       r->msglen        = len;
-       memcpy(&r->msg[0], msg, len);
+       r->msglen        = msglen;
+       memcpy(&r->msg[0], msg, msglen);
 
        talloc_free(msg);
 
@@ -187,7 +192,7 @@ static void ctdb_call_send_dmaster(struct ctdb_context *ctdb,
        struct ctdb_req_dmaster *r;
        int len;
        
-       len = sizeof(*r) + key->dsize + data->dsize;
+       len = offsetof(struct ctdb_req_dmaster, data) + key->dsize + data->dsize;
        r = ctdb->methods->allocate_pkt(ctdb, len);
        CTDB_NO_MEMORY_FATAL(ctdb, r);
        r->hdr.length    = len;
@@ -201,7 +206,7 @@ static void ctdb_call_send_dmaster(struct ctdb_context *ctdb,
        memcpy(&r->data[0], key->dptr, key->dsize);
        memcpy(&r->data[key->dsize], data->dptr, data->dsize);
 
-       if (r->hdr.destnode == ctdb->vnn && !(ctdb->flags & CTDB_FLAG_SELF_CONNECT)) {
+       if (r->hdr.destnode == ctdb->vnn) {
                /* we are the lmaster - don't send to ourselves */
                ctdb_request_dmaster(ctdb, &r->hdr);
        } else {
@@ -226,9 +231,9 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
 {
        struct ctdb_req_dmaster *c = (struct ctdb_req_dmaster *)hdr;
        struct ctdb_reply_dmaster *r;
-       TDB_DATA key, data;
+       TDB_DATA key, data, data2;
        struct ctdb_ltdb_header header;
-       int ret;
+       int ret, len;
 
        key.dptr = c->data;
        key.dsize = c->keylen;
@@ -236,7 +241,7 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
        data.dsize = c->datalen;
 
        /* fetch the current record */
-       ret = ctdb_ltdb_fetch(ctdb, key, &header, &data);
+       ret = ctdb_ltdb_fetch(ctdb, key, &header, &data2);
        if (ret != 0) {
                ctdb_fatal(ctdb, "ctdb_req_dmaster failed to fetch record");
                return;
@@ -255,9 +260,10 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
        }
 
        /* send the CTDB_REPLY_DMASTER */
-       r = ctdb->methods->allocate_pkt(ctdb, sizeof(*r) + data.dsize);
+       len = offsetof(struct ctdb_reply_dmaster, data) + data.dsize;
+       r = ctdb->methods->allocate_pkt(ctdb, len);
        CTDB_NO_MEMORY_FATAL(ctdb, r);
-       r->hdr.length = sizeof(*r) + data.dsize;
+       r->hdr.length    = len;
        r->hdr.operation = CTDB_REPLY_DMASTER;
        r->hdr.destnode  = c->dmaster;
        r->hdr.srcnode   = ctdb->vnn;
@@ -265,7 +271,11 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
        r->datalen       = data.dsize;
        memcpy(&r->data[0], data.dptr, data.dsize);
 
-       ctdb_queue_packet(ctdb, &r->hdr);
+       if (r->hdr.destnode == r->hdr.srcnode) {
+               ctdb_reply_dmaster(ctdb, &r->hdr);
+       } else {
+               ctdb_queue_packet(ctdb, &r->hdr);
+       }
 
        talloc_free(r);
 }
@@ -279,7 +289,7 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        struct ctdb_req_call *c = (struct ctdb_req_call *)hdr;
        TDB_DATA key, data, call_data, reply_data;
        struct ctdb_reply_call *r;
-       int ret;
+       int ret, len;
        struct ctdb_ltdb_header header;
 
        key.dptr = c->data;
@@ -307,7 +317,7 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        /* if this nodes has done enough consecutive calls on the same record
           then give them the record */
        if (header.laccessor == c->hdr.srcnode &&
-           header.lacount >= CTDB_MAX_LACOUNT) {
+           header.lacount >= ctdb->max_lacount) {
                ctdb_call_send_dmaster(ctdb, c, &header, &key, &data);
                talloc_free(data.dptr);
                return;
@@ -317,9 +327,10 @@ void ctdb_request_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
                        call_data.dsize?&call_data:NULL,
                        &reply_data, c->hdr.srcnode);
 
-       r = ctdb->methods->allocate_pkt(ctdb, sizeof(*r) + reply_data.dsize);
+       len = offsetof(struct ctdb_reply_call, data) + reply_data.dsize;
+       r = ctdb->methods->allocate_pkt(ctdb, len);
        CTDB_NO_MEMORY_FATAL(ctdb, r);
-       r->hdr.length = sizeof(*r) + reply_data.dsize;
+       r->hdr.length    = len;
        r->hdr.operation = CTDB_REPLY_CALL;
        r->hdr.destnode  = hdr->srcnode;
        r->hdr.srcnode   = hdr->destnode;
@@ -364,6 +375,7 @@ void ctdb_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        TDB_DATA reply_data;
 
        state = idr_find(ctdb->idr, hdr->reqid);
+       if (state == NULL) return;
 
        reply_data.dptr = c->data;
        reply_data.dsize = c->datalen;
@@ -389,6 +401,7 @@ void ctdb_reply_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        TDB_DATA data;
 
        state = idr_find(ctdb->idr, hdr->reqid);
+       if (state == NULL) return;
 
        data.dptr = c->data;
        data.dsize = c->datalen;
@@ -421,6 +434,7 @@ void ctdb_reply_error(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        struct ctdb_call_state *state;
 
        state = idr_find(ctdb->idr, hdr->reqid);
+       if (state == NULL) return;
 
        talloc_steal(state, c);
 
@@ -442,6 +456,7 @@ void ctdb_reply_redirect(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
        struct ctdb_call_state *state;
 
        state = idr_find(ctdb->idr, hdr->reqid);
+       if (state == NULL) return;
 
        talloc_steal(state, c);
        
@@ -474,7 +489,8 @@ void ctdb_call_timeout(struct event_context *ev, struct timed_event *te,
 {
        struct ctdb_call_state *state = talloc_get_type(private, struct ctdb_call_state);
        state->state = CTDB_CALL_ERROR;
-       ctdb_set_error(state->node->ctdb, "ctdb_call timed out");
+       ctdb_set_error(state->node->ctdb, "ctdb_call %u timed out",
+                      state->c->hdr.reqid);
 }
 
 /*
@@ -538,7 +554,7 @@ struct ctdb_call_state *ctdb_call_send(struct ctdb_context *ctdb,
        state = talloc_zero(ctdb, struct ctdb_call_state);
        CTDB_NO_MEMORY_NULL(ctdb, state);
 
-       len = sizeof(*state->c) + key.dsize + (call_data?call_data->dsize:0);
+       len = offsetof(struct ctdb_req_call, data) + key.dsize + (call_data?call_data->dsize:0);
        state->c = ctdb->methods->allocate_pkt(ctdb, len);
        CTDB_NO_MEMORY_NULL(ctdb, state->c);
 
index 38f2d03d4fda4134e370d4a389da8956292f5495..34fe6c6d1ad6826fc4ac19870cc25dcf82f6f331 100644 (file)
 
 #include "includes.h"
 #include "lib/events/events.h"
+#include "lib/tdb/include/tdb.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
+#include "../include/ctdb_private.h"
 
 /*
   attach to a specific database
index ed00dc8a84323c689c9e2da336bc1f532e0239e5..f2f4bcef84da83e82106002bcf4683cafdeaec6c 100644 (file)
@@ -18,6 +18,8 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#ifndef _CTDB_H
+#define _CTDB_H
 
 /*
   structure passed to a ctdb call function
@@ -56,6 +58,11 @@ int ctdb_set_transport(struct ctdb_context *ctdb, const char *transport);
 */
 void ctdb_set_flags(struct ctdb_context *ctdb, unsigned flags);
 
+/*
+  set max acess count before a dmaster migration
+*/
+void ctdb_set_max_lacount(struct ctdb_context *ctdb, unsigned count);
+
 /*
   tell ctdb what address to listen on, in transport specific format
 */
@@ -109,3 +116,7 @@ void ctdb_connect_wait(struct ctdb_context *ctdb);
 */
 void ctdb_wait_loop(struct ctdb_context *ctdb);
 
+/* return vnn of this node */
+uint32_t ctdb_get_vnn(struct ctdb_context *ctdb);
+
+#endif
index a024147c63e39002d044b06a0dff0977e6b3760d..bace97afe7befe7145332aa5a4a67496e0f3dae7 100644 (file)
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
+#ifndef _CTDB_PRIVATE_H
+#define _CTDB_PRIVATE_H
+
+#include "ctdb.h"
 
 /*
   an installed ctdb remote call
@@ -89,6 +93,7 @@ struct ctdb_context {
        const struct ctdb_methods *methods; /* transport methods */
        const struct ctdb_upcalls *upcalls; /* transport upcalls */
        void *private; /* private to transport */
+       unsigned max_lacount;
 };
 
 #define CTDB_NO_MEMORY(ctdb, p) do { if (!(p)) { \
@@ -111,7 +116,7 @@ struct ctdb_context {
 
 /* number of consecutive calls from the same node before we give them
    the record */
-#define CTDB_MAX_LACOUNT 7
+#define CTDB_DEFAULT_MAX_LACOUNT 7
 
 /*
   the extended header for records in the ltdb
@@ -152,20 +157,20 @@ struct ctdb_req_call {
        uint32_t callid;
        uint32_t keylen;
        uint32_t calldatalen;
-       uint8_t data[0]; /* key[] followed by calldata[] */
+       uint8_t data[1]; /* key[] followed by calldata[] */
 };
 
 struct ctdb_reply_call {
        struct ctdb_req_header hdr;
        uint32_t datalen;
-       uint8_t  data[0];
+       uint8_t  data[1];
 };
 
 struct ctdb_reply_error {
        struct ctdb_req_header hdr;
        uint32_t status;
        uint32_t msglen;
-       uint8_t  msg[0];
+       uint8_t  msg[1];
 };
 
 struct ctdb_reply_redirect {
@@ -178,17 +183,17 @@ struct ctdb_req_dmaster {
        uint32_t dmaster;
        uint32_t keylen;
        uint32_t datalen;
-       uint8_t  data[0];
+       uint8_t  data[1];
 };
 
 struct ctdb_reply_dmaster {
        struct ctdb_req_header hdr;
        uint32_t datalen;
-       uint8_t  data[0];
+       uint8_t  data[1];
 };
 
 /* internal prototypes */
-void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...);
+void ctdb_set_error(struct ctdb_context *ctdb, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
 void ctdb_fatal(struct ctdb_context *ctdb, const char *msg);
 bool ctdb_same_address(struct ctdb_address *a1, struct ctdb_address *a2);
 int ctdb_parse_address(struct ctdb_context *ctdb,
@@ -209,3 +214,4 @@ int ctdb_ltdb_store(struct ctdb_context *ctdb, TDB_DATA key,
                    struct ctdb_ltdb_header *header, TDB_DATA data);
 
 
+#endif
index 12dfc57d8777bb334811b22dab3be6eb6598868d..e828bb7cbba2bb6a546465311eccce927213ce19 100644 (file)
 
 #include "includes.h"
 #include "lib/events/events.h"
+#include "lib/tdb/include/tdb.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
+#include "../include/ctdb_private.h"
 #include "ctdb_tcp.h"
 
 static void set_nonblocking(int fd)
@@ -88,7 +89,7 @@ void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te,
        sock_out.sin_port = htons(node->address.port);
        sock_out.sin_family = PF_INET;
        
-       if (connect(tnode->fd, &sock_out, sizeof(sock_out)) != 0 &&
+       if (connect(tnode->fd, (struct sockaddr *)&sock_out, sizeof(sock_out)) != 0 &&
            errno != EINPROGRESS) {
                /* try again once a second */
                close(tnode->fd);
index f261d0c7dac763ede92687770f60a1f02a827fad..0058e7ad856e9ff91d1ef75398f6acb7ef8d03d9 100644 (file)
 */
 
 #include "includes.h"
+#include "lib/tdb/include/tdb.h"
 #include "lib/events/events.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
+#include "../include/ctdb_private.h"
 #include "ctdb_tcp.h"
 
 /*
index 63142f9c45b0fbc56a0196ed8087666659774942..5385ad7f46d454c4a1326c68300059ba673f1d8c 100644 (file)
 
 #include "includes.h"
 #include "lib/events/events.h"
+#include "lib/util/dlinklist.h"
+#include "lib/tdb/include/tdb.h"
 #include "system/network.h"
 #include "system/filesys.h"
-#include "ctdb_private.h"
+#include "../include/ctdb_private.h"
 #include "ctdb_tcp.h"
 
 
@@ -199,15 +201,20 @@ int ctdb_tcp_queue_pkt(struct ctdb_node *node, uint8_t *data, uint32_t length)
        struct ctdb_tcp_node *tnode = talloc_get_type(node->private, 
                                                      struct ctdb_tcp_node);
        struct ctdb_tcp_packet *pkt;
+       uint32_t length2;
 
        /* enforce the length and alignment rules from the tcp packet allocator */
-       length = (length+(CTDB_TCP_ALIGNMENT-1)) & ~(CTDB_TCP_ALIGNMENT-1);
-       *(uint32_t *)data = length;
+       length2 = (length+(CTDB_TCP_ALIGNMENT-1)) & ~(CTDB_TCP_ALIGNMENT-1);
+       *(uint32_t *)data = length2;
+
+       if (length2 != length) {
+               memset(data+length, 0, length2-length);
+       }
        
        /* if the queue is empty then try an immediate write, avoiding
           queue overhead. This relies on non-blocking sockets */
        if (tnode->queue == NULL && tnode->fd != -1) {
-               ssize_t n = write(tnode->fd, data, length);
+               ssize_t n = write(tnode->fd, data, length2);
                if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
                        event_add_timed(node->ctdb->ev, node, timeval_zero(), 
                                        ctdb_tcp_node_dead, node);
@@ -217,18 +224,18 @@ int ctdb_tcp_queue_pkt(struct ctdb_node *node, uint8_t *data, uint32_t length)
                }
                if (n > 0) {
                        data += n;
-                       length -= n;
+                       length2 -= n;
                }
-               if (length == 0) return 0;
+               if (length2 == 0) return 0;
        }
 
        pkt = talloc(tnode, struct ctdb_tcp_packet);
        CTDB_NO_MEMORY(node->ctdb, pkt);
 
-       pkt->data = talloc_memdup(pkt, data, length);
+       pkt->data = talloc_memdup(pkt, data, length2);
        CTDB_NO_MEMORY(node->ctdb, pkt->data);
 
-       pkt->length = length;
+       pkt->length = length2;
 
        if (tnode->queue == NULL && tnode->fd != -1) {
                EVENT_FD_WRITEABLE(tnode->fde);