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)
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();
rq.pop_front();
out_seq++;
}
+ if (rq.empty())
+ out_q.erase(CEPH_MSG_PRIO_HIGHEST);
}
/*