]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
src/test: add a function in ceph_test_rados to check refcount is correct
authormyoungwon oh <ohmyoungwon@gmail.com>
Tue, 16 Feb 2021 09:30:09 +0000 (18:30 +0900)
committermyoungwon oh <ohmyoungwon@gmail.com>
Mon, 29 Mar 2021 08:14:57 +0000 (17:14 +0900)
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 <myoungwon.oh@samsung.com>
src/test/osd/CMakeLists.txt
src/test/osd/RadosModel.h
src/test/osd/TestRados.cc

index fc343d969b2138101cfdcdd0f1b87c7ecf6d0298..b2c5ec884da048da825a63cc93c2f096bcfcbb3c 100644 (file)
@@ -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
index 69430b3fcba2e204ea995e57c3e66a443e1a5839..1e53eefe173b57b3ee23977d8aff26793d84eb0a 100644 (file)
@@ -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<librados::ObjectItem> 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<chunk_refs_by_object_t*>(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);
index 2f64ff8828ffc20832ac3ecb577f1e733d4f2ac0..1a1389b2a1881494aab1b1c510c2797d880ba839 100644 (file)
@@ -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;