diff options
author | Sage Weil <sage@inktank.com> | 2013-07-16 10:09:02 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-07-17 14:34:40 -0700 |
commit | 9f1c27261811733f40acf759a72958c3689c8516 (patch) | |
tree | b4ba7f4c4ea4f0a500d7caa763b870ddf7f59bc4 | |
parent | 579d858aabbe5df88543d096ef4dbddcfc023cca (diff) | |
download | ceph-9f1c27261811733f40acf759a72958c3689c8516.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>
-rw-r--r-- | src/msg/Pipe.cc | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/src/msg/Pipe.cc b/src/msg/Pipe.cc index d45666c21c6..571c3fa3233 100644 --- a/src/msg/Pipe.cc +++ b/src/msg/Pipe.cc @@ -1124,6 +1124,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(); @@ -1135,6 +1137,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); } /* |