]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
test/crimson: implement seastore replay test for onode-staged-tree
authorYingxin Cheng <yingxin.cheng@intel.com>
Wed, 23 Dec 2020 03:55:09 +0000 (11:55 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Wed, 13 Jan 2021 02:33:35 +0000 (10:33 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/onode_manager/staged-fltree/node_extent_mutable.cc
src/crimson/os/seastore/onode_manager/staged-fltree/tree_utils.h
src/test/crimson/seastore/onode_tree/test_staged_fltree.cc

index edc6324caf3919fff4ffb4c8de7f8df5f7903e5c..a9a681ca44f5dc53c35eb8eb1b0c00b8cca777dc 100644 (file)
@@ -8,16 +8,19 @@ namespace crimson::os::seastore::onode {
 
 NodeExtentMutable::NodeExtentMutable(NodeExtent& extent)
     : extent{extent} {
-  assert(extent.is_pending());
+  assert(extent.is_pending() ||  // during mutation
+         extent.is_clean());     // during replay
 }
 
 const char* NodeExtentMutable::get_read() const {
-  assert(extent.is_pending());
+  assert(extent.is_pending() ||  // during mutation
+         extent.is_clean());     // during replay
   return extent.get_bptr().c_str();
 }
 
 char* NodeExtentMutable::get_write() {
-  assert(extent.is_pending());
+  assert(extent.is_pending() ||  // during mutation
+         extent.is_clean());     // during replay
   return extent.get_bptr().c_str();
 }
 
index 4bbcd97b7a1f27c8416322b9f17a258c2ab67d4a..ad7bd4f5533d5cc4769b058af97c18f3414f6fdb 100644 (file)
@@ -197,7 +197,9 @@ class TreeBuilder {
   using future = ertr::future<ValueT>;
 
   TreeBuilder(KVPool& kvs, NodeExtentManagerURef&& nm)
-    : kvs{kvs}, tree{std::move(nm)} {}
+      : kvs{kvs} {
+    tree.emplace(std::move(nm));
+  }
 
   future<> bootstrap(Transaction& t) {
     std::ostringstream oss;
@@ -216,9 +218,9 @@ class TreeBuilder {
     } else {
       oss << "track=off, ";
     }
-    oss << tree;
+    oss << *tree;
     logger().warn("TreeBuilder: {}, bootstrapping ...", oss.str());
-    return tree.mkfs(t);
+    return tree->mkfs(t);
   }
 
   future<> insert(Transaction& t) {
@@ -232,7 +234,7 @@ class TreeBuilder {
       }
       auto [key, p_value] = kv_iter.get_kv();
       logger().debug("[{}] {} -> {}", kv_iter.index(), key_hobj_t{key}, *p_value);
-      return tree.insert(t, key, *p_value
+      return tree->insert(t, key, *p_value
       ).safe_then([&t, this, cursors](auto ret) {
         auto& [cursor, success] = ret;
         assert(success == true);
@@ -242,7 +244,7 @@ class TreeBuilder {
 #ifndef NDEBUG
         auto [key, p_value] = kv_iter.get_kv();
         Onodes::validate_cursor(cursor, key, *p_value);
-        return tree.lower_bound(t, key).safe_then([this, cursor](auto cursor_) {
+        return tree->lower_bound(t, key).safe_then([this, cursor](auto cursor_) {
           auto [key, p_value] = kv_iter.get_kv();
           ceph_assert(cursor_.get_ghobj() == key);
           ceph_assert(cursor_.value() == cursor.value());
@@ -270,7 +272,7 @@ class TreeBuilder {
             assert(c_iter != cursors->end());
             auto [k, v] = kv_iter.get_kv();
             // validate values in tree keep intact
-            return tree.lower_bound(t, k).safe_then([this, &c_iter](auto cursor) {
+            return tree->lower_bound(t, k).safe_then([this, &c_iter](auto cursor) {
               auto [k, v] = kv_iter.get_kv();
               Onodes::validate_cursor(cursor, k, *v);
               // validate values in cursors keep intact
@@ -288,12 +290,16 @@ class TreeBuilder {
   }
 
   future<> get_stats(Transaction& t) {
-    return tree.get_stats_slow(t
+    return tree->get_stats_slow(t
     ).safe_then([this](auto stats) {
       logger().warn("{}", stats);
     });
   }
 
+  void reload(NodeExtentManagerURef&& nm) {
+    tree.emplace(std::move(nm));
+  }
+
   future<> validate(Transaction& t) {
     logger().info("Verifing insertion ...");
     return seastar::do_with(
@@ -304,7 +310,7 @@ class TreeBuilder {
           return ertr::make_ready_future<bool>(true);
         }
         auto [k, v] = kvs_iter.get_kv();
-        return tree.lower_bound(t, k
+        return tree->lower_bound(t, k
         ).safe_then([&kvs_iter, k=k, v=v] (auto cursor) {
           Onodes::validate_cursor(cursor, k, *v);
           ++kvs_iter;
@@ -320,7 +326,7 @@ class TreeBuilder {
   }
 
   KVPool& kvs;
-  Btree tree;
+  std::optional<Btree> tree;
   KVPool::iterator_t kv_iter;
 };
 
index bcc1c909da8c86960a0d52b97b2bf01ff46d1c01..da7422bcb02f77614a79f9344a89e424b52a9b7f 100644 (file)
@@ -1165,17 +1165,14 @@ struct d_seastore_tm_test_t :
 TEST_F(d_seastore_tm_test_t, 6_random_insert_leaf_node)
 {
   run_async([this] {
+    constexpr bool TEST_SEASTORE = true;
     constexpr bool TRACK_CURSORS = true;
     KVPool kvs{{8, 11, 64, 256, 301, 320},
                {8, 16, 128, 512, 576, 640},
                {0, 32}, {0, 10}, {0, 4}};
     auto tree = std::make_unique<TreeBuilder<TRACK_CURSORS>>(kvs,
-#if 0
-      NodeExtentManager::create_dummy(IS_DUMMY_SYNC)
-#else
-      NodeExtentManager::create_seastore(*tm)
-#endif
-    );
+        (TEST_SEASTORE ? NodeExtentManager::create_seastore(*tm)
+                       : NodeExtentManager::create_dummy(IS_DUMMY_SYNC)));
     {
       auto t = tm->create_transaction();
       tree->bootstrap(*t).unsafe_get();
@@ -1191,6 +1188,12 @@ TEST_F(d_seastore_tm_test_t, 6_random_insert_leaf_node)
       tree->get_stats(*t).unsafe_get();
       tm->submit_transaction(std::move(t)).unsafe_get();
     }
+    if constexpr (TEST_SEASTORE) {
+      logger().info("seastore replay begin");
+      restart();
+      tree->reload(NodeExtentManager::create_seastore(*tm));
+      logger().info("seastore replay end");
+    }
     {
       // Note: tm->create_weak_transaction() can also work, but too slow.
       auto t = tm->create_transaction();