seastar::future<bool> BackfillRecovery::do_recovery()
{
- if (pg->has_reset_since(epoch_started))
+ logger().debug("{}", __func__);
+
+ if (pg->has_reset_since(epoch_started)) {
+ logger().debug("{}: pg got reset since epoch_started={}",
+ __func__, epoch_started);
return seastar::make_ready_future<bool>(false);
- // FIXME: blocking future, limits
- pg->get_recovery_handler()->dispatch_backfill_event(std::move(evt));
- return seastar::make_ready_future<bool>(false);
+ }
+ // TODO: limits
+ return with_blocking_future(
+ // process_event() of our boost::statechart machine is non-reentrant.
+ // with the backfill_pipeline we protect it from a second entry from
+ // the implementation of BackfillListener.
+ handle.enter(pg->backfill_pipeline.process)
+ ).then([this] {
+ pg->get_recovery_handler()->dispatch_backfill_event(std::move(evt));
+ return seastar::make_ready_future<bool>(false);
+ });
}
} // namespace crimson::osd
class BackfillRecovery final : public BackgroundRecovery {
boost::intrusive_ptr<const boost::statechart::event_base> evt;
+ OrderedPipelinePhase::Handle handle;
seastar::future<bool> do_recovery() override;
public:
+ class BackfillRecoveryPipeline {
+ OrderedPipelinePhase process = {
+ "BackfillRecovery::PGPipeline::process"
+ };
+ friend class BackfillRecovery;
+ };
+
template <class EventT>
BackfillRecovery(
Ref<PG> pg,
friend class PGAdvanceMap;
friend class PeeringEvent;
friend class RepRequest;
+ friend class BackfillRecovery;
friend struct BackfillState::PGFacade;
private:
seastar::future<bool> find_unfound() {
const set<pg_shard_t> &get_actingset() const {
return peering_state.get_actingset();
}
+
+private:
+ BackfillRecovery::BackfillRecoveryPipeline backfill_pipeline;
};
std::ostream& operator<<(std::ostream&, const PG& pg);