[SCM] CTDB repository - branch 1.0.112 updated - ctdb-1.0.111-23-g82f2ed8
Ronnie Sahlberg
sahlberg at samba.org
Wed Feb 3 21:41:52 MST 2010
The branch, 1.0.112 has been updated
via 82f2ed827caab8999cb3f958c70821a23490fdde (commit)
via ac885788678255f0c8a091f88ee4d440edf818a9 (commit)
via a781f05f9b80e288ae43ca16f109890942937e62 (commit)
via 3ec469339e56f5221960ac5b3a69bf8fb553b8f5 (commit)
from 4af34ca1bdb4895c2dd1ec280ef14cffab7fc815 (commit)
http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=1.0.112
- Log -----------------------------------------------------------------
commit 82f2ed827caab8999cb3f958c70821a23490fdde
Author: Andrew Tridgell <tridge at samba.org>
Date: Thu Feb 4 14:36:14 2010 +1100
ctdb: when we fill the client packet queue we need to drop the client
We can't just drop packets to the list, as those packets could be part
of the core protocol the client is using. This happens (for example)
when Samba is doing a traverse. If we drop a traverse packet then
Samba hangs indefinately. We are better off dropping the ctdb socket
to Samba.
commit ac885788678255f0c8a091f88ee4d440edf818a9
Author: Andrew Tridgell <tridge at samba.org>
Date: Thu Feb 4 14:14:18 2010 +1100
ctdb: move ctdb_io.c to use TLIST_*() macros
This will make large packet queues much more efficient
commit a781f05f9b80e288ae43ca16f109890942937e62
Author: Andrew Tridgell <tridge at samba.org>
Date: Thu Feb 4 14:13:49 2010 +1100
util: added TLIST_*() macros
The TLIST_*() macros are like the DLIST_*() macros, but take both a
head and tail pointer for the list. This means that adding an element
to the end of the list is efficient (it doesn't need to walk the
list).
We should move all uses of the DLIST_*() macros which use
DLIST_ADD_END() to use the TLIST_*() macros instead.
commit 3ec469339e56f5221960ac5b3a69bf8fb553b8f5
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date: Thu Feb 4 09:54:06 2010 +1100
We only queued up to 1000 packets per queue before we start dropping
packets, to avoid the queue to grow excessively if smbd has blocked.
This could cause traverse packets to become discarded in case the main
smbd daemon does a traverse of a database while there is a recovery
(sending a erconfigured message to smbd, causing an avalanche of unlock
messages to be sent across the cluster.)
This avalance of messages could cause also the tranversal message to be
discarded causing the main smbd process to hang indefinitely waiting
for the traversal message that will never arrive.
Bump the maximum queue length before starting to discard messages from
1000 to 1000000 and at the same time rework the queueing slightly so we
can append messages cheaply to the queue instead of walking the list
from head to tail every time.
-----------------------------------------------------------------------
Summary of changes:
common/ctdb_io.c | 10 ++++++----
lib/util/dlinklist.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++
server/ctdb_daemon.c | 17 ++++++++++++-----
server/ctdb_tunables.c | 2 +-
4 files changed, 65 insertions(+), 10 deletions(-)
Changeset truncated at 500 lines:
diff --git a/common/ctdb_io.c b/common/ctdb_io.c
index 28830d5..3fa784d 100644
--- a/common/ctdb_io.c
+++ b/common/ctdb_io.c
@@ -45,7 +45,7 @@ struct ctdb_queue_pkt {
struct ctdb_queue {
struct ctdb_context *ctdb;
struct ctdb_partial partial; /* partial input packet */
- struct ctdb_queue_pkt *out_queue;
+ struct ctdb_queue_pkt *out_queue, *out_queue_tail;
uint32_t out_queue_length;
struct fd_event *fde;
int fd;
@@ -194,7 +194,8 @@ static void queue_io_write(struct ctdb_queue *queue)
if (n == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
if (pkt->length != pkt->full_length) {
/* partial packet sent - we have to drop it */
- DLIST_REMOVE(queue->out_queue, pkt);
+ TLIST_REMOVE(queue->out_queue, queue->out_queue_tail,
+ pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
@@ -213,7 +214,7 @@ static void queue_io_write(struct ctdb_queue *queue)
return;
}
- DLIST_REMOVE(queue->out_queue, pkt);
+ TLIST_REMOVE(queue->out_queue, queue->out_queue_tail, pkt);
queue->out_queue_length--;
talloc_free(pkt);
}
@@ -294,7 +295,8 @@ int ctdb_queue_send(struct ctdb_queue *queue, uint8_t *data, uint32_t length)
EVENT_FD_WRITEABLE(queue->fde);
}
- DLIST_ADD_END(queue->out_queue, pkt, struct ctdb_queue_pkt *);
+ TLIST_ADD_END(queue->out_queue, queue->out_queue_tail, pkt);
+
queue->out_queue_length++;
if (queue->ctdb->tunable.verbose_memory_names != 0) {
diff --git a/lib/util/dlinklist.h b/lib/util/dlinklist.h
index f018d87..44747d6 100644
--- a/lib/util/dlinklist.h
+++ b/lib/util/dlinklist.h
@@ -110,4 +110,50 @@ do { \
} \
} while (0)
+/*
+ The TLIST_*() macros are meant for when you have two list pointers,
+ one pointing at the head of the list and one pointing at the tail
+ of the list. This makes the common case of adding to the end of the
+ list and removing from the front of the list efficient
+
+ TLIST stands for "tailed list"
+
+ Note: When initialising the structure containing your lists, make
+ sure that you set both head and tail to NULL
+
+ Also, do not mix the TLIST_*() macros with the DLIST_* macros!
+*/
+
+/* TLIST_ADD_FRONT adds elements to the front of the list. */
+#define TLIST_ADD_FRONT(listhead, listtail, p) \
+do { \
+ DLIST_ADD(listhead, p); \
+ if (NULL == (listtail)) { \
+ (listtail) = (p); \
+ } \
+} while (0)
+
+/* TLIST_ADD_END adds elements to the end of the list. */
+#define TLIST_ADD_END(listhead, listtail, p) \
+do { \
+ if ((listtail) == NULL) { \
+ DLIST_ADD(listhead, p); \
+ (listtail) = (listhead); \
+ } else { \
+ (listtail)->next = (p); \
+ (p)->prev = (listtail); \
+ (p)->next = NULL; \
+ (listtail) = (p); \
+ } \
+} while (0)
+
+/* TLIST_REMOVE removes an element from the list */
+#define TLIST_REMOVE(listhead, listtail, p) \
+do { \
+ if ((p) == (listtail)) { \
+ (listtail) = (p)->prev; \
+ } \
+ DLIST_REMOVE(listhead, p); \
+} while (0)
+
#endif /* _DLINKLIST_H */
diff --git a/server/ctdb_daemon.c b/server/ctdb_daemon.c
index e96b369..1f7efee 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -100,8 +100,9 @@ static int daemon_queue_send(struct ctdb_client *client, struct ctdb_req_header
client->ctdb->statistics.client_packets_sent++;
if (hdr->operation == CTDB_REQ_MESSAGE) {
if (ctdb_queue_length(client->queue) > client->ctdb->tunable.max_queue_depth_drop_msg) {
- DEBUG(DEBUG_ERR,("Drop CTDB_REQ_MESSAGE to client. Queue full.\n"));
- return 0;
+ DEBUG(DEBUG_ERR,("CTDB_REQ_MESSAGE queue full - killing client connection.\n"));
+ talloc_free(client);
+ return -1;
}
}
return ctdb_queue_send(client->queue, (uint8_t *)hdr, hdr->length);
@@ -280,6 +281,10 @@ static void daemon_call_from_client_callback(struct ctdb_call_state *state)
memcpy(&r->data[0], dstate->call->reply_data.dptr, r->datalen);
res = daemon_queue_send(client, &r->hdr);
+ if (res == -1) {
+ /* client is dead - return immediately */
+ return;
+ }
if (res != 0) {
DEBUG(DEBUG_ERR, (__location__ " Failed to queue packet from daemon to client\n"));
}
@@ -884,6 +889,7 @@ static void daemon_control_callback(struct ctdb_context *ctdb,
struct ctdb_client *client = state->client;
struct ctdb_reply_control *r;
size_t len;
+ int ret;
/* construct a message to send to the client containing the data */
len = offsetof(struct ctdb_reply_control, data) + data.dsize;
@@ -904,9 +910,10 @@ static void daemon_control_callback(struct ctdb_context *ctdb,
memcpy(&r->data[r->datalen], errormsg, r->errorlen);
}
- daemon_queue_send(client, &r->hdr);
-
- talloc_free(state);
+ ret = daemon_queue_send(client, &r->hdr);
+ if (ret != -1) {
+ talloc_free(state);
+ }
}
/*
diff --git a/server/ctdb_tunables.c b/server/ctdb_tunables.c
index e75dcbd..cca270b 100644
--- a/server/ctdb_tunables.c
+++ b/server/ctdb_tunables.c
@@ -62,7 +62,7 @@ static const struct {
{ "VacuumLimit", 5000, offsetof(struct ctdb_tunable, vacuum_limit) },
{ "VacuumMinInterval", 60, offsetof(struct ctdb_tunable, vacuum_min_interval) },
{ "VacuumMaxInterval", 600, offsetof(struct ctdb_tunable, vacuum_max_interval) },
- { "MaxQueueDropMsg", 1000, offsetof(struct ctdb_tunable, max_queue_depth_drop_msg) },
+ { "MaxQueueDropMsg", 1000000, offsetof(struct ctdb_tunable, max_queue_depth_drop_msg) },
{ "UseStatusEvents", 0, offsetof(struct ctdb_tunable, use_status_events_for_monitoring) },
{ "AllowUnhealthyDBRead", 0, offsetof(struct ctdb_tunable, allow_unhealthy_db_read) }
};
--
CTDB repository
More information about the samba-cvs
mailing list