From: Greg Farnum Date: Tue, 22 Jul 2014 23:57:00 +0000 (-0700) Subject: OSD: introduce require_up_osd_peer() function for gating replica ops X-Git-Tag: v0.80.6~83 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8d395f1cbbc63f4cd5d166fd0a667938c83f303c;p=ceph.git OSD: introduce require_up_osd_peer() function for gating replica ops 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 (cherry picked from commit ccd0eec50103b919b3eb6eea96f7dc6438520ed3) --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 5c8f0d68b833..3ccedcb3e837 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -6137,6 +6137,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(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. @@ -7555,7 +7585,7 @@ void OSD::handle_replica_op(OpRequestRef op) return; } - if (!require_osd_peer(op)) + if (!require_up_osd_peer(op, osdmap, m->map_epoch)) return; // must be a rep op. diff --git a/src/osd/OSD.h b/src/osd/OSD.h index ae8d74edd92f..080be8c13f4e 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -1514,6 +1514,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);