summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-07-16 10:09:02 -0700
committerSage Weil <sage@inktank.com>2013-07-24 16:20:36 -0700
commitae85a0a101d624363fe761c06ecd52d3d38ba4a2 (patch)
tree05684e557787f713fbf9b514256891807914945e
parent21e27262edc6f5f090ea8915517ee867e30b9066 (diff)
downloadceph-ae85a0a101d624363fe761c06ecd52d3d38ba4a2.tar.gz
msg/Pipe: avoid creating empty out_q entry
We need to maintain the invariant that all sub queues in out_q are never empty. Fix discard_requeued_up_to() to avoid creating an entry unless we know it is already present. This bug leads to an incorrect reconnect attempt when - we accept a pipe (lossless peer) - they send some stuff, maybe - fault - we initiate reconnect, even tho we have nothing queued In particular, we shouldn't reconnect because we aren't checking for resets, and the fact that our out_seq is 0 while the peer's might be something else entirely will trigger asserts later. This fixes at least one source of #5626, and possibly #5517. Backport: cuttlefish Signed-off-by: Sage Weil <sage@inktank.com> (cherry picked from commit 9f1c27261811733f40acf759a72958c3689c8516)
-rw-r--r--src/msg/Pipe.cc4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/msg/Pipe.cc b/src/msg/Pipe.cc
index 3e2894bdf85..ad7ee49d2fb 100644
--- a/src/msg/Pipe.cc
+++ b/src/msg/Pipe.cc
@@ -1118,6 +1118,8 @@ void Pipe::requeue_sent()
void Pipe::discard_requeued_up_to(uint64_t seq)
{
ldout(msgr->cct, 10) << "discard_requeued_up_to " << seq << dendl;
+ if (out_q.count(CEPH_MSG_PRIO_HIGHEST) == 0)
+ return;
list<Message*>& rq = out_q[CEPH_MSG_PRIO_HIGHEST];
while (!rq.empty()) {
Message *m = rq.front();
@@ -1129,6 +1131,8 @@ void Pipe::discard_requeued_up_to(uint64_t seq)
rq.pop_front();
out_seq++;
}
+ if (rq.empty())
+ out_q.erase(CEPH_MSG_PRIO_HIGHEST);
}
/*