if (!more && pg->have_unfound()) {
pg->discover_all_missing(*rctx.query_map);
if (rctx.query_map->empty()) {
- dout(10) << __func__ << ": no luck, giving up on this pg for now" << dendl;
+ string action;
if (pg->state_test(PG_STATE_BACKFILL)) {
auto evt = PG::CephPeeringEvtRef(new PG::CephPeeringEvt(
queued,
queued,
PG::CancelBackfill()));
pg->queue_peering_event(evt);
- }
+ action = "in backfill";
+ } else if (pg->state_test(PG_STATE_RECOVERING)) {
+ auto evt = PG::CephPeeringEvtRef(new PG::CephPeeringEvt(
+ queued,
+ queued,
+ PG::CancelRecovery()));
+ pg->queue_peering_event(evt);
+ action = "in recovery";
+ } else {
+ action = "already out of recovery/backfill";
+ }
+ dout(10) << __func__ << ": no luck, giving up on this pg for now (" << action << ")" << dendl;
} else {
- dout(10) << __func__ << ": no luck, giving up on this pg for now" << dendl;
+ dout(10) << __func__ << ": no luck, giving up on this pg for now (queue_recovery)" << dendl;
pg->queue_recovery();
}
}
pg->queue_recovery();
}
-void PG::RecoveryState::Recovering::release_reservations()
+void PG::RecoveryState::Recovering::release_reservations(bool cancel)
{
PG *pg = context< RecoveryMachine >().pg;
- assert(!pg->pg_log.get_missing().have_missing());
+ assert(cancel || !pg->pg_log.get_missing().have_missing());
// release remote reservations
for (set<pg_shard_t>::const_iterator i =
return transit<WaitRemoteBackfillReserved>();
}
+boost::statechart::result
+PG::RecoveryState::Recovering::react(const CancelRecovery &evt)
+{
+ PG *pg = context< RecoveryMachine >().pg;
+ pg->state_clear(PG_STATE_RECOVERING);
+ pg->osd->local_reserver.cancel_reservation(pg->info.pgid);
+ release_reservations(true);
+ pg->schedule_recovery_full_retry();
+ return transit<NotRecovering>();
+}
+
void PG::RecoveryState::Recovering::exit()
{
context< RecoveryMachine >().log_exit(state_name, enter_time);
TrivialEvent(RecoveryDone)
TrivialEvent(BackfillTooFull)
TrivialEvent(RecoveryTooFull)
+ TrivialEvent(CancelRecovery)
TrivialEvent(AllReplicasRecovered)
TrivialEvent(DoRecovery)
struct Recovering : boost::statechart::state< Recovering, Active >, NamedState {
typedef boost::mpl::list <
boost::statechart::custom_reaction< AllReplicasRecovered >,
+ boost::statechart::custom_reaction< CancelRecovery >,
boost::statechart::custom_reaction< RequestBackfill >
> reactions;
explicit Recovering(my_context ctx);
void exit();
- void release_reservations();
+ void release_reservations(bool cancel = false);
boost::statechart::result react(const AllReplicasRecovered &evt);
+ boost::statechart::result react(const CancelRecovery& evt);
boost::statechart::result react(const RequestBackfill &evt);
};