summaryrefslogtreecommitdiff
path: root/ctdb/common/ctdb_io.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2010-02-04 09:54:06 +1100
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2010-02-04 09:54:06 +1100
commita2857b1504966ccb59e7852016e4008910d691fb (patch)
treedb574c1b850cdaee4e9817f76c9fac44e5e22ad9 /ctdb/common/ctdb_io.c
parent7a5254ae69c946ba6e9c3b1b1efdf1c6c083fe64 (diff)
downloadsamba-a2857b1504966ccb59e7852016e4008910d691fb.tar.gz
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. (This used to be ctdb commit 59ba5d7f80e0465e5076533374fb9ee862ed7bb6)
Diffstat (limited to 'ctdb/common/ctdb_io.c')
-rw-r--r--ctdb/common/ctdb_io.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/ctdb/common/ctdb_io.c b/ctdb/common/ctdb_io.c
index 28830d5f370..47681d2a566 100644
--- a/ctdb/common/ctdb_io.c
+++ b/ctdb/common/ctdb_io.c
@@ -46,6 +46,12 @@ struct ctdb_queue {
struct ctdb_context *ctdb;
struct ctdb_partial partial; /* partial input packet */
struct ctdb_queue_pkt *out_queue;
+ /* This field is used to track the last added item so we
+ can append new items to the end cheaply.
+ This relies of that items are always appended to the tail
+ and that when reamoving items we only remove the head.
+ */
+ struct ctdb_queue_pkt *out_queue_last_added;
uint32_t out_queue_length;
struct fd_event *fde;
int fd;
@@ -294,7 +300,18 @@ 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 *);
+ /* This relies on that when adding items to the queue, we always add
+ them to the tail and that when removing items we only remove
+ the head of queue item.
+ The last_added item thus allows non n^2 behaviour when appending to
+ very long queues.
+ */
+ if (queue->out_queue == NULL) {
+ DLIST_ADD(queue->out_queue, pkt);
+ } else {
+ DLIST_ADD_END(queue->out_queue_last_added, pkt, struct ctdb_queue_pkt *);
+ }
+ queue->out_queue_last_added = pkt;
queue->out_queue_length++;
if (queue->ctdb->tunable.verbose_memory_names != 0) {