mirror of
https://github.com/ceph/ceph
synced 2025-04-01 23:02:17 +00:00
msgr: do not reopen failed lossy Connections
There was a race where: - sending stuff to a lossy Connection - it fails, and queues itself for reap, queues a RESET event - reaper clears the Pipe - some thread queues new messages and the Pipe is reopened, messages sent - RESET event delivered to dispatch, connection is closed and reopened. The result was that messages got sent to the OSD out of order during the window between the fault() and ms_handle_reset() getting called. This will prevent that. Signed-off-by: Sage Weil <sage@inktank.com>
This commit is contained in:
parent
9a4e702795
commit
2e67b7a383
@ -199,6 +199,18 @@ public:
|
||||
return pipe->get();
|
||||
return NULL;
|
||||
}
|
||||
bool try_get_pipe(RefCountedObject **p) {
|
||||
Mutex::Locker l(lock);
|
||||
if (failed) {
|
||||
*p = NULL;
|
||||
} else {
|
||||
if (pipe)
|
||||
*p = pipe->get();
|
||||
else
|
||||
*p = NULL;
|
||||
}
|
||||
return !failed;
|
||||
}
|
||||
void clear_pipe(RefCountedObject *old_p) {
|
||||
if (old_p == pipe) {
|
||||
Mutex::Locker l(lock);
|
||||
|
@ -382,8 +382,12 @@ void SimpleMessenger::submit_message(Message *m, Connection *con, const entity_a
|
||||
{
|
||||
Pipe *pipe = NULL;
|
||||
if (con) {
|
||||
pipe = con ? (Pipe *)con->pipe : NULL;
|
||||
// we don't want to deal with ref-counting here, so we don't use get_pipe()
|
||||
bool ok = con->try_get_pipe((RefCountedObject**)&pipe);
|
||||
if (!ok) {
|
||||
ldout(cct,0) << "submit_message " << *m << " on failed lossy con, dropping message " << m << dendl;
|
||||
m->put();
|
||||
return;
|
||||
}
|
||||
con->get();
|
||||
}
|
||||
|
||||
@ -395,23 +399,10 @@ void SimpleMessenger::submit_message(Message *m, Connection *con, const entity_a
|
||||
} else {
|
||||
// remote pipe.
|
||||
if (pipe) {
|
||||
pipe->pipe_lock.Lock();
|
||||
if (pipe->state == Pipe::STATE_CLOSED) {
|
||||
ldout(cct,0) << "submit_message " << *m << " remote, " << dest_addr << ", ignoring closed pipe, dropping message " << m << dendl;
|
||||
pipe->unregister_pipe();
|
||||
pipe->pipe_lock.Unlock();
|
||||
pipe = 0;
|
||||
assert(con);
|
||||
con->put();
|
||||
return;
|
||||
} else {
|
||||
ldout(cct,20) << "submit_message " << *m << " remote, " << dest_addr << ", have pipe." << dendl;
|
||||
|
||||
pipe->_send(m);
|
||||
pipe->pipe_lock.Unlock();
|
||||
}
|
||||
}
|
||||
if (!pipe) {
|
||||
ldout(cct,20) << "submit_message " << *m << " remote, " << dest_addr << ", have pipe." << dendl;
|
||||
pipe->send(m);
|
||||
pipe->put();
|
||||
} else {
|
||||
const Policy& policy = get_policy(dest_type);
|
||||
if (policy.server) {
|
||||
ldout(cct,20) << "submit_message " << *m << " remote, " << dest_addr << ", lossy server for target type "
|
||||
|
Loading…
Reference in New Issue
Block a user