]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/scrub: modify (deep)scrub ASOK commands
authorRonen Friedman <rfriedma@redhat.com>
Mon, 6 Nov 2023 10:08:57 +0000 (04:08 -0600)
committerRonen Friedman <rfriedma@redhat.com>
Sat, 11 Nov 2023 12:03:44 +0000 (06:03 -0600)
Fix all instances of 'deep_scrub' to the documented format (deep-scrub);

Make all formats of the documented command ('ceph tell $pg
[deep-]scrub', and the old 'ceph pg scrub $pgid') trigger an
operator-priority scrub;

Introduce a dev/tests-only format for the required functionality
of "trigger a scrub by modifying the timestamps".

Change some implementation details.

Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
src/osd/OSD.cc
src/osd/PrimaryLogPG.cc
src/osd/scrubber/pg_scrubber.cc
src/osd/scrubber/pg_scrubber.h
src/osd/scrubber_common.h

index 8a13353db98e3e6e10cbb71502644da08b86c4c1..8608c136565525c3fd05c221c4f5f9f0ca4498e2 100644 (file)
@@ -2633,7 +2633,9 @@ void OSD::asok_command(
       prefix == "mark_unfound_lost" ||
       prefix == "list_unfound" ||
       prefix == "scrub" ||
-      prefix == "deep_scrub"
+      prefix == "deep-scrub" ||
+      prefix == "schedule-scrub" ||      ///< dev/tests only!
+      prefix == "schedule-deep-scrub"    ///< dev/tests only!
     ) {
     string pgidstr;
     pg_t pgid;
@@ -4363,18 +4365,16 @@ void OSD::final_init()
     "");
   ceph_assert(r == 0);
   r = admin_socket->register_command(
-    "pg "                         \
-    "name=pgid,type=CephPgid "    \
-    "name=cmd,type=CephChoices,strings=scrub " \
-    "name=time,type=CephInt,req=false",
+    "pg "
+    "name=pgid,type=CephPgid "
+    "name=cmd,type=CephChoices,strings=scrub",
     asok_hook,
     "");
   ceph_assert(r == 0);
   r = admin_socket->register_command(
-    "pg "                         \
-    "name=pgid,type=CephPgid "    \
-    "name=cmd,type=CephChoices,strings=deep_scrub " \
-    "name=time,type=CephInt,req=false",
+    "pg "
+    "name=pgid,type=CephPgid "
+    "name=cmd,type=CephChoices,strings=deep-scrub",
     asok_hook,
     "");
   ceph_assert(r == 0);
@@ -4403,19 +4403,33 @@ void OSD::final_init()
     asok_hook,
     "list unfound objects on this pg, perhaps starting at an offset given in JSON");
   ceph_assert(r == 0);
+  // the operator commands (force a scrub)
+  r = admin_socket->register_command(
+    "scrub "
+    "name=pgid,type=CephPgid,req=false",
+    asok_hook,
+    "Trigger a scrub");
+  ceph_assert(r == 0);
+  r = admin_socket->register_command(
+    "deep-scrub "
+    "name=pgid,type=CephPgid,req=false",
+    asok_hook,
+    "Trigger a deep scrub");
+  ceph_assert(r == 0);
+  // debug/test commands (faking the timestamps)
   r = admin_socket->register_command(
-    "scrub "                           \
-    "name=pgid,type=CephPgid,req=false "       \
+    "schedule-scrub "
+    "name=pgid,type=CephPgid,req=false "
     "name=time,type=CephInt,req=false",
     asok_hook,
-    "Trigger a scheduled scrub ");
+    "Schedule a scrub");
   ceph_assert(r == 0);
   r = admin_socket->register_command(
-    "deep_scrub "                      \
-    "name=pgid,type=CephPgid,req=false "       \
+    "schedule-deep-scrub "
+    "name=pgid,type=CephPgid,req=false "
     "name=time,type=CephInt,req=false",
     asok_hook,
-    "Trigger a scheduled deep scrub ");
+    "Schedule a deep scrub");
   ceph_assert(r == 0);
 }
 
index ba13b9afa9b896f9ec4641b28d9f67b22b7f10ec..a2c2f15d739ed9c77f28e6ac59d82a4771645746 100644 (file)
@@ -1158,39 +1158,26 @@ void PrimaryLogPG::do_command(
     f->close_section();
   }
 
-  else if (prefix == "scrub" ||
-          prefix == "deep_scrub") {
-    bool deep = (prefix == "deep_scrub");
-    int64_t time = cmd_getval_or<int64_t>(cmdmap, "time", 0);
+  else if (prefix == "scrub" || prefix == "deep-scrub") {
+    if (is_primary()) {
+      scrub_level_t deep = (prefix == "deep-scrub") ? scrub_level_t::deep
+                                                   : scrub_level_t::shallow;
+      m_scrubber->on_operator_forced_scrub(f.get(), deep, m_planned_scrub);
+    } else {
+      ss << "Not primary";
+      ret = -EPERM;
+    }
+    outbl.append(ss.str());
+  }
 
+  // the test/debug commands that schedule a scrub by modifying timestamps
+  else if (prefix == "schedule-scrub" || prefix == "schedule-deep-scrub") {
     if (is_primary()) {
-      const pg_pool_t *p = &pool.info;
-      double pool_scrub_max_interval = 0;
-      double scrub_max_interval;
-      if (deep) {
-        p->opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL, &pool_scrub_max_interval);
-        scrub_max_interval = pool_scrub_max_interval > 0 ?
-          pool_scrub_max_interval : g_conf()->osd_deep_scrub_interval;
-      } else {
-        p->opts.get(pool_opts_t::SCRUB_MAX_INTERVAL, &pool_scrub_max_interval);
-        scrub_max_interval = pool_scrub_max_interval > 0 ?
-          pool_scrub_max_interval : g_conf()->osd_scrub_max_interval;
-      }
-      // Instead of marking must_scrub force a schedule scrub
-      utime_t stamp = ceph_clock_now();
-      if (time == 0)
-        stamp -= scrub_max_interval;
-      else
-        stamp -=  (float)time;
-      stamp -= 100.0;  // push back last scrub more for good measure
-      if (deep) {
-        set_last_deep_scrub_stamp(stamp);
-      }
-      set_last_scrub_stamp(stamp); // for 'deep' as well, as we use this value to order scrubs
-      f->open_object_section("result");
-      f->dump_bool("deep", deep);
-      f->dump_stream("stamp") << stamp;
-      f->close_section();
+      scrub_level_t deep = (prefix == "schedule-deep-scrub")
+                              ? scrub_level_t::deep
+                              : scrub_level_t::shallow;
+      const int64_t offst = cmd_getval_or<int64_t>(cmdmap, "time", 0);
+      m_scrubber->on_operator_periodic_cmd(f.get(), deep, offst);
     } else {
       ss << "Not primary";
       ret = -EPERM;
@@ -1214,6 +1201,7 @@ void PrimaryLogPG::do_command(
     }
     outbl.append(ss.str());
   }
+
   else {
     ret = -ENOSYS;
     ss << "prefix '" << prefix << "' not implemented";
index babd8782e9cae1fcb59a1cc53b25a4ba371b096b..4cd861b89c8f493c8db525daf36a1f2d35e1044f 100644 (file)
@@ -656,6 +656,78 @@ Scrub::sched_conf_t PgScrubber::populate_config_params() const
 }
 
 
+// handling Asok's "scrub" & "deep-scrub" commands
+
+namespace {
+void asok_response_section(
+    ceph::Formatter* f,
+    bool is_periodic,
+    scrub_level_t scrub_level,
+    utime_t stamp = utime_t{})
+{
+  f->open_object_section("result");
+  f->dump_bool("deep", (scrub_level == scrub_level_t::deep));
+  f->dump_bool("must", !is_periodic);
+  f->dump_stream("stamp") << stamp;
+  f->close_section();
+}
+}  // namespace
+
+// when asked to force a "periodic" scrub by faking the timestamps
+void PgScrubber::on_operator_periodic_cmd(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    int64_t offset)
+{
+  const auto cnf = populate_config_params();
+  dout(10) << fmt::format(
+                 "{}: {} (cmd offset:{}) conf:{}", __func__,
+                 (scrub_level == scrub_level_t::deep ? "deep" : "shallow"), offset,
+                 cnf)
+          << dendl;
+
+  // move the relevant time-stamp backwards - enough to trigger a scrub
+
+  utime_t now_is = ceph_clock_now();
+  utime_t stamp = now_is;
+
+  if (offset > 0) {
+    stamp -= offset;
+  } else {
+    double max_iv =
+       (scrub_level == scrub_level_t::deep)
+           ? 2 * cnf.max_deep
+           : (cnf.max_shallow ? *cnf.max_shallow : cnf.shallow_interval);
+    dout(20) << fmt::format(
+                   "{}: stamp:{:s} ms:{}/{}/{}", __func__, stamp,
+                   (cnf.max_shallow ? "ms+" : "ms-"),
+                   (cnf.max_shallow ? *cnf.max_shallow : -999.99),
+                   cnf.shallow_interval)
+            << dendl;
+    stamp -= max_iv;
+  }
+  stamp -= 100.0;  // for good measure
+
+  dout(10) << fmt::format("{}: stamp:{:s} ", __func__, stamp) << dendl;
+  asok_response_section(f, true, scrub_level, stamp);
+
+  if (scrub_level == scrub_level_t::deep) {
+    m_pg->set_last_deep_scrub_stamp(stamp);
+  }
+  // and in both cases:
+  m_pg->set_last_scrub_stamp(stamp);
+}
+
+// when asked to force a high-priority scrub
+void PgScrubber::on_operator_forced_scrub(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    requested_scrub_t& request_flags)
+{
+  auto deep_req = scrub_requested(scrub_level, scrub_type_t::not_repair, request_flags);
+  asok_response_section(f, false, deep_req);
+}
+
 
 // ----------------------------------------------------------------------------
 
index 996b26781be1e95bc0e84b9b72e19b49d23e0bfa..9946f9ce5ee96e6004c34fedb3aa1224333f7959 100644 (file)
@@ -291,6 +291,16 @@ class PgScrubber : public ScrubPgIF,
 
   pg_scrubbing_status_t get_schedule() const final;
 
+  void on_operator_periodic_cmd(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    int64_t offset) final;
+
+  void on_operator_forced_scrub(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    requested_scrub_t& request_flags) final;
+
   void dump_scrubber(ceph::Formatter* f,
                     const requested_scrub_t& request_flags) const final;
 
index 52890a8d1f044d0e9e18850bbf8e76a392739529..16810bba15c651b720edd7ae78a103fb1dbfdf90 100644 (file)
@@ -316,6 +316,21 @@ struct ScrubPgIF {
 
   virtual pg_scrubbing_status_t get_schedule() const = 0;
 
+
+  // // perform 'scrub'/'deep_scrub' asok commands
+
+  /// ... by faking the "last scrub" stamps
+  virtual void on_operator_periodic_cmd(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    int64_t offset) = 0;
+
+  /// ... by requesting an "operator initiated" scrub
+  virtual void on_operator_forced_scrub(
+    ceph::Formatter* f,
+    scrub_level_t scrub_level,
+    requested_scrub_t& request_flags) = 0;
+
   virtual void dump_scrubber(ceph::Formatter* f,
                             const requested_scrub_t& request_flags) const = 0;