]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: handle MOSDScrub2 36370/head
authorKefu Chai <kchai@redhat.com>
Thu, 30 Jul 2020 11:45:23 +0000 (19:45 +0800)
committerKefu Chai <kchai@redhat.com>
Thu, 30 Jul 2020 11:53:44 +0000 (19:53 +0800)
MOSDScrub2 is sent from mgr for serving "ceph pg
{scrub|deep-scrub|repair}' commands when it's talking to a mimic and newer OSD.

ceph task checks if all pgs are scrubbed by looking at the `last_scrub_stamp` fields
in the `ceph pg dump` output. and it request the not-yet-scrubbed pgs a
deep scrub to ensure they are scrub before timeout.

in this change, crimson handles MOSDScrub2 by starting a remote peering
request, and the underlying peering_state will notify the corresponding
PG to start scrub. to get the test pass, a minimal implmentation is
added to update the scrub timestamp to `now` upon request of
peering_state.

we will need to add the correct scrubbing support later. but this is
enough for passing the thrasher test and for preparing for more tests
which uses the "ceph" task.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/osd/osd.cc
src/crimson/osd/osd.h
src/crimson/osd/pg.cc
src/crimson/osd/pg.h

index 6985d26157db65437758e8fd25b8005480bd7532..0677825f15dbeb2fbdaa1f9563443bf95051438f 100644 (file)
@@ -28,6 +28,7 @@
 #include "messages/MOSDPGRecoveryDelete.h"
 #include "messages/MOSDPGRecoveryDeleteReply.h"
 #include "messages/MOSDRepOpReply.h"
+#include "messages/MOSDScrub2.h"
 #include "messages/MPGStats.h"
 
 #include "os/Transaction.h"
@@ -644,6 +645,8 @@ seastar::future<> OSD::ms_dispatch(crimson::net::Connection* conn, MessageRef m)
       return handle_rep_op(conn, boost::static_pointer_cast<MOSDRepOp>(m));
     case MSG_OSD_REPOPREPLY:
       return handle_rep_op_reply(conn, boost::static_pointer_cast<MOSDRepOpReply>(m));
+    case MSG_OSD_SCRUB2:
+      return handle_scrub(conn, boost::static_pointer_cast<MOSDScrub2>(m));
     default:
       logger().info("ms_dispatch unhandled message {}", *m);
       return seastar::now();
@@ -1111,6 +1114,28 @@ seastar::future<> OSD::handle_rep_op_reply(crimson::net::Connection* conn,
   return seastar::now();
 }
 
+seastar::future<> OSD::handle_scrub(crimson::net::Connection* conn,
+                                   Ref<MOSDScrub2> m)
+{
+  if (m->fsid != superblock.cluster_fsid) {
+    logger().warn("fsid mismatched");
+    return seastar::now();
+  }
+  return seastar::parallel_for_each(std::move(m->scrub_pgs),
+    [m, conn=conn->get_shared(), this](spg_t pgid) {
+    pg_shard_t from_shard{static_cast<int>(m->get_source().num()),
+                          pgid.shard};
+    PeeringState::RequestScrub scrub_request{m->deep, m->repair};
+    return shard_services.start_operation<RemotePeeringEvent>(
+      *this,
+      conn,
+      shard_services,
+      from_shard,
+      pgid,
+      PGPeeringEvent{m->epoch, m->epoch, scrub_request}).second;
+  });
+}
+
 seastar::future<> OSD::handle_mark_me_down(crimson::net::Connection* conn,
                                           Ref<MOSDMarkMeDown> m)
 {
index 93f58eb65cb82d8ce70d1d1478ad823e2c3aa9cf..e95b4f8ee110450604fc2057f64481017378a261 100644 (file)
@@ -37,6 +37,7 @@ class MCommand;
 class MOSDMap;
 class MOSDRepOpReply;
 class MOSDRepOp;
+class MOSDScrub2;
 class OSDMap;
 class OSDMeta;
 class Heartbeat;
@@ -191,6 +192,8 @@ private:
                                      Ref<MOSDPeeringOp> m);
   seastar::future<> handle_recovery_subreq(crimson::net::Connection* conn,
                                           Ref<MOSDFastDispatchOp> m);
+  seastar::future<> handle_scrub(crimson::net::Connection* conn,
+                                Ref<MOSDScrub2> m);
   seastar::future<> handle_mark_me_down(crimson::net::Connection* conn,
                                        Ref<MOSDMarkMeDown> m);
 
index 59ef7be99b5c8d22e0a53d9f873f56e0128308ac..b6c5927de8a43b1498d31dd8126554db0e3a9e93 100644 (file)
@@ -318,6 +318,23 @@ void PG::do_delete_work(ceph::os::Transaction &t)
   shard_services.dec_pg_num();
 }
 
+void PG::scrub_requested(bool deep, bool repair, bool need_auto)
+{
+  // TODO: should update the stats upon finishing the scrub
+  peering_state.update_stats([deep, this](auto& history, auto& stats) {
+    const utime_t now = ceph_clock_now();
+    history.last_scrub = peering_state.get_info().last_update;
+    history.last_scrub_stamp = now;
+    history.last_clean_scrub_stamp = now;
+    if (deep) {
+      history.last_deep_scrub = history.last_scrub;
+      history.last_deep_scrub_stamp = now;
+    }
+    // yes, please publish the stats
+    return true;
+  });
+}
+
 void PG::log_state_enter(const char *state) {
   logger().info("Entering state: {}", state);
 }
index 19d9d4e876a1a6131fc183b7dfc7d04d1d452df4..421ff418e4ef2b8ba4d286a76de7187dc17eb187 100644 (file)
@@ -150,9 +150,7 @@ public:
     // Not needed yet -- mainly for scrub scheduling
   }
 
-  void scrub_requested(bool deep, bool repair, bool need_auto = false) final {
-    ceph_assert(0 == "Not implemented");
-  }
+  void scrub_requested(bool deep, bool repair, bool need_auto = false) final;
 
   uint64_t get_snap_trimq_size() const final {
     return 0;