summaryrefslogtreecommitdiffstats
path: root/src/osd/scrubber/scrub_job.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/scrubber/scrub_job.cc')
-rw-r--r--src/osd/scrubber/scrub_job.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/osd/scrubber/scrub_job.cc b/src/osd/scrubber/scrub_job.cc
new file mode 100644
index 00000000000..35071af5fd5
--- /dev/null
+++ b/src/osd/scrubber/scrub_job.cc
@@ -0,0 +1,108 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "./scrub_job.h"
+#include "pg_scrubber.h"
+
+using qu_state_t = Scrub::qu_state_t;
+using must_scrub_t = Scrub::must_scrub_t;
+using ScrubQContainer = Scrub::ScrubQContainer;
+using sched_params_t = Scrub::sched_params_t;
+using OSDRestrictions = Scrub::OSDRestrictions;
+using ScrubJob = Scrub::ScrubJob;
+
+
+// ////////////////////////////////////////////////////////////////////////// //
+// ScrubJob
+
+#define dout_subsys ceph_subsys_osd
+#undef dout_context
+#define dout_context (cct)
+#undef dout_prefix
+#define dout_prefix _prefix_fn(_dout, this, __func__)
+
+template <class T>
+static std::ostream& _prefix_fn(std::ostream* _dout, T* t, std::string fn = "")
+{
+ return t->gen_prefix(*_dout, fn);
+}
+
+ScrubJob::ScrubJob(CephContext* cct, const spg_t& pg, int node_id)
+ : RefCountedObject{cct}
+ , pgid{pg}
+ , whoami{node_id}
+ , cct{cct}
+ , log_msg_prefix{fmt::format("osd.{}: scrub-job:pg[{}]:", node_id, pgid)}
+{}
+
+// debug usage only
+namespace std {
+ostream& operator<<(ostream& out, const ScrubJob& sjob)
+{
+ return out << fmt::format("{}", sjob);
+}
+} // namespace std
+
+void ScrubJob::update_schedule(const Scrub::scrub_schedule_t& adjusted)
+{
+ schedule = adjusted;
+ penalty_timeout = utime_t(0, 0); // helps with debugging
+
+ // 'updated' is changed here while not holding jobs_lock. That's OK, as
+ // the (atomic) flag will only be cleared by select_pg_and_scrub() after
+ // scan_penalized() is called and the job was moved to the to_scrub queue.
+ updated = true;
+ dout(10) << fmt::format(
+ "adjusted: {:s} ({})", schedule.scheduled_at,
+ registration_state())
+ << dendl;
+}
+
+std::string ScrubJob::scheduling_state(utime_t now_is, bool is_deep_expected)
+ const
+{
+ // if not in the OSD scheduling queues, not a candidate for scrubbing
+ if (state != qu_state_t::registered) {
+ return "no scrub is scheduled";
+ }
+
+ // if the time has passed, we are surely in the queue
+ // (note that for now we do not tell client if 'penalized')
+ if (now_is > schedule.scheduled_at) {
+ // we are never sure that the next scrub will indeed be shallow:
+ return fmt::format("queued for {}scrub", (is_deep_expected ? "deep " : ""));
+ }
+
+ return fmt::format(
+ "{}scrub scheduled @ {:s}", (is_deep_expected ? "deep " : ""),
+ schedule.scheduled_at);
+}
+
+std::ostream& ScrubJob::gen_prefix(std::ostream& out, std::string_view fn) const
+{
+ return out << log_msg_prefix << fn << ": ";
+}
+
+// clang-format off
+std::string_view ScrubJob::qu_state_text(qu_state_t st)
+{
+ switch (st) {
+ case qu_state_t::not_registered: return "not registered w/ OSD"sv;
+ case qu_state_t::registered: return "registered"sv;
+ case qu_state_t::unregistering: return "unregistering"sv;
+ }
+ // g++ (unlike CLANG), requires an extra 'return' here
+ return "(unknown)"sv;
+}
+// clang-format on
+
+void ScrubJob::dump(ceph::Formatter* f) const
+{
+ f->open_object_section("scrub");
+ f->dump_stream("pgid") << pgid;
+ f->dump_stream("sched_time") << schedule.scheduled_at;
+ f->dump_stream("deadline") << schedule.deadline;
+ f->dump_bool("forced",
+ schedule.scheduled_at == PgScrubber::scrub_must_stamp());
+ f->close_section();
+}