summaryrefslogtreecommitdiffstats
path: root/src/test/osd/scrubber_generators.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/osd/scrubber_generators.cc')
-rw-r--r--src/test/osd/scrubber_generators.cc168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/test/osd/scrubber_generators.cc b/src/test/osd/scrubber_generators.cc
new file mode 100644
index 000000000..0f2f371e7
--- /dev/null
+++ b/src/test/osd/scrubber_generators.cc
@@ -0,0 +1,168 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/osd/scrubber_generators.h"
+
+#include <fmt/ranges.h>
+
+using namespace ScrubGenerator;
+
+// ref: PGLogTestRebuildMissing()
+bufferptr create_object_info(const ScrubGenerator::RealObj& objver)
+{
+ object_info_t oi{};
+ oi.soid = objver.ghobj.hobj;
+ oi.version = eversion_t(objver.ghobj.generation, 0);
+ oi.size = objver.data.size;
+
+ bufferlist bl;
+ oi.encode(bl,
+ 0 /*get_osdmap()->get_features(CEPH_ENTITY_TYPE_OSD, nullptr)*/);
+ bufferptr bp(bl.c_str(), bl.length());
+ return bp;
+}
+
+std::pair<bufferptr, std::vector<snapid_t>> create_object_snapset(
+ const ScrubGenerator::RealObj& robj,
+ const SnapsetMockData* snapset_mock_data)
+{
+ if (!snapset_mock_data) {
+ return {bufferptr(), {}};
+ }
+ /// \todo fill in missing version/osd details from the robj
+ auto sns = snapset_mock_data->make_snapset();
+ bufferlist bl;
+ encode(sns, bl);
+ bufferptr bp = bufferptr(bl.c_str(), bl.length());
+
+ // extract the set of object snaps
+ return {bp, sns.snaps};
+}
+
+RealObjsConfList ScrubGenerator::make_real_objs_conf(
+ int64_t pool_id,
+ const RealObjsConf& blueprint,
+ std::vector<int32_t> active_osds)
+{
+ RealObjsConfList all_osds;
+
+ for (auto osd : active_osds) {
+ RealObjsConfRef this_osd_fakes = std::make_unique<RealObjsConf>(blueprint);
+ // now - fix & corrupt every "object" in the blueprint
+ for (RealObj& robj : this_osd_fakes->objs) {
+
+ robj.ghobj.hobj.pool = pool_id;
+ }
+
+ all_osds[osd] = std::move(this_osd_fakes);
+ }
+ return all_osds; // reconsider (maybe add a move ctor?)
+}
+
+///\todo dispose of the created buffer pointers
+
+ScrubGenerator::SmapEntry ScrubGenerator::make_smobject(
+ const ScrubGenerator::RealObj& blueprint,
+ int osd_num)
+{
+ ScrubGenerator::SmapEntry ret;
+
+ ret.ghobj = blueprint.ghobj;
+ ret.smobj.attrs[OI_ATTR] = create_object_info(blueprint);
+ if (blueprint.snapset_mock_data) {
+ auto [bp, snaps] =
+ create_object_snapset(blueprint, blueprint.snapset_mock_data);
+ ret.smobj.attrs[SS_ATTR] = bp;
+ std::cout << fmt::format("{}: ({}) osd:{} snaps:{}",
+ __func__,
+ ret.ghobj.hobj,
+ osd_num,
+ snaps)
+ << std::endl;
+ }
+
+ for (const auto& [at_k, at_v] : blueprint.data.attrs) {
+ ret.smobj.attrs[at_k] = ceph::buffer::copy(at_v.c_str(), at_v.size());
+ {
+ // verifying (to be removed after dev phase)
+ auto bk = ret.smobj.attrs[at_k].begin_deep().get_ptr(
+ ret.smobj.attrs[at_k].length());
+ std::string bkstr{bk.raw_c_str(), bk.raw_length()};
+ std::cout << fmt::format("{}: verification: {}", __func__, bkstr)
+ << std::endl;
+ }
+ }
+ ret.smobj.size = blueprint.data.size;
+ ret.smobj.digest = blueprint.data.hash;
+ /// \todo handle the 'present' etc'
+
+ ret.smobj.object_omap_keys = blueprint.data.omap.size();
+ ret.smobj.object_omap_bytes = blueprint.data.omap_bytes;
+ return ret;
+}
+
+all_clones_snaps_t ScrubGenerator::all_clones(
+ const ScrubGenerator::RealObj& head_obj)
+{
+ std::cout << fmt::format("{}: head_obj.ghobj.hobj:{}",
+ __func__,
+ head_obj.ghobj.hobj)
+ << std::endl;
+
+ std::map<hobject_t, std::vector<snapid_t>> ret;
+
+ for (const auto& clone : head_obj.snapset_mock_data->clones) {
+ auto clone_set_it = head_obj.snapset_mock_data->clone_snaps.find(clone);
+ if (clone_set_it == head_obj.snapset_mock_data->clone_snaps.end()) {
+ std::cout << "note: no clone_snaps for " << clone << std::endl;
+ continue;
+ }
+ auto clone_set = clone_set_it->second;
+ hobject_t clone_hobj{head_obj.ghobj.hobj};
+ clone_hobj.snap = clone;
+
+ ret[clone_hobj] = clone_set_it->second;
+ std::cout << fmt::format("{}: clone:{} clone_set:{}",
+ __func__,
+ clone_hobj,
+ clone_set)
+ << std::endl;
+ }
+
+ return ret;
+}
+
+void ScrubGenerator::add_object(ScrubMap& map,
+ const ScrubGenerator::RealObj& real_obj,
+ int osd_num)
+{
+ // do we have data corruption recipe for this OSD?
+ /// \todo c++20: use contains()
+ CorruptFunc relevant_fix = crpt_do_nothing;
+
+ auto p = real_obj.corrupt_funcs->find(osd_num);
+ if (p != real_obj.corrupt_funcs->end()) {
+ // yes, we have a corruption recepie for this OSD
+ // \todo c++20: use at()
+ relevant_fix = p->second;
+ }
+
+ // create a possibly-corrupted copy of the "real object"
+ auto modified_obj = (relevant_fix)(real_obj, osd_num);
+
+ std::cout << fmt::format("{}: modified: osd:{} ho:{} key:{}",
+ __func__,
+ osd_num,
+ modified_obj.ghobj.hobj,
+ modified_obj.ghobj.hobj.get_key())
+ << std::endl;
+
+ auto entry = make_smobject(modified_obj, osd_num);
+ std::cout << fmt::format("{}: osd:{} smap entry: {} {}",
+ __func__,
+ osd_num,
+ entry.smobj.size,
+ entry.smobj.attrs.size())
+ << std::endl;
+ map.objects[entry.ghobj.hobj] = entry.smobj;
+}