]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/PG: allow preemption of remote recovery reservation too
authorSage Weil <sage@redhat.com>
Thu, 26 Oct 2017 03:09:16 +0000 (22:09 -0500)
committerSage Weil <sage@redhat.com>
Fri, 27 Oct 2017 13:07:08 +0000 (08:07 -0500)
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 <sage@redhat.com>
src/messages/MRecoveryReserve.h
src/osd/OSD.cc
src/osd/PG.cc
src/osd/PG.h

index bd7a851bc8b352b42600710475c98bae8531c7cc..51d746f01a84a882ee9606f586f681b1d3365a25 100644 (file)
@@ -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;
index 188175ccc0653ac513a4c6c89fc7e9a1744ba602..03d0236df2761a1a7a42ba1e6ddd6ed98d8d8e02 100644 (file)
@@ -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();
   }
index 33a8a780d847b5d303ecdf431f359708115d96bc..f5fea98dbd93c6eabd1be3dcb481103c764185d1 100644 (file)
@@ -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<RemoteRecoveryPreempted>(
+      pg, pg->get_osdmap()->get_epoch(),
+      RemoteRecoveryPreempted());
+  }
+
   pg->osd->remote_reserver.request_reservation(
     pg->info.pgid,
     new QueuePeeringEvt<RemoteRecoveryReserved>(
       pg, pg->get_osdmap()->get_epoch(),
       RemoteRecoveryReserved()),
-    prio);
+    prio,
+    preempt);
   return transit<RepWaitRecoveryReserved>();
 }
 
@@ -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 &)
 {
index 0ddb648cb40e653768e877a8ab6cdd96f1a4be3f..9f76f2d99f2eb2f64059c0248d66cb42899a8a76 100644 (file)
@@ -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();