]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
msgr: close get_connection() race
authorSage Weil <sage@inktank.com>
Thu, 19 Jul 2012 16:47:52 +0000 (09:47 -0700)
committerSage Weil <sage@inktank.com>
Sat, 21 Jul 2012 01:36:33 +0000 (18:36 -0700)
This could null deref if the Pipe is registered but failed.

We need to loop here because the Pipe vs Connection stuff sucks; hopefully
this gets fixed up soonish.

Signed-off-by: Sage Weil <sage@inktank.com>
src/msg/SimpleMessenger.cc

index e4fbb487451f9f038aacccd93ddcf75c3e12a921..75fecb5714fa26f3ba4c3932026d877b7e3a03ca 100644 (file)
@@ -355,22 +355,29 @@ Connection *SimpleMessenger::get_connection(const entity_inst_t& dest)
   if (my_inst.addr == dest.addr) {
     // local
     return (Connection *)local_connection->get();
-  } else {
-    // remote
+  }
+
+  // remote
+  while (true) {
     Pipe *pipe = NULL;
     hash_map<entity_addr_t, Pipe*>::iterator p = rank_pipe.find(dest.addr);
     if (p != rank_pipe.end()) {
       pipe = p->second;
-    }
-    if (!pipe) {
+      ldout(cct, 10) << "get_connection " << dest << " existing " << pipe << dendl;
+    } else {
       pipe = connect_rank(dest.addr, dest.name.type(), NULL);
+      ldout(cct, 10) << "get_connection " << dest << " new " << pipe << dendl;
     }
-    return (Connection *)pipe->connection_state->get();
+    Mutex::Locker l(pipe->pipe_lock);
+    if (pipe->connection_state)
+      return (Connection *)pipe->connection_state->get();
+    // we failed too quickly!  retry.  FIXME.
   }
 }
 
 
-void SimpleMessenger::submit_message(Message *m, Connection *con, const entity_addr_t& dest_addr, int dest_type, bool lazy)
+void SimpleMessenger::submit_message(Message *m, Connection *con,
+                                    const entity_addr_t& dest_addr, int dest_type, bool lazy)
 {
   // existing connection?
   if (con) {