]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/scrub: improve scrub target dumps
authorRonen Friedman <rfriedma@redhat.com>
Sat, 27 Dec 2025 17:18:46 +0000 (17:18 +0000)
committerRonen Friedman <rfriedma@redhat.com>
Mon, 5 Jan 2026 13:23:27 +0000 (15:23 +0200)
Following the changes to the internal structures used for
scrub scheduling, improve the code handling external queries
and dumps, so that:
- common code is used when creating the JSON lines for scrub targets;
- the data dumped more closely matches the internal state;

Specifically:
- the scrub-queue dump ('tell osd.1 dump_scrubs') now includes
  whether the target is active (being scrubbed) or not.
- the scrubber dump (the ',scrubber' object in 'pg <pgid> query'
  output) now also dumps the two scrub targets.

Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
src/osd/scrubber/osd_scrub.cc
src/osd/scrubber/osd_scrub_sched.cc
src/osd/scrubber/osd_scrub_sched.h
src/osd/scrubber/pg_scrubber.cc
src/osd/scrubber/scrub_job.cc
src/osd/scrubber/scrub_job.h
src/osd/scrubber/scrub_queue_entry.h

index 7a3466a20d76b8a53715f40d1d2e8cdf4ba34d2e..11e9756af20a447a0bb86393939c7eb13fc70d34 100644 (file)
@@ -59,7 +59,8 @@ std::ostream& OsdScrub::gen_prefix(std::ostream& out, std::string_view fn) const
 
 void OsdScrub::dump_scrubs(ceph::Formatter* f) const
 {
-  m_queue.dump_scrubs(f);
+  ceph_assert(f != nullptr);
+  m_queue.dump_scrubs(*f);
 }
 
 void OsdScrub::dump_scrub_reservations(ceph::Formatter* f) const
index aa356a1c12cc502594a478e79380c578d8fbe3e4..ef3a11922dcfff32aa610fcbfc5e26b790da4f06 100644 (file)
@@ -147,31 +147,22 @@ bool ScrubQueue::remove_entry_unlocked(spg_t pgid, scrub_level_t s_or_d)
 }
 
 
-void ScrubQueue::dump_scrubs(ceph::Formatter* f) const
+void ScrubQueue::dump_scrubs(ceph::Formatter& f) const
 {
-  ceph_assert(f != nullptr);
   const auto query_time = ceph_clock_now();
-  Formatter::ArraySection all_scrubs_section{*f, "scrubs"};
+  Formatter::ArraySection all_scrubs_section{f, "scrubs"};
   for_each_job(
       [&f, query_time](const Scrub::SchedEntry& e) {
-        Formatter::ObjectSection job_section{*f, "scrub"sv};
-       f->dump_stream("pgid") << e.pgid;
-       f->dump_stream("sched_time") << e.schedule.not_before;
-       f->dump_stream("orig_sched_time") << e.schedule.scheduled_at;
-       f->dump_bool(
-           "forced",
-           e.schedule.scheduled_at == PgScrubber::scrub_must_stamp());
-
-        f->dump_stream("level") << (e.level == scrub_level_t::shallow
-                                       ? "shallow"
-                                       : "deep");
-        f->dump_stream("urgency") << fmt::format("{}", e.urgency);
-        f->dump_bool("eligible", e.schedule.not_before <= query_time);
-        f->dump_stream("last_issue") << fmt::format("{}", e.last_issue);
+        Formatter::ObjectSection job_section{f, "scrub"sv};
+        e.dump(f);
+        f.dump_bool("eligible", e.schedule.not_before <= query_time);
+        f.dump_bool("queued", true);
+        f.dump_bool("active", false);  // not being scrubbed
       },
       std::numeric_limits<int>::max());
 }
 
+
 // ////////////////////////////////////////////////////////////////////////// //
 // ScrubQueue - maintaining the 'blocked on a locked object' count
 
index 381fc5cc4e580550e49c9250634a94310c44b55f..929bdc17f8632daeadb4ea01a5a9d3af99ccf06a 100644 (file)
@@ -198,7 +198,7 @@ class ScrubQueue {
   std::ostream& gen_prefix(std::ostream& out, std::string_view fn) const;
 
  public:
-  void dump_scrubs(ceph::Formatter* f) const;
+  void dump_scrubs(ceph::Formatter& f) const;
 
   void for_each_job(
       std::function<void(const Scrub::SchedEntry&)> fn,
index 1d6b8898c92b5ce745f8bf41f338af0629ca93fc..ba2575aa48c6f4062d8575cce856ac67ddf2054b 100644 (file)
@@ -2313,6 +2313,7 @@ void PgScrubber::dump_scrubber(
        << earliest.sched_info.schedule.not_before;
     auto sched_state = m_scrub_job->scheduling_state(now_is);
     f->dump_string("schedule", sched_state);
+    f->dump_named_fmt("urgency", "{}", earliest.urgency());
   }
 
   if (m_publish_sessions) {
@@ -2320,6 +2321,34 @@ void PgScrubber::dump_scrubber(
     // The 'test_sequence' is an ever-increasing number used by tests.
     f->dump_int("test_sequence", m_sessions_counter);
   }
+
+  // always (also) dump the two targets (as some tests expect their specific
+  // format)
+  const auto query_time = ceph_clock_now();
+  {
+    Formatter::ObjectSection shallow_section{*f, "shallow-target"sv};
+    m_scrub_job->shallow_target.queued_element().dump(*f);
+    f->dump_bool(
+        "eligible",
+        m_scrub_job->shallow_target.queued_element().schedule.not_before <=
+            query_time);
+    f->dump_bool("queued", m_scrub_job->shallow_target.queued);
+    f->dump_bool(
+        "active",
+        (m_active_target && m_active_target->is_shallow()) ? true : false);
+  }
+  {
+    Formatter::ObjectSection deep_section{*f, "deep-target"sv};
+    m_scrub_job->deep_target.queued_element().dump(*f);
+    f->dump_bool(
+        "eligible",
+        m_scrub_job->deep_target.queued_element().schedule.not_before <=
+            query_time);
+    f->dump_bool("queued", m_scrub_job->deep_target.queued);
+    f->dump_bool(
+        "active",
+        (m_active_target && m_active_target->is_deep()) ? true : false);
+  }
 }
 
 
@@ -2361,6 +2390,7 @@ void PgScrubber::dump_active_scrubber(ceph::Formatter* f) const
   } else {
     f->dump_bool("is_reserving_replicas", false);
   }
+  f->dump_named_fmt("urgency", "{}",m_active_target->urgency());
 }
 
 pg_scrubbing_status_t PgScrubber::get_schedule() const
index 9d228ae6a008cf9dd8e1f3ccb46279d37be53649..b8f1aa3aa2b3ae7dd6cd6406bde4ff7a5c7bb43f 100644 (file)
@@ -3,10 +3,12 @@
 
 #include "./scrub_job.h"
 
-#include "pg_scrubber.h"
-
 #include "common/debug.h"
 
+#include "common/Formatter.h"
+
+#include "pg_scrubber.h"
+
 using must_scrub_t = Scrub::must_scrub_t;
 using sched_params_t = Scrub::sched_params_t;
 using OSDRestrictions = Scrub::OSDRestrictions;
@@ -17,6 +19,20 @@ using namespace std::chrono;
 
 using SchedEntry = Scrub::SchedEntry;
 
+// ////////////////////////////////////////////////////////////////////////// //
+// SchedEntry
+
+void SchedEntry::dump(ceph::Formatter& f) const
+{
+  f.dump_named_fmt("pgid", "{}", pgid);
+  f.dump_string("level", level == scrub_level_t::shallow ? "shallow" : "deep");
+  f.dump_named_fmt("urgency", "{}", urgency);
+  f.dump_named_fmt("sched_time", "{}", schedule.not_before);
+  f.dump_named_fmt("orig_sched_time", "{}", schedule.scheduled_at);
+  f.dump_named_fmt("last_issue", "{}", last_issue);
+  f.dump_bool("forced", urgency >= urgency_t::operator_requested);
+}
+
 // ////////////////////////////////////////////////////////////////////////// //
 // SchedTarget
 
@@ -350,17 +366,6 @@ std::ostream& ScrubJob::gen_prefix(std::ostream& out, std::string_view fn) const
   return out << log_msg_prefix << fn << ": ";
 }
 
-void ScrubJob::dump(ceph::Formatter* f) const
-{
-  const auto& entry = earliest_target().sched_info;
-  const auto& sch = entry.schedule;
-  Formatter::ObjectSection scrubjob_section{*f, "scrub"sv};
-  f->dump_stream("pgid") << pgid;
-  f->dump_stream("sched_time") << get_sched_time();
-  f->dump_stream("orig_sched_time") << sch.scheduled_at;
-  f->dump_bool("forced", entry.urgency >= urgency_t::operator_requested);
-}
-
 // a set of static functions to determine, given a scheduling target's urgency,
 // what restrictions apply to that target (and what exemptions it has).
 
index 1d37f062c817f730388b840aabaf151e5179e2cd..f0f7f0a3268465246466c35c2ac56999242307b4 100644 (file)
@@ -270,8 +270,6 @@ class ScrubJob {
       scrub_level_t s_or_d,
       const Scrub::sched_conf_t& app_conf);
 
-  void dump(ceph::Formatter* f) const;
-
   bool is_registered() const { return registered; }
 
   /// are any of our two SchedTargets queued in the scrub queue?
index 4fc0cb063602ab74fc8cbe40575fcc18eba471ea..87de07131a9c61bba8c3cf772e32fa0b30df7e89 100644 (file)
 #include "osd/osd_types.h"
 #include "osd/scrubber_common.h"
 
+namespace ceph {
+class Formatter;
+}  // namespace ceph
+
 namespace Scrub {
 
 /**
@@ -84,6 +88,8 @@ struct SchedEntry {
   /// either 'none', or the reason for the latest failure/delay (for
   /// logging/reporting purposes)
   delay_cause_t last_issue{delay_cause_t::none};
+
+  void dump(ceph::Formatter& f) const;
 };