]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: synchronize BackfillRecovery with PeeringEvent.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Thu, 21 May 2020 18:26:07 +0000 (20:26 +0200)
committerRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 13 Jul 2020 14:25:31 +0000 (16:25 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzyns@redhat.com>
src/crimson/osd/backfill_facades.h
src/crimson/osd/backfill_state.cc
src/crimson/osd/osd_operations/background_recovery.cc
src/crimson/osd/osd_operations/background_recovery.h
src/crimson/osd/osd_operations/peering_event.cc
src/crimson/osd/pg_recovery.cc

index 645fc898737c445efcd3ffaf8ba027c909723610..d6d6f91e363b79d87f6ae3c8baf31a8e4aa39651 100644 (file)
@@ -42,6 +42,10 @@ struct BackfillState::PeeringFacade {
     return peering_state.update_complete_backfill_object_stats(hoid, stats);
   }
 
+  bool is_backfilling() const {
+    return peering_state.is_backfilling();
+  }
+
   PeeringFacade(PeeringState& peering_state)
     : peering_state(peering_state) {
   }
index 7181e31a3a633b23dd72c587c0fb130416d527e2..44f9fa0177d81892206070befd99492a76bed2a8 100644 (file)
@@ -67,6 +67,7 @@ BackfillState::Initial::react(const BackfillState::Triggered& evt)
   logger().debug("{}: backfill triggered", __func__);
   ceph_assert(backfill_state().last_backfill_started == \
               peering_state().earliest_backfill());
+  ceph_assert(peering_state().is_backfilling());
   // initialize BackfillIntervals
   for (const auto& bt : peering_state().get_backfill_targets()) {
     backfill_state().peer_backfill_info[bt].reset(
index ae7f5c4258b370a18f240db466be90348653176d..40407e708d7de6592dbcb45c2ea06637531ec190 100644 (file)
@@ -108,6 +108,11 @@ seastar::future<bool> PglogBasedRecovery::do_recovery()
       crimson::common::local_conf()->osd_recovery_max_single_start));
 }
 
+BackfillRecovery::BackfillRecoveryPipeline &BackfillRecovery::bp(PG &pg)
+{
+  return pg.backfill_pipeline;
+}
+
 seastar::future<bool> BackfillRecovery::do_recovery()
 {
   logger().debug("{}", __func__);
@@ -122,7 +127,8 @@ seastar::future<bool> BackfillRecovery::do_recovery()
     // 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)
+    // additionally, this stage serves to synchronize with PeeringEvent.
+    handle.enter(bp(*pg).process)
   ).then([this] {
     pg->get_recovery_handler()->dispatch_backfill_event(std::move(evt));
     return seastar::make_ready_future<bool>(false);
index ae439b9300bfa6e4dc2a89c58723e38018c51293..1fa0e1df30e4025a6229f52f5344e1777156e096 100644 (file)
@@ -83,6 +83,7 @@ public:
       "BackfillRecovery::PGPipeline::process"
     };
     friend class BackfillRecovery;
+    friend class PeeringEvent;
   };
 
   template <class EventT>
@@ -91,6 +92,8 @@ public:
     ShardServices &ss,
     epoch_t epoch_started,
     const EventT& evt);
+
+  static BackfillRecoveryPipeline &bp(PG &pg);
 };
 
 template <class EventT>
index a7255bbe7a98862939c6239e0d0120dee8f7cf97..d3c6ccf817f822b993aa34c089b7a91a95833621 100644 (file)
@@ -76,6 +76,11 @@ seastar::future<> PeeringEvent::start()
          pg->osdmap_gate.wait_for_map(evt.get_epoch_sent()));
       }).then([this, pg](auto) {
        return with_blocking_future(handle.enter(pp(*pg).process));
+      }).then([this, pg] {
+        // TODO: likely we should synchronize also with the pg log-based
+        // recovery.
+       return with_blocking_future(
+          handle.enter(BackfillRecovery::bp(*pg).process));
       }).then([this, pg] {
        pg->do_peering_event(evt, ctx);
        handle.exit();
index 4a9ec12a37bfe8083179950c7dbb752054ceda87..6028a457e46bd99d4b735f7c8ddfd80a8db8134a 100644 (file)
@@ -545,5 +545,12 @@ void PGRecovery::on_backfill_reserved()
     std::make_unique<BackfillState::PeeringFacade>(pg->get_peering_state()),
     std::make_unique<BackfillState::PGFacade>(
       *static_cast<crimson::osd::PG*>(pg)));
+  // yes, it's **not** backfilling yet. The PG_STATE_BACKFILLING
+  // will be set after on_backfill_reserved() returns.
+  // Backfill needs to take this into consideration when scheduling
+  // events -- they must be mutually exclusive with PeeringEvent
+  // instances. Otherwise the execution might begin without having
+  // the state updated.
+  ceph_assert(!pg->get_peering_state().is_backfilling());
   start_backfill_recovery(BackfillState::Triggered{});
 }