]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
OSD: introduce require_up_osd_peer() function for gating replica ops
authorGreg Farnum <greg@inktank.com>
Tue, 22 Jul 2014 23:57:00 +0000 (16:57 -0700)
committerSage Weil <sage@redhat.com>
Sat, 9 Aug 2014 05:59:09 +0000 (22:59 -0700)
This checks both that a Message originates from an OSD, and that the OSD
is up in the given map epoch.
We use it in handle_replica_op so that we don't inadvertently add operations
from down peers, who might or might not know it.

Signed-off-by: Greg Farnum <greg@inktank.com>
(cherry picked from commit ccd0eec50103b919b3eb6eea96f7dc6438520ed3)

src/osd/OSD.cc
src/osd/OSD.h

index 307def8f5f78a6c4ff3f527902ea71e1b0811b90..d9213b5a5eb33dc36632468d8c7d3dc1d80e2e58 100644 (file)
@@ -6678,6 +6678,36 @@ bool OSD::require_osd_peer(OpRequestRef op)
   return true;
 }
 
+bool OSD::require_up_osd_peer(OpRequestRef& op, OSDMapRef& map,
+                              epoch_t their_epoch)
+{
+  int from = op->get_req()->get_source().num();
+  if (!require_osd_peer(op)) {
+    return false;
+  } else if (map->get_epoch() >= their_epoch &&
+      (!map->have_inst(from) ||
+      map->get_cluster_addr(from) != op->get_req()->get_source_inst().addr)) {
+    dout(0) << "require_osd_peer_up received from non-up osd "
+            << op->get_req()->get_connection()->get_peer_addr()
+            << " " << *op->get_req() << dendl;
+
+    ConnectionRef con = op->get_req()->get_connection();
+    cluster_messenger->mark_down(con.get());
+    Session *s = static_cast<Session*>(con->get_priv());
+    if (s) {
+      s->session_dispatch_lock.Lock();
+      clear_session_waiting_on_map(s);
+      con->set_priv(NULL);   // break ref <-> session cycle, if any
+      s->session_dispatch_lock.Unlock();
+      s->put();
+    }
+
+    return false;
+  }
+
+  return true;
+}
+
 /*
  * require that we have same (or newer) map, and that
  * the source is the pg primary.
@@ -8038,7 +8068,7 @@ void OSD::handle_replica_op(OpRequestRef& op, OSDMapRef& osdmap)
     return;
   }
 
-  if (!require_osd_peer(op))
+  if (!require_up_osd_peer(op, osdmap, m->map_epoch))
     return;
 
   // must be a rep op.
index cfbfd120386c883e8cd5a6f1c075bd0c27a7ae4b..124b3d77dd8ad3c25fba216f58964e47fcb34ba2 100644 (file)
@@ -1810,6 +1810,8 @@ protected:
 
   bool require_mon_peer(Message *m);
   bool require_osd_peer(OpRequestRef op);
+  bool require_up_osd_peer(OpRequestRef& Op, OSDMapRef& map,
+                           epoch_t their_epoch);
 
   bool require_same_or_newer_map(OpRequestRef op, epoch_t e);