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;
case RELEASE:
out << " RELEASE";
break;
+ case REVOKE:
+ out << " REVOKE";
+ break;
}
out << " e" << query_epoch << ")";
if (type == REQUEST) out << ", prio: " << priority;
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>();
}
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 &)
{
TrivialEvent(RequestBackfill)
TrivialEvent(RecoveryDone)
protected:
+ TrivialEvent(RemoteRecoveryPreempted)
TrivialEvent(RemoteBackfillPreempted)
TrivialEvent(BackfillTooFull)
TrivialEvent(RecoveryTooFull)
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();