From: Ronen Friedman Date: Mon, 6 Nov 2023 10:08:57 +0000 (-0600) Subject: osd/scrub: modify (deep)scrub ASOK commands X-Git-Tag: v19.0.0~85^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=653ae9ebc143617d99997fa872ddaf0c5fd60223;p=ceph-ci.git osd/scrub: modify (deep)scrub ASOK commands 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 --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 8a13353db98..8608c136565 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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); } diff --git a/src/osd/PrimaryLogPG.cc b/src/osd/PrimaryLogPG.cc index ba13b9afa9b..a2c2f15d739 100644 --- a/src/osd/PrimaryLogPG.cc +++ b/src/osd/PrimaryLogPG.cc @@ -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(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(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"; diff --git a/src/osd/scrubber/pg_scrubber.cc b/src/osd/scrubber/pg_scrubber.cc index babd8782e9c..4cd861b89c8 100644 --- a/src/osd/scrubber/pg_scrubber.cc +++ b/src/osd/scrubber/pg_scrubber.cc @@ -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); +} + // ---------------------------------------------------------------------------- diff --git a/src/osd/scrubber/pg_scrubber.h b/src/osd/scrubber/pg_scrubber.h index 996b26781be..9946f9ce5ee 100644 --- a/src/osd/scrubber/pg_scrubber.h +++ b/src/osd/scrubber/pg_scrubber.h @@ -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; diff --git a/src/osd/scrubber_common.h b/src/osd/scrubber_common.h index 52890a8d1f0..16810bba15c 100644 --- a/src/osd/scrubber_common.h +++ b/src/osd/scrubber_common.h @@ -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;