]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/osd: implement MOSDPGBackfill.
authorRadoslaw Zarzynski <rzarzyns@redhat.com>
Mon, 18 May 2020 13:24:28 +0000 (15:24 +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/osd.cc
src/crimson/osd/pg.h
src/crimson/osd/pg_recovery.cc
src/crimson/osd/pg_recovery_listener.h
src/crimson/osd/recovery_backend.cc
src/crimson/osd/recovery_backend.h

index 5725ad7b46d9d3c58e142b75740a27e6b47fa5f3..e4fb16cc9f11ec696afb353eff44c024d2a33e1d 100644 (file)
@@ -620,6 +620,8 @@ seastar::future<> OSD::ms_dispatch(crimson::net::Connection* conn, MessageRef m)
     case MSG_OSD_PG_RECOVERY_DELETE_REPLY:
       [[fallthrough]];
     case MSG_OSD_PG_SCAN:
+      [[fallthrough]];
+    case MSG_OSD_PG_BACKFILL:
       return handle_recovery_subreq(conn, boost::static_pointer_cast<MOSDFastDispatchOp>(m));
     case MSG_OSD_PG_LEASE:
       [[fallthrough]];
index 58e17daeaf80e47d842dc4c6a63511af69333edb..19d9d4e876a1a6131fc183b7dfc7d04d1d452df4 100644 (file)
@@ -116,7 +116,7 @@ public:
     return peering_state.get_min_last_complete_ondisk();
   }
 
-  const pg_info_t& get_info() const {
+  const pg_info_t& get_info() const final {
     return peering_state.get_info();
   }
 
index ca5aa1c0ce58f7ce766b00f8e3cf205cb50d833f..7320fed5a26a4d62b66fb17b3e86fbb6a7bd7bf2 100644 (file)
@@ -477,7 +477,35 @@ void PGRecovery::enqueue_drop(
 void PGRecovery::update_peers_last_backfill(
   const hobject_t& new_last_backfill)
 {
-  ceph_abort_msg("Not implemented");
+  logger().debug("{}: new_last_backfill={}",
+                 __func__, new_last_backfill);
+  // If new_last_backfill == MAX, then we will send OP_BACKFILL_FINISH to
+  // all the backfill targets.  Otherwise, we will move last_backfill up on
+  // those targets need it and send OP_BACKFILL_PROGRESS to them.
+  for (const auto& bt : pg->get_peering_state().get_backfill_targets()) {
+    if (const pg_info_t& pinfo = pg->get_peering_state().get_peer_info(bt);
+        new_last_backfill > pinfo.last_backfill) {
+      pg->get_peering_state().update_peer_last_backfill(bt, new_last_backfill);
+      auto m = make_message<MOSDPGBackfill>(
+        pinfo.last_backfill.is_max() ? MOSDPGBackfill::OP_BACKFILL_FINISH
+                                     : MOSDPGBackfill::OP_BACKFILL_PROGRESS,
+        pg->get_osdmap_epoch(),
+        pg->get_last_peering_reset(),
+        spg_t(pg->get_pgid().pgid, bt.shard));
+      // Use default priority here, must match sub_op priority
+      // TODO: if pinfo.last_backfill.is_max(), then
+      //       start_recovery_op(hobject_t::get_max());
+      m->last_backfill = pinfo.last_backfill;
+      m->stats = pinfo.stats;
+      std::ignore = pg->get_shard_services().send_to_osd(
+        bt.osd, std::move(m), pg->get_osdmap_epoch());
+      logger().info("{}: peer {} num_objects now {} / {}",
+                    __func__,
+                    bt,
+                    pinfo.stats.stats.sum.num_objects,
+                    pg->get_info().stats.stats.sum.num_objects);
+    }
+  }
 }
 
 bool PGRecovery::budget_available() const
@@ -488,13 +516,14 @@ bool PGRecovery::budget_available() const
 
 void PGRecovery::backfilled()
 {
-  shard_services.start_operation<LocalPeeringEvent>(
-    this,
-    shard_services,
-    pg_whoami,
-    pgid,
-    get_osdmap_epoch(),
-    get_osdmap_epoch(),
+  using LocalPeeringEvent = crimson::osd::LocalPeeringEvent;
+  std::ignore = pg->get_shard_services().start_operation<LocalPeeringEvent>(
+    static_cast<crimson::osd::PG*>(pg),
+    pg->get_shard_services(),
+    pg->get_pg_whoami(),
+    pg->get_pgid(),
+    pg->get_osdmap_epoch(),
+    pg->get_osdmap_epoch(),
     PeeringState::Backfilled{});
 }
 
index 3c8d3b66a852841dcee5461f2b1177e66fdac6c5..2ed08e91d773e04c2f518383653abbc708b5a775 100644 (file)
@@ -33,5 +33,6 @@ public:
   virtual bool has_reset_since(epoch_t) const = 0;
   virtual std::vector<pg_shard_t> get_replica_recovery_order() const = 0;
   virtual epoch_t get_last_peering_reset() const = 0;
+  virtual const pg_info_t& get_info() const= 0;
   virtual seastar::future<> stop() = 0;
 };
index e81e38668ccfffcad037589a921f0a49a58c56a5..cd8173fd519fa71b328059a83643ae34ad1927b4 100644 (file)
@@ -60,6 +60,78 @@ void RecoveryBackend::WaitForObjectRecovery::stop() {
   }
 }
 
+void RecoveryBackend::handle_backfill_finish(
+  MOSDPGBackfill& m)
+{
+  logger().debug("{}", __func__);
+  ceph_assert(!pg.is_primary());
+  ceph_assert(crimson::common::local_conf()->osd_kill_backfill_at != 1);
+  auto reply = make_message<MOSDPGBackfill>(
+    MOSDPGBackfill::OP_BACKFILL_FINISH_ACK,
+    pg.get_osdmap_epoch(),
+    m.query_epoch,
+    spg_t(pg.get_pgid().pgid, pg.get_primary().shard));
+  reply->set_priority(pg.get_recovery_op_priority());
+  std::ignore = m.get_connection()->send(std::move(reply));
+  shard_services.start_operation<crimson::osd::LocalPeeringEvent>(
+    static_cast<crimson::osd::PG*>(&pg),
+    shard_services,
+    pg.get_pg_whoami(),
+    pg.get_pgid(),
+    pg.get_osdmap_epoch(),
+    pg.get_osdmap_epoch(),
+    RecoveryDone{});
+}
+
+seastar::future<> RecoveryBackend::handle_backfill_progress(
+  MOSDPGBackfill& m)
+{
+  logger().debug("{}", __func__);
+  ceph_assert(!pg.is_primary());
+  ceph_assert(crimson::common::local_conf()->osd_kill_backfill_at != 2);
+
+  ObjectStore::Transaction t;
+  pg.get_peering_state().update_backfill_progress(
+    m.last_backfill,
+    m.stats,
+    m.op == MOSDPGBackfill::OP_BACKFILL_PROGRESS,
+    t);
+  return shard_services.get_store().do_transaction(
+    pg.get_collection_ref(), std::move(t)
+  ).handle_exception([] (auto) {
+    ceph_assert("this transaction shall not fail" == nullptr);
+  });
+}
+
+seastar::future<> RecoveryBackend::handle_backfill_finish_ack(
+  MOSDPGBackfill& m)
+{
+  logger().debug("{}", __func__);
+  ceph_assert(pg.is_primary());
+  ceph_assert(crimson::common::local_conf()->osd_kill_backfill_at != 3);
+  // TODO:
+  // finish_recovery_op(hobject_t::get_max());
+  return seastar::now();
+}
+
+seastar::future<> RecoveryBackend::handle_backfill(
+  MOSDPGBackfill& m)
+{
+  logger().debug("{}", __func__);
+  switch (m.op) {
+    case MOSDPGBackfill::OP_BACKFILL_FINISH:
+      handle_backfill_finish(m);
+      [[fallthrough]];
+    case MOSDPGBackfill::OP_BACKFILL_PROGRESS:
+      return handle_backfill_progress(m);
+    case MOSDPGBackfill::OP_BACKFILL_FINISH_ACK:
+      return handle_backfill_finish_ack(m);
+    default:
+      ceph_assert("unknown op type for pg backfill");
+      return seastar::now();
+  }
+}
+
 seastar::future<BackfillInterval> RecoveryBackend::scan_for_backfill(
   const hobject_t& start,
   [[maybe_unused]] const std::int64_t min,
@@ -196,6 +268,8 @@ seastar::future<> RecoveryBackend::handle_recovery_op(
   Ref<MOSDFastDispatchOp> m)
 {
   switch (m->get_header().type) {
+  case MSG_OSD_PG_BACKFILL:
+    return handle_backfill(*boost::static_pointer_cast<MOSDPGBackfill>(m));
   case MSG_OSD_PG_SCAN:
     return handle_scan(*boost::static_pointer_cast<MOSDPGScan>(m));
   default:
index 771924d2d0119947501bfddddd475aea2292e76d..49396ad8ed1001e7e4641d893216c842db49885d 100644 (file)
@@ -11,6 +11,7 @@
 #include "crimson/osd/object_context.h"
 #include "crimson/osd/shard_services.h"
 
+#include "messages/MOSDPGBackfill.h"
 #include "messages/MOSDPGScan.h"
 #include "osd/recovery_types.h"
 #include "osd/osd_types.h"
@@ -22,6 +23,14 @@ namespace crimson::osd{
 class PGBackend;
 
 class RecoveryBackend {
+  void handle_backfill_finish(
+    MOSDPGBackfill& m);
+  seastar::future<> handle_backfill_progress(
+    MOSDPGBackfill& m);
+  seastar::future<> handle_backfill_finish_ack(
+    MOSDPGBackfill& m);
+  seastar::future<> handle_backfill(MOSDPGBackfill& m);
+
   seastar::future<> handle_scan_get_digest(
     MOSDPGScan& m);
   seastar::future<> handle_scan_digest(