]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: wire up FLTreeOnodeManager and FlatCollectionManager
authorSamuel Just <sjust@redhat.com>
Thu, 11 Feb 2021 02:58:58 +0000 (18:58 -0800)
committerSamuel Just <sjust@redhat.com>
Wed, 10 Mar 2021 06:35:55 +0000 (22:35 -0800)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/os/seastore/CMakeLists.txt
src/crimson/os/seastore/seastore.cc
src/crimson/os/seastore/seastore.h
src/test/crimson/seastore/CMakeLists.txt
src/test/crimson/seastore/test_seastore.cc [new file with mode: 0644]
src/test/crimson/seastore/transaction_manager_test_state.h

index 39fe5bdfef012f3b7a5a9cebbe0c4c70c7f0adca..79777fb7aa87de2d8f143e3a1039728340ccc4a4 100644 (file)
@@ -26,6 +26,7 @@ add_library(crimson-seastore STATIC
   onode_manager/staged-fltree/stages/sub_items_stage.cc
   onode_manager/staged-fltree/super.cc
   onode_manager/staged-fltree/value.cc
+  onode_manager/staged-fltree/fltree_onode_manager.cc
   extentmap_manager.cc
   extentmap_manager/btree/extentmap_btree_node_impl.cc
   extentmap_manager/btree/btree_extentmap_manager.cc
index f9221294cc00c2dd814d8f987b64e34a7df04624..8edf97648a0f61b017c2d07b0d9f3a8e90f700d5 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "seastore.h"
 
+#include <algorithm>
+
 #include <boost/algorithm/string/trim.hpp>
 #include <fmt/format.h>
 #include <fmt/ostream.h>
@@ -37,12 +39,23 @@ struct SeastoreCollection final : public FuturizedCollection {
 
 seastar::future<> SeaStore::stop()
 {
-  return seastar::now();
+  return transaction_manager->close(
+  ).handle_error(
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::stop"
+    }
+  );
+
 }
 
 seastar::future<> SeaStore::mount()
 {
-  return seastar::now();
+  return transaction_manager->mount(
+  ).handle_error(
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::mount"
+    }
+  );
 }
 
 seastar::future<> SeaStore::umount()
@@ -52,7 +65,27 @@ seastar::future<> SeaStore::umount()
 
 seastar::future<> SeaStore::mkfs(uuid_d new_osd_fsid)
 {
-  return seastar::now();
+  return transaction_manager->mkfs(
+  ).safe_then([this] {
+    return seastar::do_with(
+      make_transaction(),
+      [this](auto &t) {
+       return onode_manager->mkfs(*t
+       ).safe_then([this, &t] {
+         return collection_manager->mkfs(*t);
+       }).safe_then([this, &t](auto coll_root) {
+         transaction_manager->write_collection_root(
+           *t,
+           coll_root);
+         return transaction_manager->submit_transaction(
+           std::move(t));
+       });
+      });
+  }).handle_error(
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::mkfs"
+    }
+  );
 }
 
 seastar::future<store_statfs_t> SeaStore::stat() const
@@ -75,7 +108,20 @@ SeaStore::list_objects(CollectionRef ch,
 seastar::future<CollectionRef> SeaStore::create_new_collection(const coll_t& cid)
 {
   auto c = _get_collection(cid);
-  return seastar::make_ready_future<CollectionRef>(c);
+  return repeat_with_internal_context(
+    c,
+    ceph::os::Transaction{},
+    [this, cid](auto &ctx) {
+      return _create_collection(
+       ctx,
+       cid,
+       4 /* TODO */
+      ).safe_then([this, &ctx] {
+       return transaction_manager->submit_transaction(std::move(ctx.transaction));
+      });
+    }).then([c] {
+      return CollectionRef(c);
+    });
 }
 
 seastar::future<CollectionRef> SeaStore::open_collection(const coll_t& cid)
@@ -85,7 +131,34 @@ seastar::future<CollectionRef> SeaStore::open_collection(const coll_t& cid)
 
 seastar::future<std::vector<coll_t>> SeaStore::list_collections()
 {
-  return seastar::make_ready_future<std::vector<coll_t>>();
+  return seastar::do_with(
+    std::vector<coll_t>(),
+    [this](auto &ret) {
+      return repeat_eagain([this, &ret] {
+
+       return seastar::do_with(
+         make_transaction(),
+         [this, &ret](auto &t) {
+           return transaction_manager->read_collection_root(*t
+           ).safe_then([this, &ret, &t](auto coll_root) {
+             return collection_manager->list(
+               coll_root,
+               *t);
+           }).safe_then([this, &ret, &t](auto colls) {
+             ret.resize(colls.size());
+             std::transform(
+               colls.begin(), colls.end(), ret.begin(),
+               [](auto p) { return p.first; });
+           });
+         });
+      }).safe_then([&ret] {
+       return seastar::make_ready_future<std::vector<coll_t>>(ret);
+      });
+    }).handle_error(
+      crimson::ct_error::assert_all{
+       "Invalid error in SeaStore::list_collections"
+      }
+    );
 }
 
 SeaStore::read_errorator::future<ceph::bufferlist> SeaStore::read(
@@ -128,20 +201,26 @@ SeaStore::get_attrs_ertr::future<SeaStore::attrs_t> SeaStore::get_attrs(
   return crimson::ct_error::enoent::make();
 }
 
-seastar::future<struct stat> stat(
-  CollectionRef c,
-  const ghobject_t& oid)
-{
-  return seastar::make_ready_future<struct stat>();
-}
-
-
 seastar::future<struct stat> SeaStore::stat(
   CollectionRef c,
   const ghobject_t& oid)
 {
-  struct stat st;
-  return seastar::make_ready_future<struct stat>(st);
+  return repeat_with_onode<struct stat>(
+    c,
+    oid,
+    [=](auto &t, auto &onode) {
+      struct stat st;
+      auto &olayout = onode.get_layout();
+      st.st_size = olayout.size;
+      st.st_blksize = 4096;
+      st.st_blocks = (st.st_size + st.st_blksize - 1) / st.st_blksize;
+      st.st_nlink = 1;
+      return seastar::make_ready_future<struct stat>();
+    }).handle_error(
+      crimson::ct_error::assert_all{
+       "Invalid error in SeaStore::stat"
+       }
+    );
 }
 
 auto
@@ -305,6 +384,12 @@ SeaStore::tm_ret SeaStore::_do_transaction_step(
       return _create_collection(ctx, cid, op->split_bits);
     }
     break;
+    case Transaction::OP_RMCOLL:
+    {
+      coll_t cid = i.get_cid(op->cid);
+      return _remove_collection(ctx, cid);
+    }
+    break;
     case Transaction::OP_OMAP_SETKEYS:
     {
       std::map<std::string, ceph::bufferlist> aset;
@@ -377,17 +462,6 @@ SeaStore::tm_ret SeaStore::_write(
   logger().debug("{}: {} {} ~ {}",
                 __func__, *onode, offset, len);
   assert(len == bl.length());
-
-/*
-  return onode_manager->get_or_create_onode(cid, oid).safe_then([=, &bl](auto ref) {
-    return;
-  }).handle_error(
-    crimson::ct_error::enoent::handle([]() {
-      return;
-    }),
-    OnodeManager::open_ertr::pass_further{}
-  );
-  */
   return tm_ertr::now();
 }
 
@@ -461,7 +535,62 @@ SeaStore::tm_ret SeaStore::_create_collection(
   internal_context_t &ctx,
   const coll_t& cid, int bits)
 {
-  return tm_ertr::now();
+  return transaction_manager->read_collection_root(
+    *ctx.transaction
+  ).safe_then([=, &ctx](auto _cmroot) {
+    return seastar::do_with(
+      _cmroot,
+      [=, &ctx](auto &cmroot) {
+       return collection_manager->create(
+         cmroot,
+         *ctx.transaction,
+         cid,
+         bits
+       ).safe_then([=, &ctx, &cmroot] {
+         if (cmroot.must_update()) {
+           transaction_manager->write_collection_root(
+             *ctx.transaction,
+             cmroot);
+         }
+       });
+      });
+  }).handle_error(
+    tm_ertr::pass_further{},
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::_create_collection"
+    }
+  );
+}
+
+SeaStore::tm_ret SeaStore::_remove_collection(
+  internal_context_t &ctx,
+  const coll_t& cid)
+{
+  return transaction_manager->read_collection_root(
+    *ctx.transaction
+  ).safe_then([=, &ctx](auto _cmroot) {
+    return seastar::do_with(
+      _cmroot,
+      [=, &ctx](auto &cmroot) {
+       return collection_manager->remove(
+         cmroot,
+         *ctx.transaction,
+         cid
+       ).safe_then([=, &ctx, &cmroot] {
+         // param here denotes whether it already existed, probably error
+         if (cmroot.must_update()) {
+           transaction_manager->write_collection_root(
+             *ctx.transaction,
+             cmroot);
+         }
+       });
+      });
+  }).handle_error(
+    tm_ertr::pass_further{},
+    crimson::ct_error::assert_all{
+      "Invalid error in SeaStore::_create_collection"
+    }
+  );
 }
 
 boost::intrusive_ptr<SeastoreCollection> SeaStore::_get_collection(const coll_t& cid)
index 3bdc7bdb2290509546a851f66ef3018ab5395814..1d5627201e074a76cd70f7b8fd4d1235a4048741 100644 (file)
@@ -15,6 +15,7 @@
 #include "include/uuid.h"
 
 #include "os/Transaction.h"
+#include "crimson/os/futurized_collection.h"
 #include "crimson/os/futurized_store.h"
 #include "crimson/os/seastore/transaction.h"
 #include "crimson/os/seastore/onode_manager.h"
@@ -166,6 +167,34 @@ private:
       });
   }
 
+  template <typename Ret, typename F>
+  auto repeat_with_onode(
+    CollectionRef ch,
+    const ghobject_t &oid,
+    F &&f) {
+    return seastar::do_with(
+      oid,
+      Ret{},
+      TransactionRef(),
+      OnodeRef(),
+      std::forward<F>(f),
+      [=](auto &oid, auto &ret, auto &t, auto &onode, auto &f) {
+       return repeat_eagain([&, this] {
+         t = make_transaction();
+         return onode_manager->get_onode(
+           *t, oid
+         ).safe_then([&, this](auto onode_ret) {
+           onode = std::move(onode_ret);
+           return f(*t, *onode);
+         }).safe_then([&ret](auto _ret) {
+           ret = _ret;
+         });
+       }).safe_then([&ret] {
+         return seastar::make_ready_future<Ret>(ret);
+       });
+      });
+  }
+
   TransactionManagerRef transaction_manager;
   CollectionManagerRef collection_manager;
   OnodeManagerRef onode_manager;
@@ -216,6 +245,9 @@ private:
   tm_ret _create_collection(
     internal_context_t &ctx,
     const coll_t& cid, int bits);
+  tm_ret _remove_collection(
+    internal_context_t &ctx,
+    const coll_t& cid);
 
   boost::intrusive_ptr<SeastoreCollection> _get_collection(const coll_t& cid);
 };
index bbe47d34bad2472ff81c67211a79de05babac95b..7155704a4bc98123b629cb19c1782073558c5171 100644 (file)
@@ -67,4 +67,14 @@ target_link_libraries(
   ${CMAKE_DL_LIBS}
   crimson-seastore)
 
+add_executable(unittest-seastore
+  test_seastore.cc
+  ../gtest_seastar.cc)
+add_ceph_unittest(unittest-seastore)
+target_link_libraries(
+  unittest-seastore
+  ${CMAKE_DL_LIBS}
+  crimson-seastore
+  crimson-common)
+
 add_subdirectory(onode_tree)
diff --git a/src/test/crimson/seastore/test_seastore.cc b/src/test/crimson/seastore/test_seastore.cc
new file mode 100644 (file)
index 0000000..fd6f645
--- /dev/null
@@ -0,0 +1,113 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <string>
+#include <iostream>
+#include <sstream>
+
+#include "test/crimson/gtest_seastar.h"
+
+#include "test/crimson/seastore/transaction_manager_test_state.h"
+
+#include "crimson/os/futurized_collection.h"
+#include "crimson/os/seastore/seastore.h"
+
+using namespace crimson;
+using namespace crimson::os;
+using namespace crimson::os::seastore;
+using CTransaction = ceph::os::Transaction;
+using namespace std;
+
+namespace {
+  [[maybe_unused]] seastar::logger& logger() {
+    return crimson::get_logger(ceph_subsys_test);
+  }
+}
+
+
+struct seastore_test_t :
+  public seastar_test_suite_t,
+  SeaStoreTestState {
+
+  coll_t coll_name{spg_t{pg_t{0, 0}}};
+  CollectionRef coll;
+
+  seastore_test_t() {}
+
+  seastar::future<> set_up_fut() final {
+    return tm_setup(
+    ).then([this] {
+      return seastore->create_new_collection(coll_name);
+    }).then([this](auto coll_ref) {
+      coll = coll_ref;
+    });
+  }
+
+  seastar::future<> tear_down_fut() final {
+    return tm_teardown();
+  }
+
+  void do_transaction(CTransaction &&t) {
+    return seastore->do_transaction(
+      coll,
+      std::move(t)).get0();
+  }
+};
+
+ghobject_t make_oid(int i) {
+  stringstream ss;
+  ss << "object_" << i;
+  auto ret = ghobject_t(
+    hobject_t(
+      sobject_t(ss.str(), CEPH_NOSNAP)));
+  ret.hobj.nspace = "asdf";
+  return ret;
+}
+
+template <typename T, typename V>
+auto contains(const T &t, const V &v) {
+  return std::find(
+    t.begin(),
+    t.end(),
+    v) != t.end();
+}
+
+TEST_F(seastore_test_t, collection_create_list_remove)
+{
+  run_async([this] {
+    coll_t test_coll{spg_t{pg_t{1, 0}}};
+    {
+      seastore->create_new_collection(test_coll).get0();
+      auto collections = seastore->list_collections().get0();
+      EXPECT_EQ(collections.size(), 2);
+      EXPECT_TRUE(contains(collections, coll_name));
+      EXPECT_TRUE(contains(collections,  test_coll));
+    }
+
+    {
+      CTransaction t;
+      t.remove_collection(test_coll);
+      do_transaction(std::move(t));
+      auto collections = seastore->list_collections().get0();
+      EXPECT_EQ(collections.size(), 1);
+      EXPECT_TRUE(contains(collections, coll_name));
+    }
+  });
+}
+
+TEST_F(seastore_test_t, touch_stat)
+{
+  run_async([this] {
+    auto test = make_oid(0);
+    {
+      CTransaction t;
+      t.touch(coll_name, test);
+      do_transaction(std::move(t));
+
+      auto result = seastore->stat(
+       coll,
+       test).get0();
+      EXPECT_EQ(result.st_size, 0);
+    }
+  });
+}
index ed422329669de3e9c30cec3340f47fde06f596a0..0158da44ce0dc26dae7fb175f8b94aaa4d776da5 100644 (file)
@@ -9,7 +9,10 @@
 #include "crimson/os/seastore/cache.h"
 #include "crimson/os/seastore/transaction_manager.h"
 #include "crimson/os/seastore/segment_manager/ephemeral.h"
+#include "crimson/os/seastore/seastore.h"
 #include "crimson/os/seastore/segment_manager.h"
+#include "crimson/os/seastore/collection_manager/flat_collection_manager.h"
+#include "crimson/os/seastore/onode_manager/staged-fltree/fltree_onode_manager.h"
 
 using namespace crimson;
 using namespace crimson::os;
@@ -87,6 +90,28 @@ auto get_transaction_manager(
   return ret;
 }
 
+auto get_seastore(
+  SegmentManager &segment_manager
+) {
+  auto segment_cleaner = std::make_unique<SegmentCleaner>(
+    SegmentCleaner::config_t::default_from_segment_manager(
+      segment_manager),
+    true);
+  auto journal = std::make_unique<Journal>(segment_manager);
+  auto cache = std::make_unique<Cache>(segment_manager);
+  auto lba_manager = lba_manager::create_lba_manager(segment_manager, *cache);
+
+  journal->set_segment_provider(&*segment_cleaner);
+
+  auto tm = get_transaction_manager(segment_manager);
+  auto cm = std::make_unique<collection_manager::FlatCollectionManager>(*tm);
+  return std::make_unique<SeaStore>(
+    std::move(tm),
+    std::move(cm),
+    std::make_unique<crimson::os::seastore::onode::FLTreeOnodeManager>(*tm));
+}
+
+
 class TMTestState : public EphemeralTestState {
 protected:
   std::unique_ptr<TransactionManager> tm;
@@ -128,3 +153,30 @@ protected:
     );
   }
 };
+
+class SeaStoreTestState : public EphemeralTestState {
+protected:
+  std::unique_ptr<SeaStore> seastore;
+
+  SeaStoreTestState() : EphemeralTestState() {}
+
+  virtual void _init() {
+    seastore = get_seastore(*segment_manager);
+  }
+
+  virtual void _destroy() {
+    seastore.reset();
+  }
+
+  virtual seastar::future<> _teardown() {
+    return seastore->stop();
+  }
+
+  virtual seastar::future<> _mount() {
+    return seastore->mount();
+  }
+
+  virtual seastar::future<> _mkfs() {
+    return seastore->mkfs(uuid_d{});
+  }
+};