// -*- 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 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> 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 active_osds) { RealObjsConfList all_osds; for (auto osd : active_osds) { RealObjsConfRef this_osd_fakes = std::make_unique(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> 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; }