From: Ronen Friedman Date: Sat, 27 Dec 2025 17:18:46 +0000 (+0000) Subject: osd/scrub: improve scrub target dumps X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7bb4322c2cf55dccccbccff722a1bf845ce5b441;p=ceph.git osd/scrub: improve scrub target dumps 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 query' output) now also dumps the two scrub targets. Signed-off-by: Ronen Friedman --- diff --git a/src/osd/scrubber/osd_scrub.cc b/src/osd/scrubber/osd_scrub.cc index 7a3466a20d7..11e9756af20 100644 --- a/src/osd/scrubber/osd_scrub.cc +++ b/src/osd/scrubber/osd_scrub.cc @@ -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 diff --git a/src/osd/scrubber/osd_scrub_sched.cc b/src/osd/scrubber/osd_scrub_sched.cc index aa356a1c12c..ef3a11922dc 100644 --- a/src/osd/scrubber/osd_scrub_sched.cc +++ b/src/osd/scrubber/osd_scrub_sched.cc @@ -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::max()); } + // ////////////////////////////////////////////////////////////////////////// // // ScrubQueue - maintaining the 'blocked on a locked object' count diff --git a/src/osd/scrubber/osd_scrub_sched.h b/src/osd/scrubber/osd_scrub_sched.h index 381fc5cc4e5..929bdc17f86 100644 --- a/src/osd/scrubber/osd_scrub_sched.h +++ b/src/osd/scrubber/osd_scrub_sched.h @@ -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 fn, diff --git a/src/osd/scrubber/pg_scrubber.cc b/src/osd/scrubber/pg_scrubber.cc index 1d6b8898c92..ba2575aa48c 100644 --- a/src/osd/scrubber/pg_scrubber.cc +++ b/src/osd/scrubber/pg_scrubber.cc @@ -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 diff --git a/src/osd/scrubber/scrub_job.cc b/src/osd/scrubber/scrub_job.cc index 9d228ae6a00..b8f1aa3aa2b 100644 --- a/src/osd/scrubber/scrub_job.cc +++ b/src/osd/scrubber/scrub_job.cc @@ -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). diff --git a/src/osd/scrubber/scrub_job.h b/src/osd/scrubber/scrub_job.h index 1d37f062c81..f0f7f0a3268 100644 --- a/src/osd/scrubber/scrub_job.h +++ b/src/osd/scrubber/scrub_job.h @@ -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? diff --git a/src/osd/scrubber/scrub_queue_entry.h b/src/osd/scrubber/scrub_queue_entry.h index 4fc0cb06360..87de07131a9 100644 --- a/src/osd/scrubber/scrub_queue_entry.h +++ b/src/osd/scrubber/scrub_queue_entry.h @@ -10,6 +10,10 @@ #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; };