From: Sage Weil Date: Thu, 26 Oct 2017 03:09:16 +0000 (-0500) Subject: osd/PG: allow preemption of remote recovery reservation too X-Git-Tag: v13.0.1~375^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=df783919fe10ea79a831a44de3334f79cc78486d;p=ceph.git osd/PG: allow preemption of remote recovery reservation too We did backfill but not recovery. This one is easier because we already have a DeferRecovery event we can queue that does everything. Condition on the RECOVERY_RESERVATION_2 feature. Signed-off-by: Sage Weil --- diff --git a/src/messages/MRecoveryReserve.h b/src/messages/MRecoveryReserve.h index bd7a851bc8b3..51d746f01a84 100644 --- a/src/messages/MRecoveryReserve.h +++ b/src/messages/MRecoveryReserve.h @@ -27,6 +27,7 @@ public: REQUEST = 0, // primary->replica: please reserve slot GRANT = 1, // replica->primary: ok, i reserved it RELEASE = 2, // primary->replica: release the slot i reserved before + REVOKE = 3, // replica->primary: i'm taking back the slot i gave you }; uint32_t type; uint32_t priority = 0; @@ -58,6 +59,9 @@ public: case RELEASE: out << " RELEASE"; break; + case REVOKE: + out << " REVOKE"; + break; } out << " e" << query_epoch << ")"; if (type == REQUEST) out << ", prio: " << priority; diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 188175ccc065..03d0236df276 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -8623,6 +8623,12 @@ void OSD::handle_pg_recovery_reserve(OpRequestRef op) m->query_epoch, m->query_epoch, PG::RecoveryDone())); + } else if (m->type == MRecoveryReserve::REVOKE) { + evt = PG::CephPeeringEvtRef( + new PG::CephPeeringEvt( + m->query_epoch, + m->query_epoch, + PG::DeferRecovery(0.0))); } else { ceph_abort(); } diff --git a/src/osd/PG.cc b/src/osd/PG.cc index 33a8a780d847..f5fea98dbd93 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -6777,17 +6777,26 @@ boost::statechart::result PG::RecoveryState::RepNotRecovering::react(const RequestRecoveryPrio &evt) { PG *pg = context< RecoveryMachine >().pg; - ostringstream ss; // fall back to a local reckoning of priority of primary doesn't pass one // (pre-mimic compat) int prio = evt.priority ? evt.priority : pg->get_recovery_priority(); + + Context *preempt = nullptr; + if (HAVE_FEATURE(pg->upacting_features, RECOVERY_RESERVATION_2)) { + // older peers can't handle this + preempt = new QueuePeeringEvt( + pg, pg->get_osdmap()->get_epoch(), + RemoteRecoveryPreempted()); + } + pg->osd->remote_reserver.request_reservation( pg->info.pgid, new QueuePeeringEvt( pg, pg->get_osdmap()->get_epoch(), RemoteRecoveryReserved()), - prio); + prio, + preempt); return transit(); } @@ -6865,6 +6874,20 @@ PG::RecoveryState::RepRecovering::RepRecovering(my_context ctx) context< RecoveryMachine >().log_enter(state_name); } +boost::statechart::result +PG::RecoveryState::RepRecovering::react(const RemoteRecoveryPreempted &) +{ + PG *pg = context< RecoveryMachine >().pg; + pg->osd->send_message_osd_cluster( + pg->primary.osd, + new MRecoveryReserve( + MRecoveryReserve::REVOKE, + spg_t(pg->info.pgid.pgid, pg->primary.shard), + pg->get_osdmap()->get_epoch()), + pg->get_osdmap()->get_epoch()); + return discard_event(); +} + boost::statechart::result PG::RecoveryState::RepRecovering::react(const BackfillTooFull &) { diff --git a/src/osd/PG.h b/src/osd/PG.h index 0ddb648cb40e..9f76f2d99f2e 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -1859,6 +1859,7 @@ protected: TrivialEvent(RequestBackfill) TrivialEvent(RecoveryDone) protected: + TrivialEvent(RemoteRecoveryPreempted) TrivialEvent(RemoteBackfillPreempted) TrivialEvent(BackfillTooFull) TrivialEvent(RecoveryTooFull) @@ -2295,9 +2296,11 @@ protected: boost::statechart::transition< RemoteReservationRejected, RepNotRecovering >, boost::statechart::transition< RemoteReservationCanceled, RepNotRecovering >, boost::statechart::custom_reaction< BackfillTooFull >, + boost::statechart::custom_reaction< RemoteRecoveryPreempted >, boost::statechart::custom_reaction< RemoteBackfillPreempted > > reactions; explicit RepRecovering(my_context ctx); + boost::statechart::result react(const RemoteRecoveryPreempted &evt); boost::statechart::result react(const BackfillTooFull &evt); boost::statechart::result react(const RemoteBackfillPreempted &evt); void exit();