]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/tools/store_nbd: add FuturizedStore driver
authorSamuel Just <sjust@redhat.com>
Sat, 8 May 2021 01:56:14 +0000 (18:56 -0700)
committerSamuel Just <sjust@redhat.com>
Wed, 12 May 2021 04:15:55 +0000 (21:15 -0700)
Allows usage of bluestore and seastore.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/tools/CMakeLists.txt
src/crimson/tools/store_nbd/block_driver.cc
src/crimson/tools/store_nbd/block_driver.h
src/crimson/tools/store_nbd/fs_driver.cc [new file with mode: 0644]
src/crimson/tools/store_nbd/fs_driver.h [new file with mode: 0644]

index f044e1d3e7dbcaab33a9fb9c9e534a6b18c037e0..52436c62dc48d7b3e21bcdb2387a38e4e8094395 100644 (file)
@@ -1,8 +1,9 @@
 add_executable(crimson-store-nbd
        store_nbd/store-nbd.cc
        store_nbd/tm_driver.cc
+       store_nbd/fs_driver.cc
        store_nbd/block_driver.cc
   )
 target_link_libraries(crimson-store-nbd
-  crimson-seastore)
+  crimson-os)
 install(TARGETS crimson-store-nbd DESTINATION bin)
index f4678dbd40c5acf7e92fa3b1be29f7f39d60f9d5..10e77a34bc39d19a7b8cfde6f944bfc602711891 100644 (file)
@@ -1,6 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
+#include "fs_driver.h"
 #include "block_driver.h"
 
 #include "tm_driver.h"
@@ -9,6 +10,8 @@ BlockDriverRef get_backend(BlockDriver::config_t config)
 {
   if (config.type == "transaction_manager") {
     return std::make_unique<TMDriver>(config);
+  } else if (config.is_futurized_store()) {
+    return std::make_unique<FSDriver>(config);
   } else {
     ceph_assert(0 == "invalid option");
     return BlockDriverRef();
index c92475c07d0390b7e40d15b63bd4350ea1daea29..dca74ee43bdcbe1b0be61204521444a675f24b95 100644 (file)
@@ -24,8 +24,19 @@ public:
   struct config_t {
     std::string type;
     bool mkfs = false;
+    unsigned num_collections = 128;
+    unsigned object_size = 4<<20 /* 4MB, rbd default */;
     std::optional<std::string> path;
 
+    bool is_futurized_store() const {
+      return type == "seastore" || type == "bluestore";
+    }
+
+    std::string get_fs_type() const {
+      ceph_assert(is_futurized_store());
+      return type;
+    }
+
     void populate_options(
       boost::program_options::options_description &desc)
     {
@@ -35,7 +46,7 @@ public:
         po::value<std::string>()
         ->default_value("transaction_manager")
         ->notifier([this](auto s) { type = s; }),
-        "Backend to use, options are transaction_manager"
+        "Backend to use, options are transaction_manager, seastore"
        )
        ("device-path",
         po::value<std::string>()
@@ -43,6 +54,16 @@ public:
         ->notifier([this](auto s) { path = s; }),
         "Path to device for backend"
        )
+       ("num-collections",
+        po::value<unsigned>()
+        ->notifier([this](auto s) { num_collections = s; }),
+        "Number of collections to use for futurized_store backends"
+       )
+       ("object-size",
+        po::value<unsigned>()
+        ->notifier([this](auto s) { object_size = s; }),
+        "Object size to use for futurized_store backends"
+       )
        ("mkfs",
         po::value<bool>()
         ->default_value(false)
diff --git a/src/crimson/tools/store_nbd/fs_driver.cc b/src/crimson/tools/store_nbd/fs_driver.cc
new file mode 100644 (file)
index 0000000..76db2c2
--- /dev/null
@@ -0,0 +1,166 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include <boost/iterator/counting_iterator.hpp>
+
+#include "os/Transaction.h"
+#include "fs_driver.h"
+
+using namespace crimson;
+using namespace crimson::os;
+
+coll_t get_coll(unsigned num) {
+  return coll_t(spg_t(pg_t(0, num)));
+}
+
+FSDriver::offset_mapping_t FSDriver::map_offset(off_t offset)
+{
+  uint32_t objid = offset / config.object_size;
+  uint32_t collid = objid % config.num_collections;
+  return offset_mapping_t{
+    collections[collid],
+    ghobject_t(
+      shard_id_t::NO_SHARD,
+      0,
+      (objid << 16) | collid,
+      "",
+      "",
+      0,
+      ghobject_t::NO_GEN),
+    offset % config.object_size
+  };
+}
+
+seastar::future<> FSDriver::write(
+  off_t offset,
+  bufferptr ptr)
+{
+  auto mapping = map_offset(offset);
+  ceph_assert(mapping.offset + ptr.length() <= config.object_size);
+  ceph::os::Transaction t;
+  bufferlist bl;
+  bl.append(ptr);
+  t.write(
+    mapping.chandle->get_cid(), 
+    mapping.object,
+    mapping.offset,
+    ptr.length(),
+    bl,
+    0);
+  return fs->do_transaction(
+    mapping.chandle,
+    std::move(t));
+}
+
+seastar::future<bufferlist> FSDriver::read(
+  off_t offset,
+  size_t size)
+{
+  auto mapping = map_offset(offset);
+  ceph_assert((mapping.offset + size) <= config.object_size);
+  return fs->read(
+    mapping.chandle,
+    mapping.object,
+    mapping.offset,
+    size,
+    0
+  ).handle_error(
+    crimson::ct_error::enoent::handle([size](auto &e) {
+      bufferlist bl;
+      bl.append_zero(size);
+      return seastar::make_ready_future<bufferlist>(std::move(bl));
+    }),
+    crimson::ct_error::assert_all{"Unrecoverable error in FSDriver::read"}
+  ).then([this, size](auto &&bl) {
+    if (bl.length() < size) {
+      bl.append_zero(size - bl.length());
+    }
+    return seastar::make_ready_future<bufferlist>(std::move(bl));
+  });
+}
+
+seastar::future<> FSDriver::mkfs()
+{
+  init();
+  assert(fs);
+  return fs->start(
+  ).then([this] {
+    uuid_d uuid;
+    uuid.generate_random();
+    return fs->mkfs(uuid);
+  }).then([this] {
+    return fs->stop();
+  }).then([this] {
+    init();
+    return fs->start();
+  }).then([this] {
+    return fs->mount();
+  }).then([this] {
+    return seastar::do_for_each(
+      boost::counting_iterator<unsigned>(0),
+      boost::counting_iterator<unsigned>(config.num_collections),
+      [this](auto i) {
+       return fs->create_new_collection(get_coll(i)
+       ).then([this, i](auto coll) {
+         ceph::os::Transaction t;
+         t.create_collection(get_coll(i), 0);
+         return fs->do_transaction(coll, std::move(t));
+       });
+      });
+  }).then([this] {
+    return fs->umount();
+  }).then([this] {
+    return fs->stop();
+  }).then([this] {
+    fs.reset();
+    return seastar::now();
+  });
+}
+
+seastar::future<> FSDriver::mount()
+{
+  ceph_assert(config.path);
+  return (
+    config.mkfs ? mkfs() : seastar::now()
+  ).then([this] {
+    init();
+    return fs->start();
+  }).then([this] {
+    return fs->mount();
+  }).then([this] {
+    return seastar::do_for_each(
+      boost::counting_iterator<unsigned>(0),
+      boost::counting_iterator<unsigned>(config.num_collections),
+      [this](auto i) {
+       return fs->open_collection(get_coll(i)
+       ).then([this, i](auto ref) {
+         collections[i] = ref;
+         return seastar::now();
+       });
+      });
+  }).then([this] {
+    return fs->stat();
+  }).then([this](auto s) {
+    size = s.total;
+  });
+};
+
+seastar::future<> FSDriver::close()
+{
+  collections.clear();
+  return fs->umount(
+  ).then([this] {
+    return fs->stop();
+  }).then([this] {
+    fs.reset();
+    return seastar::now();
+  });
+}
+
+void FSDriver::init()
+{
+  fs = FuturizedStore::create(
+    config.get_fs_type(),
+    *config.path,
+    crimson::common::local_conf().get_config_values());
+}
diff --git a/src/crimson/tools/store_nbd/fs_driver.h b/src/crimson/tools/store_nbd/fs_driver.h
new file mode 100644 (file)
index 0000000..1ef0797
--- /dev/null
@@ -0,0 +1,49 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "block_driver.h"
+
+#include "crimson/os/futurized_collection.h"
+#include "crimson/os/futurized_store.h"
+
+class FSDriver final : public BlockDriver {
+public:
+  FSDriver(config_t config) : config(config) {}
+  ~FSDriver() final {}
+
+  bufferptr get_buffer(size_t size) final {
+    return ceph::buffer::create_page_aligned(size);
+  }
+
+  seastar::future<> write(
+    off_t offset,
+    bufferptr ptr) final;
+
+  seastar::future<bufferlist> read(
+    off_t offset,
+    size_t size) final;
+
+  size_t get_size() const {
+    return size;
+  }
+
+  seastar::future<> mount() final;
+
+  seastar::future<> close() final;
+
+private:
+  size_t size = 0;
+  const config_t config;
+  std::unique_ptr<crimson::os::FuturizedStore> fs;
+  std::map<unsigned, crimson::os::CollectionRef> collections;
+
+  struct offset_mapping_t {
+    crimson::os::CollectionRef chandle;
+    ghobject_t object;
+    off_t offset;
+  };
+  offset_mapping_t map_offset(off_t offset);
+
+  seastar::future<> mkfs();
+  void init();
+};