]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd/scrub: move snap_mapper_{fix/op}_t to the Scrub namespace
authorRonen Friedman <rfriedma@redhat.com>
Wed, 3 Aug 2022 13:04:00 +0000 (13:04 +0000)
committerRonen Friedman <rfriedma@redhat.com>
Fri, 7 Jul 2023 11:38:18 +0000 (06:38 -0500)
Signed-off-by: Ronen Friedman <rfriedma@redhat.com>
(cherry picked from commit d32b1b41b8f1843dcc2a5a0542410f09ea82e466)

Conflicts:
- changes that had to be made to pg_scrubber instead of
  scrub_backend
- fmt formatters required to compile

src/common/hobject_fmt.h
src/osd/SnapMapReaderI.h
src/osd/osd_types_fmt.h
src/osd/scrubber/pg_scrubber.cc
src/osd/scrubber/pg_scrubber.h

index 4a1b5c74db7661b56e46c03b80efdf336f74b86e..a57e1670c3d40cb4af4a423e4cad5d56c2cc125c 100644 (file)
@@ -6,6 +6,7 @@
  * \file fmtlib formatters for some hobject.h classes
  */
 #include <fmt/format.h>
+#include <fmt/ranges.h>
 
 #include "common/hobject.h"
 #include "include/types_fmt.h"
index f979dff5db235b7213cc1bcafddf5f77f5ea204c..664e9bd4219b944bfd00fec61a0192979047af83 100644 (file)
@@ -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<snapid_t> snaps;
   std::set<snapid_t> wrong_snaps;  // only collected & returned for logging sake
 };
+
+}  // namespace Scrub
index 23c0e8a3b81afff95c5058fb94d9e1f09394e010..8d48134106ec3b84decc72ec7585a50868f93e1b 100644 (file)
@@ -7,13 +7,17 @@
 
 #include "common/hobject_fmt.h"
 #include "osd/osd_types.h"
+#include <fmt/chrono.h>
+#if FMT_VERSION >= 90000
+#include <fmt/ostream.h>
+#endif
 
 template <>
 struct fmt::formatter<osd_reqid_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<pg_shard_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<eversion_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<object_manifest_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<object_info_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<pg_t> {
   constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
 
   template <typename FormatContext>
-  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<spg_t> {
+  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+  template <typename FormatContext>
+  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<pg_history_t> {
+  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+  template <typename FormatContext>
+  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<pg_info_t> {
+  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+  template <typename FormatContext>
+  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<SnapSet> {
+  template <typename ParseContext>
+  constexpr auto parse(ParseContext& ctx)
+  {
+    auto it = ctx.begin();
+    if (it != ctx.end() && *it == 'D') {
+      verbose = true;
+      ++it;
+    }
+    return it;
+  }
+
+  template <typename FormatContext>
+  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<ScrubMap::object> {
+  constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
+
+  ///\todo: consider passing the 'D" flag to control snapset dump
+  template <typename FormatContext>
+  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(), "{{{}:<<OI_ATTR>>({})}} ", 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<ScrubMap> {
+  template <typename ParseContext>
+  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 <typename FormatContext>
+  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<ObjectRecoveryInfo> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<ObjectRecoveryProgress> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<PastIntervals> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<pg_log_op_return_item_t> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<watch_info_t> : fmt::ostream_formatter {};
+template <> struct fmt::formatter<pg_log_entry_t> : fmt::ostream_formatter {};
+template <bool TrackChanges> struct fmt::formatter<pg_missing_set<TrackChanges>> : fmt::ostream_formatter {};
+#endif
index 95967ae4258c594c143c73eacc1843ca815f307b..d9e07a6c2e89e1a526c3ae15498185496f04fde3 100644 (file)
@@ -977,7 +977,7 @@ void PgScrubber::on_replica_init()
 }
 
 void PgScrubber::apply_snap_mapper_fixes(
-    const std::vector<snap_mapper_fix_t>& fix_list)
+    const std::vector<Scrub::snap_mapper_fix_t>& fix_list)
 {
   dout(15) << __func__ << " " << fix_list.size() << " fixes" << dendl;
 
@@ -1048,9 +1048,9 @@ void PgScrubber::apply_snap_mapper_fixes(
 }
 
 
-std::vector<snap_mapper_fix_t> PgScrubber::_scan_snaps(ScrubMap& smap)
+std::vector<Scrub::snap_mapper_fix_t> PgScrubber::_scan_snaps(ScrubMap& smap)
 {
-  std::vector<snap_mapper_fix_t> out_orders;
+  std::vector<Scrub::snap_mapper_fix_t> out_orders;
   hobject_t head;
   SnapSet snapset;
 
@@ -1122,7 +1122,7 @@ std::vector<snap_mapper_fix_t> PgScrubber::_scan_snaps(ScrubMap& smap)
   return out_orders;
 }
 
-std::optional<snap_mapper_fix_t> PgScrubber::scan_object_snaps(
+std::optional<Scrub::snap_mapper_fix_t> PgScrubber::scan_object_snaps(
   const hobject_t& hoid,
   const SnapSet& snapset,
   SnapMapReaderI& snaps_getter)
@@ -1164,17 +1164,17 @@ std::optional<snap_mapper_fix_t> 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<snap_mapper_fix_t> 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};
 }
 
index ff5c83407b7f3aa153e047daa5531746e76094a6..2279d5c64f7d25e0c50844d1ddcff0ce4acd9002 100644 (file)
@@ -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<snap_mapper_fix_t> _scan_snaps(ScrubMap& smap);
+  [[nodiscard]] std::vector<Scrub::snap_mapper_fix_t> _scan_snaps(ScrubMap& smap);
 
-  [[nodiscard]] std::optional<snap_mapper_fix_t> scan_object_snaps(
+  [[nodiscard]] std::optional<Scrub::snap_mapper_fix_t> scan_object_snaps(
       const hobject_t& hoid,
       const SnapSet& snapset,
       Scrub::SnapMapReaderI& snaps_getter);
 
   void apply_snap_mapper_fixes(
-      const std::vector<snap_mapper_fix_t>& fix_list);
+      const std::vector<Scrub::snap_mapper_fix_t>& fix_list);
 
   ScrubMap clean_meta_map();