Existing code exempts all 'high priority' scrubs, including for example
'after_repair' and 'mandatory on invalid history' scrubs from the limit.
PGs that do not have valid last-scrub data (which is what we have when
a pool is first created) - are set to shallow-scrub immediately.
Unfortunately - this type of scrub is (in the low granularity implemented
in existing code) is 'high priority'.
Which means that a newly created pool will have all its PGs start
scrubbing, regardless of concurrency (or any other) limits.
Fixes: https://tracker.ceph.com/issues/67253
Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
(cherry picked from commit
babd65e412266f5c734f7a2b57d87657d3470c47)
conflict resolution:
- eliminating irrelevant 'main' code that was picked into this branch.
- the code to set the scrub_job's flag moved to osd_scrub_sched.cc,
where the corresponding function is.
// adjust the suggested scrub time according to OSD-wide status
auto adjusted = adjust_target_time(suggested);
scrub_job->high_priority = suggested.is_must == must_scrub_t::mandatory;
+ scrub_job->observes_max_concurrency = suggested.observes_max_scrubs;
scrub_job->update_schedule(adjusted, reset_nb);
}
// Set the smallest time that isn't utime_t()
res.proposed_time = PgScrubber::scrub_must_stamp();
res.is_must = Scrub::must_scrub_t::mandatory;
+ res.observes_max_scrubs = false;
// we do not need the interval data in this case
} else if (
// a wrapper around the actual reservation, and that object releases
// the local resource automatically when reset.
m_local_osd_resource = m_osds->get_scrub_services().inc_scrubs_local(
- m_scrub_job->is_high_priority());
+ !m_scrub_job->observes_max_concurrency);
if (m_local_osd_resource) {
dout(15) << __func__ << ": local resources reserved" << dendl;
return true;
double min_interval{0.0};
double max_interval{0.0};
must_scrub_t is_must{must_scrub_t::not_mandatory};
+ bool observes_max_scrubs{true};
};
class ScrubJob final : public RefCountedObject {
bool high_priority{false};
+ /**
+ * If cleared: the scrub can be initiated even if the local OSD has reached
+ * osd_max_scrubs. Only 'false' for those high-priority scrubs that were
+ * operator initiated.
+ */
+ bool observes_max_concurrency{true};
+
ScrubJob(CephContext* cct, const spg_t& pg, int node_id);
utime_t get_sched_time() const { return schedule.not_before; }