From: myoungwon oh Date: Tue, 16 Feb 2021 09:30:09 +0000 (+0900) Subject: src/test: add a function in ceph_test_rados to check refcount is correct X-Git-Tag: v17.1.0~2307^2~28 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=0c971cb3d3c8f50a41819e296136626363523ca6;p=ceph.git src/test: add a function in ceph_test_rados to check refcount is correct Comparing refcounts between manifest object and chunk object, ceph_test_rados will check refcount is correct at the end of test Signed-off-by: Myoungwon Oh --- diff --git a/src/test/osd/CMakeLists.txt b/src/test/osd/CMakeLists.txt index fc343d969b2..b2c5ec884da 100644 --- a/src/test/osd/CMakeLists.txt +++ b/src/test/osd/CMakeLists.txt @@ -12,6 +12,8 @@ target_link_libraries(ceph_test_rados ${CMAKE_DL_LIBS} ${EXTRALIBS} ${CMAKE_DL_LIBS} + cls_cas_internal + cls_cas_client ) install(TARGETS ceph_test_rados diff --git a/src/test/osd/RadosModel.h b/src/test/osd/RadosModel.h index 69430b3fcba..1e53eefe173 100644 --- a/src/test/osd/RadosModel.h +++ b/src/test/osd/RadosModel.h @@ -24,6 +24,9 @@ #include "osd/HitSet.h" #include "common/ceph_crypto.h" +#include "cls/cas/cls_cas_client.h" +#include "cls/cas/cls_cas_internal.h" + #ifndef RADOSMODEL_H #define RADOSMODEL_H @@ -585,6 +588,80 @@ public: contents.dirty = true; pool_obj_cont.rbegin()->second.insert_or_assign(oid, contents); } + + bool check_chunks_refcount(librados::IoCtx &chunk_pool_ctx, librados::IoCtx &manifest_pool_ctx) + { + librados::ObjectCursor shard_start; + librados::ObjectCursor shard_end; + librados::ObjectCursor begin; + librados::ObjectCursor end; + begin = chunk_pool_ctx.object_list_begin(); + end = chunk_pool_ctx.object_list_end(); + + chunk_pool_ctx.object_list_slice( + begin, + end, + 1, + 1, + &shard_start, + &shard_end); + + librados::ObjectCursor c(shard_start); + while(c < shard_end) + { + std::vector result; + int r = chunk_pool_ctx.object_list(c, shard_end, 12, {}, &result, &c); + if (r < 0) { + cerr << "error object_list : " << cpp_strerror(r) << std::endl; + return false; + } + + for (const auto & i : result) { + auto oid = i.oid; + cout << oid << std::endl; + chunk_refs_t refs; + { + bufferlist t; + r = chunk_pool_ctx.getxattr(oid, CHUNK_REFCOUNT_ATTR, t); + if (r < 0) { + continue; + } + auto p = t.cbegin(); + decode(refs, p); + } + ceph_assert(refs.get_type() == chunk_refs_t::TYPE_BY_OBJECT); + + chunk_refs_by_object_t *byo = + static_cast(refs.r.get()); + + for (auto& pp : byo->by_object) { + int src_refcount = 0; + int dst_refcount = byo->by_object.count(pp); + for (int tries = 0; tries < 10; tries++) { + r = cls_cas_references_chunk(manifest_pool_ctx, pp.oid.name, oid); + if (r == -ENOENT || r == -ENOLINK) { + src_refcount = 0; + } else if (r == -EBUSY) { + sleep(10); + continue; + } else { + src_refcount = r; + } + break; + } + if (src_refcount > dst_refcount) { + cerr << " src_object " << pp + << ": src_refcount " << src_refcount + << ", dst_object " << oid + << ": dst_refcount " << dst_refcount + << std::endl; + return false; + } + } + } + } + return true; + } }; void read_callback(librados::completion_t comp, void *arg); diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc index 2f64ff8828f..1a1389b2a18 100644 --- a/src/test/osd/TestRados.cc +++ b/src/test/osd/TestRados.cc @@ -15,7 +15,6 @@ #include "test/osd/RadosModel.h" - using namespace std; class WeightedTestGenerator : public TestOpGenerator @@ -716,6 +715,12 @@ int main(int argc, char **argv) exit(1); } context.loop(&gen); + if (enable_dedup) { + if (!context.check_chunks_refcount(context.low_tier_io_ctx, context.io_ctx)) { + cerr << " Invalid refcount " << std::endl; + exit(1); + } + } context.shutdown(); cerr << context.errors << " errors." << std::endl;