From: Ronen Friedman Date: Wed, 3 Aug 2022 13:04:00 +0000 (+0000) Subject: osd/scrub: move snap_mapper_{fix/op}_t to the Scrub namespace X-Git-Tag: v17.2.7~203^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=70889b2583c23d396573d27536e834730ec3b259;p=ceph.git osd/scrub: move snap_mapper_{fix/op}_t to the Scrub namespace Signed-off-by: Ronen Friedman (cherry picked from commit d32b1b41b8f1843dcc2a5a0542410f09ea82e466) Conflicts: - changes that had to be made to pg_scrubber instead of scrub_backend - fmt formatters required to compile --- diff --git a/src/common/hobject_fmt.h b/src/common/hobject_fmt.h index 4a1b5c74db76..a57e1670c3d4 100644 --- a/src/common/hobject_fmt.h +++ b/src/common/hobject_fmt.h @@ -6,6 +6,7 @@ * \file fmtlib formatters for some hobject.h classes */ #include +#include #include "common/hobject.h" #include "include/types_fmt.h" diff --git a/src/osd/SnapMapReaderI.h b/src/osd/SnapMapReaderI.h index f979dff5db23..664e9bd4219b 100644 --- a/src/osd/SnapMapReaderI.h +++ b/src/osd/SnapMapReaderI.h @@ -51,8 +51,6 @@ struct SnapMapReaderI { virtual ~SnapMapReaderI() = default; }; -} // namespace Scrub - enum class snap_mapper_op_t { add, update, @@ -66,3 +64,5 @@ struct snap_mapper_fix_t { std::set snaps; std::set wrong_snaps; // only collected & returned for logging sake }; + +} // namespace Scrub diff --git a/src/osd/osd_types_fmt.h b/src/osd/osd_types_fmt.h index 23c0e8a3b81a..8d48134106ec 100644 --- a/src/osd/osd_types_fmt.h +++ b/src/osd/osd_types_fmt.h @@ -7,13 +7,17 @@ #include "common/hobject_fmt.h" #include "osd/osd_types.h" +#include +#if FMT_VERSION >= 90000 +#include +#endif template <> struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const osd_reqid_t& req_id, FormatContext& ctx) + auto format(const osd_reqid_t& req_id, FormatContext& ctx) const { return fmt::format_to(ctx.out(), "{}.{}:{}", req_id.name, req_id.inc, req_id.tid); @@ -25,7 +29,7 @@ struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const pg_shard_t& shrd, FormatContext& ctx) + auto format(const pg_shard_t& shrd, FormatContext& ctx) const { if (shrd.is_undefined()) { return fmt::format_to(ctx.out(), "?"); @@ -42,7 +46,7 @@ struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const eversion_t& ev, FormatContext& ctx) + auto format(const eversion_t& ev, FormatContext& ctx) const { return fmt::format_to(ctx.out(), "{}'{}", ev.epoch, ev.version); } @@ -66,7 +70,7 @@ struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const object_manifest_t& om, FormatContext& ctx) + auto format(const object_manifest_t& om, FormatContext& ctx) const { fmt::format_to(ctx.out(), "manifest({}", om.get_type_name()); if (om.is_redirect()) { @@ -83,7 +87,7 @@ struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const object_info_t& oi, FormatContext& ctx) + auto format(const object_info_t& oi, FormatContext& ctx) const { fmt::format_to(ctx.out(), "{}({} {} {} s {} uv {}", oi.soid, oi.version, oi.last_reqid, (oi.flags ? oi.get_flag_string() : ""), oi.size, @@ -110,8 +114,226 @@ struct fmt::formatter { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const pg_t& pg, FormatContext& ctx) + auto format(const pg_t& pg, FormatContext& ctx) const { return fmt::format_to(ctx.out(), "{}.{:x}", pg.pool(), pg.m_seed); } }; + + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const spg_t& spg, FormatContext& ctx) const + { + if (shard_id_t::NO_SHARD == spg.shard.id) { + return fmt::format_to(ctx.out(), "{}", spg.pgid); + } else { + return fmt::format_to(ctx.out(), "{}s{}>", spg.pgid, spg.shard.id); + } + } +}; + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const pg_history_t& pgh, FormatContext& ctx) const + { + fmt::format_to(ctx.out(), + "ec={}/{} lis/c={}/{} les/c/f={}/{}/{} sis={}", + pgh.epoch_created, + pgh.epoch_pool_created, + pgh.last_interval_started, + pgh.last_interval_clean, + pgh.last_epoch_started, + pgh.last_epoch_clean, + pgh.last_epoch_marked_full, + pgh.same_interval_since); + + if (pgh.prior_readable_until_ub != ceph::timespan::zero()) { + return fmt::format_to(ctx.out(), + " pruub={}", + pgh.prior_readable_until_ub); + } else { + return ctx.out(); + } + } +}; + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + template + auto format(const pg_info_t& pgi, FormatContext& ctx) + { + fmt::format_to(ctx.out(), "{}({}", pgi.pgid, (pgi.dne() ? " DNE" : "")); + if (pgi.is_empty()) { + fmt::format_to(ctx.out(), " empty"); + } else { + fmt::format_to(ctx.out(), " v {}", pgi.last_update); + if (pgi.last_complete != pgi.last_update) { + fmt::format_to(ctx.out(), " lc {}", pgi.last_complete); + } + fmt::format_to(ctx.out(), " ({},{}]", pgi.log_tail, pgi.last_update); + } + if (pgi.is_incomplete()) { + fmt::format_to(ctx.out(), " lb {}", pgi.last_backfill); + } + fmt::format_to(ctx.out(), + " local-lis/les={}/{}", + pgi.last_interval_started, + pgi.last_epoch_started); + return fmt::format_to(ctx.out(), + " n={} {})", + pgi.stats.stats.sum.num_objects, + pgi.history); + } +}; + +// snaps and snap-sets + +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext& ctx) + { + auto it = ctx.begin(); + if (it != ctx.end() && *it == 'D') { + verbose = true; + ++it; + } + return it; + } + + template + auto format(const SnapSet& snps, FormatContext& ctx) + { + if (verbose) { + // similar to SnapSet::dump() + fmt::format_to(ctx.out(), + "snaps{{{}: clns ({}): ", + snps.seq, + snps.clones.size()); + for (auto cln : snps.clones) { + + fmt::format_to(ctx.out(), "[{}: sz:", cln); + + auto cs = snps.clone_size.find(cln); + if (cs != snps.clone_size.end()) { + fmt::format_to(ctx.out(), "{} ", cs->second); + } else { + fmt::format_to(ctx.out(), "??"); + } + + auto co = snps.clone_overlap.find(cln); + if (co != snps.clone_overlap.end()) { + fmt::format_to(ctx.out(), "olp:{} ", co->second); + } else { + fmt::format_to(ctx.out(), "olp:?? "); + } + + auto cln_snps = snps.clone_snaps.find(cln); + if (cln_snps != snps.clone_snaps.end()) { + fmt::format_to(ctx.out(), "cl-snps:{} ]", cln_snps->second); + } else { + fmt::format_to(ctx.out(), "cl-snps:?? ]"); + } + } + + return fmt::format_to(ctx.out(), "}}"); + + } else { + return fmt::format_to(ctx.out(), + "{}={}:{}", + snps.seq, + snps.snaps, + snps.clone_snaps); + } + } + + bool verbose{false}; +}; + +template <> +struct fmt::formatter { + constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } + + ///\todo: consider passing the 'D" flag to control snapset dump + template + auto format(const ScrubMap::object& so, FormatContext& ctx) + { + fmt::format_to(ctx.out(), + "so{{ sz:{} dd:{} od:{} ", + so.size, + so.digest, + so.digest_present); + + // note the special handling of (1) OI_ATTR and (2) non-printables + for (auto [k, v] : so.attrs) { + std::string bkstr{v.raw_c_str(), v.raw_length()}; + if (k == std::string{OI_ATTR}) { + /// \todo consider parsing the OI args here. Maybe add a specific format + /// specifier + fmt::format_to(ctx.out(), "{{{}:<>({})}} ", k, bkstr.length()); + } else if (k == std::string{SS_ATTR}) { + bufferlist bl; + bl.push_back(v); + SnapSet sns{bl}; + fmt::format_to(ctx.out(), "{{{}:{:D}}} ", k, sns); + } else { + fmt::format_to(ctx.out(), "{{{}:{}({})}} ", k, bkstr, bkstr.length()); + } + } + + return fmt::format_to(ctx.out(), "}}"); + } +}; + +template <> +struct fmt::formatter { + template + constexpr auto parse(ParseContext& ctx) + { + auto it = ctx.begin(); + if (it != ctx.end() && *it == 'D') { + debug_log = true; // list the objects + ++it; + } + return it; + } + + template + auto format(const ScrubMap& smap, FormatContext& ctx) + { + fmt::format_to(ctx.out(), + "smap{{ valid:{} incr-since:{} #:{}", + smap.valid_through, + smap.incr_since, + smap.objects.size()); + if (debug_log) { + fmt::format_to(ctx.out(), " objects:"); + for (const auto& [ho, so] : smap.objects) { + fmt::format_to(ctx.out(), "\n\th.o<{}>:<{}> ", ho, so); + } + fmt::format_to(ctx.out(), "\n"); + } + return fmt::format_to(ctx.out(), "}}"); + } + + bool debug_log{false}; +}; + +#if FMT_VERSION >= 90000 +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template <> struct fmt::formatter : fmt::ostream_formatter {}; +template struct fmt::formatter> : fmt::ostream_formatter {}; +#endif diff --git a/src/osd/scrubber/pg_scrubber.cc b/src/osd/scrubber/pg_scrubber.cc index 95967ae4258c..d9e07a6c2e89 100644 --- a/src/osd/scrubber/pg_scrubber.cc +++ b/src/osd/scrubber/pg_scrubber.cc @@ -977,7 +977,7 @@ void PgScrubber::on_replica_init() } void PgScrubber::apply_snap_mapper_fixes( - const std::vector& fix_list) + const std::vector& fix_list) { dout(15) << __func__ << " " << fix_list.size() << " fixes" << dendl; @@ -1048,9 +1048,9 @@ void PgScrubber::apply_snap_mapper_fixes( } -std::vector PgScrubber::_scan_snaps(ScrubMap& smap) +std::vector PgScrubber::_scan_snaps(ScrubMap& smap) { - std::vector out_orders; + std::vector out_orders; hobject_t head; SnapSet snapset; @@ -1122,7 +1122,7 @@ std::vector PgScrubber::_scan_snaps(ScrubMap& smap) return out_orders; } -std::optional PgScrubber::scan_object_snaps( +std::optional PgScrubber::scan_object_snaps( const hobject_t& hoid, const SnapSet& snapset, SnapMapReaderI& snaps_getter) @@ -1164,17 +1164,17 @@ std::optional PgScrubber::scan_object_snaps( case result_t::code_t::not_found: dout(10) << __func__ << ": no snaps for " << hoid << ". Adding." << dendl; - return snap_mapper_fix_t{snap_mapper_op_t::add, hoid, obj_snaps, {}}; + return Scrub::snap_mapper_fix_t{snap_mapper_op_t::add, hoid, obj_snaps, {}}; case result_t::code_t::inconsistent: dout(10) << __func__ << ": inconsistent snapmapper data for " << hoid << ". Recreating." << dendl; - return snap_mapper_fix_t{ + return Scrub::snap_mapper_fix_t{ snap_mapper_op_t::overwrite, hoid, obj_snaps, {}}; default: dout(10) << __func__ << ": error (" << cpp_strerror(e.backend_error) << ") fetching snapmapper data for " << hoid << ". Recreating." << dendl; - return snap_mapper_fix_t{ + return Scrub::snap_mapper_fix_t{ snap_mapper_op_t::overwrite, hoid, obj_snaps, {}}; } __builtin_unreachable(); @@ -1194,7 +1194,7 @@ std::optional PgScrubber::scan_object_snaps( "{}: obj {}: was: {} updating to: {}", __func__, hoid, *cur_snaps, obj_snaps) << dendl; - return snap_mapper_fix_t{ + return Scrub::snap_mapper_fix_t{ snap_mapper_op_t::update, hoid, obj_snaps, *cur_snaps}; } diff --git a/src/osd/scrubber/pg_scrubber.h b/src/osd/scrubber/pg_scrubber.h index ff5c83407b7f..2279d5c64f7d 100644 --- a/src/osd/scrubber/pg_scrubber.h +++ b/src/osd/scrubber/pg_scrubber.h @@ -489,15 +489,15 @@ class PgScrubber : public ScrubPgIF, public ScrubMachineListener { void requeue_waiting() const { m_pg->requeue_ops(m_pg->waiting_for_scrub); } - [[nodiscard]] std::vector _scan_snaps(ScrubMap& smap); + [[nodiscard]] std::vector _scan_snaps(ScrubMap& smap); - [[nodiscard]] std::optional scan_object_snaps( + [[nodiscard]] std::optional scan_object_snaps( const hobject_t& hoid, const SnapSet& snapset, Scrub::SnapMapReaderI& snaps_getter); void apply_snap_mapper_fixes( - const std::vector& fix_list); + const std::vector& fix_list); ScrubMap clean_meta_map();