From: Andrew Tridgell Date: Tue, 23 Jan 2007 00:38:45 +0000 (+1100) Subject: merge fixes from samba4 X-Git-Tag: tevent-0.9.20~348^2~2985 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=16d2ca6fa0c2e431240b2033d0b2c9196e66c200;p=thirdparty%2Fsamba.git merge fixes from samba4 (This used to be ctdb commit fb90a5424348d0b6ed9a1b8da4ceadcc4d1a1cb1) --- diff --git a/ctdb/common/ctdb.c b/ctdb/common/ctdb.c index e4150f83ca9..94715f62269 100644 --- a/ctdb/common/ctdb.c +++ b/ctdb/common/ctdb.c @@ -19,10 +19,12 @@ */ #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; } diff --git a/ctdb/common/ctdb_call.c b/ctdb/common/ctdb_call.c index 81f3cbdea10..9b21ce7cb21 100644 --- a/ctdb/common/ctdb_call.c +++ b/ctdb/common/ctdb_call.c @@ -23,10 +23,10 @@ */ #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); diff --git a/ctdb/common/ctdb_ltdb.c b/ctdb/common/ctdb_ltdb.c index 38f2d03d4fd..34fe6c6d1ad 100644 --- a/ctdb/common/ctdb_ltdb.c +++ b/ctdb/common/ctdb_ltdb.c @@ -20,9 +20,10 @@ #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 diff --git a/ctdb/include/ctdb.h b/ctdb/include/ctdb.h index ed00dc8a843..f2f4bcef84d 100644 --- a/ctdb/include/ctdb.h +++ b/ctdb/include/ctdb.h @@ -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 diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h index a024147c63e..bace97afe7b 100644 --- a/ctdb/include/ctdb_private.h +++ b/ctdb/include/ctdb_private.h @@ -18,6 +18,10 @@ 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 diff --git a/ctdb/tcp/tcp_connect.c b/ctdb/tcp/tcp_connect.c index 12dfc57d877..e828bb7cbba 100644 --- a/ctdb/tcp/tcp_connect.c +++ b/ctdb/tcp/tcp_connect.c @@ -20,9 +20,10 @@ #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); diff --git a/ctdb/tcp/tcp_init.c b/ctdb/tcp/tcp_init.c index f261d0c7dac..0058e7ad856 100644 --- a/ctdb/tcp/tcp_init.c +++ b/ctdb/tcp/tcp_init.c @@ -19,10 +19,11 @@ */ #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" /* diff --git a/ctdb/tcp/tcp_io.c b/ctdb/tcp/tcp_io.c index 63142f9c45b..5385ad7f46d 100644 --- a/ctdb/tcp/tcp_io.c +++ b/ctdb/tcp/tcp_io.c @@ -20,9 +20,11 @@ #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);