]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson:add alien blue store
authorChunmei Liu <chunmei.liu@intel.com>
Wed, 22 Jan 2020 07:25:02 +0000 (23:25 -0800)
committerChunmei Liu <chunmei.liu@intel.com>
Fri, 28 Feb 2020 04:00:29 +0000 (20:00 -0800)
adds an alien store wrapper for ceph blue store, which will
create a thread pool, so crimson-osd can call bluestore API
which is running in Posix thread from seastar thread.

Signed-off-by: Chunmei Liu <chunmei.liu@intel.com>
27 files changed:
src/common/RefCountedObj.h
src/common/WorkQueue.h
src/common/admin_socket.h
src/common/ceph_atomic.h
src/common/ceph_context.cc
src/common/ceph_context.h
src/common/ceph_mutex.h
src/common/config_proxy.h
src/common/dout.h
src/common/perf_counters.cc
src/common/perf_counters.h
src/crimson/CMakeLists.txt
src/crimson/common/config_proxy.h
src/crimson/os/CMakeLists.txt
src/crimson/os/alienstore/CMakeLists.txt [new file with mode: 0644]
src/crimson/os/alienstore/alien_collection.h [new file with mode: 0644]
src/crimson/os/alienstore/alien_store.cc [new file with mode: 0644]
src/crimson/os/alienstore/alien_store.h [new file with mode: 0644]
src/crimson/os/cyanstore/cyan_store.cc
src/crimson/os/futurized_store.cc
src/crimson/os/futurized_store.h
src/crimson/osd/osd.cc
src/global/global_context.cc
src/include/Context.h
src/include/common_fwd.h
src/os/ObjectStore.cc
src/os/bluestore/BlockDevice.cc

index 49f29dcf84231c2eddf85b2628e6c67a89c366c8..b23f488cad90ba815286470e058b766e458b8f5c 100644 (file)
@@ -74,11 +74,11 @@ protected:
 private:
   void _get() const;
 
-#ifndef WITH_SEASTAR
-  mutable std::atomic<uint64_t> nref{1};
-#else
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
   // crimson is single threaded at the moment
   mutable uint64_t nref{1};
+#else
+  mutable std::atomic<uint64_t> nref{1};
 #endif
   CephContext *cct{nullptr};
 };
@@ -94,7 +94,7 @@ template<typename... Args>
   virtual ~RefCountedObjectSafe() override {}
 };
 
-#ifndef WITH_SEASTAR
+#if !defined(WITH_SEASTAR)|| defined(WITH_ALIEN)
 
 /**
  * RefCountedCond
@@ -185,7 +185,7 @@ struct RefCountedWaitObject {
   }
 };
 
-#endif // WITH_SEASTAR
+#endif // !defined(WITH_SEASTAR)|| defined(WITH_ALIEN)
 
 static inline void intrusive_ptr_add_ref(const RefCountedObject *p) {
   p->get();
index 21e9669bfb4c66e07214646e88e3f011deddf9d2..0c16cfc31f200217fc6e8d31ccbe78c1fd5fc85b 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef CEPH_WORKQUEUE_H
 #define CEPH_WORKQUEUE_H
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 // for ObjectStore.h
 struct ThreadPool {
   struct TPHandle {
index fad3e556fb9a55696afaf2c734447b7090b273e8..2105097bbeeb618fd52f13b9ccd84d31ffb1f2cf 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef CEPH_COMMON_ADMIN_SOCKET_H
 #define CEPH_COMMON_ADMIN_SOCKET_H
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #include "crimson/admin/admin_socket.h"
 #else
 
index 26a20ee28317532ad313e27960b5ad990f877b0d..320963500e7f5f195cf3c5928952e69732a3a75d 100644 (file)
@@ -17,7 +17,7 @@
 // like a full memory barrier stalling execution till CPU's store and
 // load buffers are drained.
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_BLUESTORE)
 
 #include <type_traits>
 
index 389033429418a0c669bc3a9bde0f7a3557ae713e..e7116e38875cd91e19e2791df8e0b2cd75b506e3 100644 (file)
@@ -55,7 +55,7 @@ using ceph::HeartbeatMap;
 #include <iostream>
 #include <pthread.h>
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 namespace crimson::common {
 CephContext::CephContext()
   : _conf{crimson::common::local_conf()},
index 88f94ff72280d01b26e1f853a38c7bae69188aef..adacecebfc3991d4008ec4c661fdd09d890ed3c9 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "common/cmdparse.h"
 #include "common/code_environment.h"
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #include "crimson/common/config_proxy.h"
 #include "crimson/common/perf_counters_collection.h"
 #else
@@ -60,7 +60,7 @@ namespace ceph {
   }
 }
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 namespace crimson::common {
 class CephContext {
 public:
index 4e888d72bb19c02939f18a43dfc42831241d1d64..4029a5a9f159ce9f4ace47834ba7a21d33214aef 100644 (file)
@@ -14,7 +14,7 @@
 // and make_recursive_mutex() factory methods, which take a string
 // naming the mutex for the purposes of the lockdep debug variant.
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 
 namespace ceph {
   // an empty class satisfying the mutex concept
@@ -58,7 +58,7 @@ namespace ceph {
   #define ceph_mutex_is_locked_by_me(m) true
 }
 
-#else  // WITH_SEASTAR
+#else  // defined (WITH_SEASTAR) && !defined(WITH_ALIEN)
 //
 // For legacy Mutex users that passed recursive=true, use
 // ceph::make_recursive_mutex.  For legacy Mutex users that passed
index 025f0a0a3bfc0ede43d44a025fb5a46f2bc2f167..9c0850fd08e1c7053f72e411c06d548e070aec06 100644 (file)
@@ -124,6 +124,11 @@ public:
   ConfigValues* operator->() noexcept {
     return &values;
   }
+#ifdef WITH_SEASTAR
+  void set_config_values(const ConfigValues& val) {
+    values = val;
+  }
+#endif
   int get_val(const std::string_view key, char** buf, int len) const {
     std::lock_guard l{lock};
     return config.get_val(values, key, buf, len);
index 2fdc07a19a65826a6d65cb47e029b1e62b2a7f56..c7c08182e5390354a94166e6e8e5e9cb6662d5a5 100644 (file)
@@ -19,7 +19,8 @@
 #include <type_traits>
 
 #include "include/ceph_assert.h"
-#ifdef WITH_SEASTAR
+#include "include/common_fwd.h"
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #include <seastar/util/log.hh>
 #include "crimson/common/log.h"
 #include "crimson/common/config_proxy.h"
@@ -117,7 +118,7 @@ struct is_dynamic<dynamic_marker_t<T>> : public std::true_type {};
 // generic macros
 #define dout_prefix *_dout
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #define dout_impl(cct, sub, v)                                          \
   do {                                                                  \
     if (crimson::common::local_conf()->subsys.should_gather(sub, v)) {  \
@@ -131,6 +132,16 @@ struct is_dynamic<dynamic_marker_t<T>> : public std::true_type {};
                   _out.str().c_str());          \
     }                                           \
   } while (0)
+#elif defined(WITH_SEASTAR) && defined(WITH_ALIEN)
+#define dout_impl(cct, sub, v)                                         \
+  do {                                                                 \
+  if (0) {                                                     \
+    ceph::logging::MutableEntry _dout_e(v, sub);                        \
+    std::ostream* _dout = &_dout_e.get_ostream();
+
+#define dendl_impl std::flush;                                          \
+  }                                                                     \
+  } while (0)
 #else
 #define dout_impl(cct, sub, v)                                         \
   do {                                                                 \
index dda589e1ca96cfc737ea39653efb5e014ae2c0dc..80c96413eb16b998ea69dd56c7c543270197cecc 100644 (file)
@@ -476,7 +476,7 @@ PerfCounters::PerfCounters(CephContext *cct, const std::string &name,
     m_lower_bound(lower_bound),
     m_upper_bound(upper_bound),
     m_name(name)
-#ifndef WITH_SEASTAR
+#if !defined(WITH_SEASTAR) || defined(WITH_ALIEN)
     ,
     m_lock_name(std::string("PerfCounters::") + name.c_str()),
     m_lock(ceph::make_mutex(m_lock_name))
index 1f9391137e876547ec452f4abfe63ac9fb16b5d3..c5f69aa7ce31abcb911c86d29f586f951f79faf3 100644 (file)
@@ -113,7 +113,7 @@ public:
     prio_default = prio_;
   }
 
-  TOPNSPC::common::PerfCounters* create_perf_counters();
+  PerfCounters* create_perf_counters();
 private:
   PerfCountersBuilder(const PerfCountersBuilder &rhs);
   PerfCountersBuilder& operator=(const PerfCountersBuilder &rhs);
@@ -121,7 +121,7 @@ private:
                 const char *description, const char *nick, int prio, int ty, int unit=UNIT_NONE,
                 std::unique_ptr<PerfHistogram<>> histogram = nullptr);
 
-  TOPNSPC::common::PerfCounters *m_perf_counters;
+  PerfCounters *m_perf_counters;
 
   int prio_default = 0;
 };
@@ -289,7 +289,7 @@ private:
 
   int prio_adjust = 0;
 
-#ifndef WITH_SEASTAR
+#if !defined(WITH_SEASTAR) || defined(WITH_ALIEN)
   const std::string m_lock_name;
   /** Protects m_data */
   ceph::mutex m_lock;
index 17550fb13280acdd6adf8882e54f2a30e8cf995e..e51af009c5ec5a7a965da13f849112eef2ab700e 100644 (file)
@@ -52,8 +52,6 @@ add_library(crimson-common STATIC
   ${PROJECT_SOURCE_DIR}/src/common/hobject.cc
   ${PROJECT_SOURCE_DIR}/src/common/hostname.cc
   ${PROJECT_SOURCE_DIR}/src/common/ipaddr.cc
-  ${PROJECT_SOURCE_DIR}/src/common/lockdep.cc
-  ${PROJECT_SOURCE_DIR}/src/common/mutex_debug.cc
   ${PROJECT_SOURCE_DIR}/src/common/mempool.cc
   ${PROJECT_SOURCE_DIR}/src/common/options.cc
   ${PROJECT_SOURCE_DIR}/src/common/perf_counters.cc
@@ -80,7 +78,6 @@ add_library(crimson-common STATIC
   ${PROJECT_SOURCE_DIR}/src/common/SubProcess.cc
   ${PROJECT_SOURCE_DIR}/src/common/TextTable.cc
   ${PROJECT_SOURCE_DIR}/src/common/Thread.cc
-  ${PROJECT_SOURCE_DIR}/src/common/HeartbeatMap.cc
   ${PROJECT_SOURCE_DIR}/src/common/PluginRegistry.cc
   ${PROJECT_SOURCE_DIR}/src/common/RefCountedObj.cc
   ${PROJECT_SOURCE_DIR}/src/crush/builder.c
index f0c1e592317379d0030db40f634d79804fe0aa58..d6132455eced5d3f04545cebf8ea5115e5f647ef 100644 (file)
@@ -89,6 +89,9 @@ public:
   const ConfigValues* operator->() const noexcept {
     return values.get();
   }
+  const ConfigValues get_config_values() {
+     return *values.get();
+  }
   ConfigValues* operator->() noexcept {
     return values.get();
   }
index 3be23677d1b0ee03083119d96f4320b9c574f0f5..8936fd101a6187e8662de98db919576e0c8e01c4 100644 (file)
@@ -2,6 +2,12 @@ add_library(crimson-os
   futurized_store.cc
   ${PROJECT_SOURCE_DIR}/src/os/Transaction.cc)
 add_subdirectory(cyanstore)
+
+if(WITH_BLUESTORE)
+  add_subdirectory(alienstore)
+endif()
+
 target_link_libraries(crimson-os
   crimson-cyanstore
+  crimson-alienstore
   crimson)
diff --git a/src/crimson/os/alienstore/CMakeLists.txt b/src/crimson/os/alienstore/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a0fbeef
--- /dev/null
@@ -0,0 +1,65 @@
+include_directories(SYSTEM "${CMAKE_SOURCE_DIR}/src/rocksdb/include")
+set(crimson_alien_srcs
+    alien_store.cc)
+
+list(APPEND crimson_alien_srcs
+  ${PROJECT_SOURCE_DIR}/src/common/admin_socket.cc
+  ${PROJECT_SOURCE_DIR}/src/common/blkdev.cc
+  ${PROJECT_SOURCE_DIR}/src/common/ceph_context.cc
+  ${PROJECT_SOURCE_DIR}/src/common/ceph_crypto.cc
+  ${PROJECT_SOURCE_DIR}/src/common/condition_variable_debug.cc
+  ${PROJECT_SOURCE_DIR}/src/common/cmdparse.cc
+  ${PROJECT_SOURCE_DIR}/src/common/Finisher.cc
+  ${PROJECT_SOURCE_DIR}/src/common/HeartbeatMap.cc
+  ${PROJECT_SOURCE_DIR}/src/common/PluginRegistry.cc
+  ${PROJECT_SOURCE_DIR}/src/common/lockdep.cc
+  ${PROJECT_SOURCE_DIR}/src/common/mutex_debug.cc
+  ${PROJECT_SOURCE_DIR}/src/common/perf_counters.cc
+  ${PROJECT_SOURCE_DIR}/src/common/perf_counters_collection.cc
+  ${PROJECT_SOURCE_DIR}/src/common/RefCountedObj.cc
+  ${PROJECT_SOURCE_DIR}/src/common/shared_mutex_debug.cc
+  ${PROJECT_SOURCE_DIR}/src/common/Throttle.cc
+  ${PROJECT_SOURCE_DIR}/src/common/Timer.cc
+  ${PROJECT_SOURCE_DIR}/src/common/TrackedOp.cc
+  ${PROJECT_SOURCE_DIR}/src/common/WorkQueue.cc
+  ${PROJECT_SOURCE_DIR}/src/common/util.cc
+  ${PROJECT_SOURCE_DIR}/src/global/global_context.cc
+  ${PROJECT_SOURCE_DIR}/src/os/ObjectStore.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/Allocator.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/AvlAllocator.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BitmapFreelistManager.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlockDevice.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueFS.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/bluefs_types.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueRocksEnv.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BlueStore.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/bluestore_types.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/fastbmap_allocator_impl.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/FreelistManager.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/io_uring.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/StupidAllocator.cc
+  ${PROJECT_SOURCE_DIR}/src/os/bluestore/BitmapAllocator.cc)
+
+if(HAVE_LIBAIO OR HAVE_POSIXAIO)
+  list(APPEND crimson_alien_srcs
+     ${PROJECT_SOURCE_DIR}/src/os/bluestore/KernelDevice.cc
+     ${PROJECT_SOURCE_DIR}/src/os/bluestore/aio.cc)
+endif()
+
+add_library(crimson-alienstore STATIC ${crimson_alien_srcs}
+  $<TARGET_OBJECTS:compressor_objs>
+  $<TARGET_OBJECTS:crush_objs>
+  $<TARGET_OBJECTS:common_prioritycache_obj>)
+if(HAVE_LIBAIO)
+  target_link_libraries(crimson-alienstore ${AIO_LIBRARIES})
+endif(HAVE_LIBAIO)
+
+target_compile_definitions(crimson-alienstore PRIVATE -DWITH_SEASTAR -DWITH_ALIEN)
+target_include_directories(crimson-alienstore PRIVATE
+  $<TARGET_PROPERTY:Seastar::seastar,INTERFACE_INCLUDE_DIRECTORIES>)
+target_link_libraries(crimson-alienstore fmt::fmt)
+target_link_libraries(crimson-alienstore kv)
+target_link_libraries(crimson-alienstore heap_profiler)
+target_link_libraries(crimson-alienstore ${BLKID_LIBRARIES})
+target_link_libraries(crimson-alienstore ${UDEV_LIBRARIES})
+target_link_libraries(crimson-alienstore crimson)
diff --git a/src/crimson/os/alienstore/alien_collection.h b/src/crimson/os/alienstore/alien_collection.h
new file mode 100644 (file)
index 0000000..30364b8
--- /dev/null
@@ -0,0 +1,25 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "os/ObjectStore.h"
+
+#include "crimson/os/futurized_collection.h"
+#include "crimson/os/futurized_store.h"
+#include "alien_store.h"
+
+namespace crimson::os {
+
+struct AlienCollection final : public FuturizedCollection {
+
+  ObjectStore::CollectionHandle collection;
+
+  AlienCollection(ObjectStore::CollectionHandle ch)
+  : FuturizedCollection(ch->cid),
+    collection(ch) {}
+
+  ~AlienCollection() {}
+};
+
+}
diff --git a/src/crimson/os/alienstore/alien_store.cc b/src/crimson/os/alienstore/alien_store.cc
new file mode 100644 (file)
index 0000000..e3d176c
--- /dev/null
@@ -0,0 +1,380 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "alien_collection.h"
+#include "alien_store.h"
+
+#include <map>
+#include <string_view>
+#include <boost/algorithm/string/trim.hpp>
+#include <fmt/format.h>
+#include <fmt/ostream.h>
+
+#include <seastar/core/alien.hh>
+#include <seastar/core/future-util.hh>
+#include <seastar/core/reactor.hh>
+
+#include "common/ceph_context.h"
+#include "global/global_context.h"
+#include "include/Context.h"
+#include "os/bluestore/BlueStore.h"
+#include "os/ObjectStore.h"
+#include "os/Transaction.h"
+
+#include "crimson/common/log.h"
+#include "crimson/os/futurized_store.h"
+
+namespace {
+  seastar::logger& logger()
+  {
+    return crimson::get_logger(ceph_subsys_filestore);
+  }
+
+class OnCommit final: public Context
+{
+  int cpuid;
+  Context* on_commit = nullptr;
+public:
+  seastar::promise<> alien_done;
+  OnCommit(int id, ceph::os::Transaction& txn): cpuid(id) {
+    if (txn.has_contexts()) {
+      on_commit = txn.get_on_commit();
+    }
+  }
+
+  void finish(int) final {
+    auto fut = seastar::alien::submit_to(cpuid, [this] {
+      if (on_commit) {
+        on_commit->complete(0);
+      }
+      alien_done.set_value();
+      return seastar::make_ready_future<>();
+    });
+    fut.wait();
+  }
+};
+}
+
+namespace crimson::os {
+
+AlienStore::AlienStore(const std::string& path, const ConfigValues& values)
+  : path{path}
+{
+  cct = std::make_unique<CephContext>(CEPH_ENTITY_TYPE_OSD);
+  g_ceph_context = cct.get();
+  cct->_conf.set_config_values(values);
+  store = std::make_unique<BlueStore>(cct.get(), path);
+  tp = std::make_unique<crimson::thread::ThreadPool>(1, 128, seastar::engine().cpu_id() + 10);
+}
+
+seastar::future<> AlienStore::start()
+{
+  return tp->start();
+}
+
+seastar::future<> AlienStore::stop()
+{
+  return tp->submit([this] {
+    for (auto [cid, ch]: coll_map)
+      static_cast<AlienCollection*>(ch.get())->collection.reset();
+    store.reset();
+  }).then([this] {
+    return tp->stop();
+  });
+}
+
+AlienStore::~AlienStore() = default;
+
+seastar::future<> AlienStore::mount()
+{
+  logger().debug("{}", __func__);
+  return tp->submit([this] {
+    return store->mount();
+  }).then([] (int) {
+    return seastar::now();
+  });
+}
+
+seastar::future<> AlienStore::umount()
+{
+  logger().debug("{}", __func__);
+  return transaction_gate.close().then([this] {
+    return tp->submit([this] {
+      return store->umount();
+    });
+  }).then([] (int) {
+    return seastar::now();
+  });
+}
+
+seastar::future<> AlienStore::mkfs(uuid_d new_osd_fsid)
+{
+  logger().debug("{}", __func__);
+  osd_fsid = new_osd_fsid;
+  return tp->submit([this] {
+    return store->mkfs();
+  }).then([] (int) {
+    return seastar::now();
+  });
+}
+
+seastar::future<std::vector<ghobject_t>, ghobject_t>
+AlienStore::list_objects(CollectionRef ch,
+                        const ghobject_t& start,
+                        const ghobject_t& end,
+                        uint64_t limit) const
+{
+  logger().debug("{}", __func__);
+  return seastar::do_with(std::vector<ghobject_t>(), ghobject_t(),
+                          [=] (auto &objects, auto &next) {
+    objects.reserve(limit);
+    return tp->submit([=, &objects, &next] {
+      auto c = static_cast<AlienCollection*>(ch.get());
+      return store->collection_list(c->collection, start, end,
+                                    store->get_ideal_list_max(),
+                                    &objects, &next);
+    }).then([&objects, &next] (int) {
+      return seastar::make_ready_future<std::vector<ghobject_t>, ghobject_t>(
+                                         std::move(objects), std::move(next));
+    });
+  });
+}
+
+seastar::future<CollectionRef> AlienStore::create_new_collection(const coll_t& cid)
+{
+  logger().debug("{}", __func__);
+  return tp->submit([this, cid] {
+    return store->create_new_collection(cid);
+  }).then([this, cid] (ObjectStore::CollectionHandle c) {
+    CollectionRef ch;
+    auto cp = coll_map.find(c->cid);
+    if (cp == coll_map.end()) {
+      ch = new AlienCollection(c);
+      coll_map[c->cid] = ch;
+    } else {
+      ch = cp->second;
+      auto ach = static_cast<AlienCollection*>(ch.get());
+      if (ach->collection != c) {
+        ach->collection = c;
+      }
+    }
+    return seastar::make_ready_future<CollectionRef>(ch);
+  });
+
+}
+
+seastar::future<CollectionRef> AlienStore::open_collection(const coll_t& cid)
+{
+  logger().debug("{}", __func__);
+    return tp->submit([this, cid] {
+    return store->open_collection(cid);
+  }).then([this] (ObjectStore::CollectionHandle c) {
+    CollectionRef ch;
+    auto cp = coll_map.find(c->cid);
+    if (cp == coll_map.end()){
+      ch = new AlienCollection(c);
+      coll_map[c->cid] = ch;
+    } else {
+      ch = cp->second;
+      auto ach = static_cast<AlienCollection*>(ch.get());
+      if (ach->collection != c){
+        ach->collection = c;
+      }
+    }
+    return seastar::make_ready_future<CollectionRef>(ch);
+  });
+}
+
+seastar::future<std::vector<coll_t>> AlienStore::list_collections()
+{
+  logger().debug("{}", __func__);
+
+  return seastar::do_with(std::vector<coll_t>{}, [=] (auto &ls) {
+    return tp->submit([this, &ls] {
+      return store->list_collections(ls);
+    }).then([&ls] (int) {
+      return seastar::make_ready_future<std::vector<coll_t>>(std::move(ls));
+    });
+  });
+}
+
+AlienStore::read_errorator::future<ceph::bufferlist>
+AlienStore::read(CollectionRef ch,
+                 const ghobject_t& oid,
+                 uint64_t offset,
+                 size_t len,
+                 uint32_t op_flags)
+{
+  logger().debug("{}", __func__);
+  return seastar::do_with(ceph::bufferlist{}, [=] (auto &bl) {
+    return tp->submit([=, &bl] {
+      auto c = static_cast<AlienCollection*>(ch.get());
+      return store->read(c->collection, oid, offset, len, bl, op_flags);
+    }).then([&bl] (int r) -> read_errorator::future<ceph::bufferlist> {
+      if (r == -ENOENT) {
+        return crimson::ct_error::enoent::make();
+      } else if (r == -EIO) {
+        return crimson::ct_error::input_output_error::make();
+      } else {
+        return read_errorator::make_ready_future<ceph::bufferlist>(std::move(bl));
+      }
+    });
+  });
+}
+
+AlienStore::get_attr_errorator::future<ceph::bufferptr>
+AlienStore::get_attr(CollectionRef ch,
+                     const ghobject_t& oid,
+                     std::string_view name) const
+{
+  logger().debug("{}", __func__);
+  return seastar::do_with(ceph::bufferptr{}, [=] (auto &value) {
+    return tp->submit([=, &value] {
+      auto c =static_cast<AlienCollection*>(ch.get());
+      return store->getattr(c->collection, oid,
+                           static_cast<std::string>(name).c_str(), value);
+    }).then([oid, name, &value] (int r) -> get_attr_errorator::future<ceph::bufferptr> {
+      if (r == -ENOENT) {
+        return crimson::ct_error::enoent::make();
+      } else if (r == -ENODATA) {
+        return crimson::ct_error::enodata::make();
+      } else {
+        return get_attr_errorator::make_ready_future<ceph::bufferptr>(
+          std::move(value));
+      }
+    });
+  });
+}
+
+AlienStore::get_attrs_ertr::future<AlienStore::attrs_t>
+AlienStore::get_attrs(CollectionRef ch,
+                      const ghobject_t& oid)
+{
+  logger().debug("{}", __func__);
+  return seastar::do_with(attrs_t{}, [=] (auto &aset) {
+    return tp->submit([=, &aset] {
+      auto c = static_cast<AlienCollection*>(ch.get());
+      return store->getattrs(c->collection, oid,
+                            reinterpret_cast<map<string,bufferptr>&>(aset));
+    }).then([&aset] (int r) -> get_attrs_ertr::future<attrs_t> {
+      if (r == -ENOENT) {
+        return crimson::ct_error::enoent::make();;
+      } else {
+        return get_attrs_ertr::make_ready_future<attrs_t>(std::move(aset));
+      }
+    });
+  });
+}
+
+seastar::future<AlienStore::omap_values_t>
+AlienStore::omap_get_values(CollectionRef ch,
+                       const ghobject_t& oid,
+                       const set<string>& keys)
+{
+  logger().debug("{}", __func__);
+  return seastar::do_with(omap_values_t{}, [=] (auto &values) {
+    return tp->submit([=, &values] {
+      auto c = static_cast<AlienCollection*>(ch.get());
+      return store->omap_get_values(c->collection, oid, keys,
+                                   reinterpret_cast<map<string, bufferlist>*>(&values));
+    }).then([&values] (int) {
+      return seastar::make_ready_future<omap_values_t>(std::move(values));
+    });
+  });
+}
+
+seastar::future<bool, AlienStore::omap_values_t>
+AlienStore::omap_get_values(CollectionRef ch,
+                            const ghobject_t &oid,
+                            const std::optional<string> &start)
+{
+  logger().debug("{} with_start", __func__);
+  return seastar::do_with(omap_values_t{}, [=] (auto &values) {
+    return tp->submit([=, &values] {
+      auto c = static_cast<AlienCollection*>(ch.get());
+      return store->omap_get_values(c->collection, oid, start,
+                                   reinterpret_cast<map<string, bufferlist>*>(&values));
+    }).then([&values] (int r) {
+      return seastar::make_ready_future<bool, omap_values_t>(true, std::move(values));
+    });
+  });
+}
+
+seastar::future<> AlienStore::do_transaction(CollectionRef ch,
+                                             ceph::os::Transaction&& txn)
+{
+  logger().debug("{}", __func__);
+  auto callback =
+    std::make_unique<OnCommit>(seastar::engine().cpu_id(), txn);
+  return seastar::do_with(std::move(txn), std::move(callback),
+      [this, ch] (ceph::os::Transaction &txn, auto &callback) {
+    return seastar::with_gate(transaction_gate, [this, ch, &txn, &callback] {
+      return tp_mutex.lock().then ([this, ch, &txn, &callback] {
+        return tp->submit([=, &txn, &callback] {
+          txn.register_on_commit(callback.get());
+          auto c = static_cast<AlienCollection*>(ch.get());
+          return store->queue_transaction(c->collection, std::move(txn));
+        });
+      }).then([this, &callback] (int) {
+       tp_mutex.unlock();
+        return callback->alien_done.get_future();
+      });
+    });
+  });
+}
+
+seastar::future<> AlienStore::write_meta(const std::string& key,
+                                         const std::string& value)
+{
+  logger().debug("{}", __func__);
+  return tp->submit([=] {
+    return store->write_meta(key, value);
+  }).then([] (int) {
+    return seastar::make_ready_future<>();
+  });
+}
+
+seastar::future<int, std::string> AlienStore::read_meta(const std::string& key)
+{
+  logger().debug("{}", __func__);
+  return tp->submit([this, key] {
+    std::string value;
+    int r = store->read_meta(key, &value);
+    if (r > 0) {
+      value.resize(r);
+      boost::algorithm::trim_right_if(value,
+        [] (unsigned char c) {return isspace(c);});
+    } else {
+      value.clear();
+    }
+    return std::make_pair(r, value);
+  }).then([] (auto entry) {
+    return seastar::make_ready_future<int, std::string>(entry.first, entry.second);
+  });
+}
+
+uuid_d AlienStore::get_fsid() const
+{
+  logger().debug("{}", __func__);
+  return osd_fsid;
+}
+
+seastar::future<store_statfs_t> AlienStore::stat() const
+{
+  logger().info("{}", __func__);
+  return seastar::do_with(store_statfs_t{}, [this] (store_statfs_t &st) {
+    return tp->submit([this, &st] {
+      return store->statfs(&st, nullptr);
+    }).then([&st] (int) {
+      return seastar::make_ready_future<store_statfs_t>(std::move(st));
+    });
+  });
+}
+
+unsigned AlienStore::get_max_attr_name_length() const
+{
+  logger().info("{}", __func__);
+  return 256;
+}
+
+}
diff --git a/src/crimson/os/alienstore/alien_store.h b/src/crimson/os/alienstore/alien_store.h
new file mode 100644 (file)
index 0000000..d8dd155
--- /dev/null
@@ -0,0 +1,89 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <seastar/core/future.hh>
+#include <seastar/core/shared_mutex.hh>
+
+#include "common/ceph_context.h"
+#include "os/ObjectStore.h"
+#include "osd/osd_types.h"
+
+#include "crimson/os/futurized_collection.h"
+#include "crimson/os/futurized_store.h"
+#include "crimson/thread/ThreadPool.h"
+
+namespace ceph::os {
+class Transaction;
+}
+
+namespace crimson::os {
+class AlienStore final : public FuturizedStore {
+public:
+  mutable std::unique_ptr<crimson::thread::ThreadPool> tp;
+  AlienStore(const std::string& path, const ConfigValues& values);
+  ~AlienStore() final;
+
+  seastar::future<> start() final;
+  seastar::future<> stop() final;
+  seastar::future<> mount() final;
+  seastar::future<> umount() final;
+
+  seastar::future<> mkfs(uuid_d new_osd_fsid) final;
+  read_errorator::future<ceph::bufferlist> read(CollectionRef c,
+                                   const ghobject_t& oid,
+                                   uint64_t offset,
+                                   size_t len,
+                                   uint32_t op_flags = 0) final;
+
+  get_attr_errorator::future<ceph::bufferptr> get_attr(CollectionRef c,
+                                            const ghobject_t& oid,
+                                            std::string_view name) const final;
+  get_attrs_ertr::future<attrs_t> get_attrs(CollectionRef c,
+                                     const ghobject_t& oid) final;
+
+  seastar::future<omap_values_t> omap_get_values(
+    CollectionRef c,
+    const ghobject_t& oid,
+    const omap_keys_t& keys) final;
+
+  seastar::future<std::vector<ghobject_t>, ghobject_t> list_objects(
+    CollectionRef c,
+    const ghobject_t& start,
+    const ghobject_t& end,
+    uint64_t limit) const final;
+
+  /// Retrieves paged set of values > start (if present)
+  seastar::future<bool, omap_values_t> omap_get_values(
+    CollectionRef c,           ///< [in] collection
+    const ghobject_t &oid,     ///< [in] oid
+    const std::optional<std::string> &start ///< [in] start, empty for begin
+    ) final; ///< @return <done, values> values.empty() iff done
+
+  seastar::future<CollectionRef> create_new_collection(const coll_t& cid) final;
+  seastar::future<CollectionRef> open_collection(const coll_t& cid) final;
+  seastar::future<std::vector<coll_t>> list_collections() final;
+
+  seastar::future<> do_transaction(CollectionRef c,
+                                   ceph::os::Transaction&& txn) final;
+
+  seastar::future<> write_meta(const std::string& key,
+                  const std::string& value) final;
+  seastar::future<int, std::string> read_meta(const std::string& key) final;
+  uuid_d get_fsid() const final;
+  seastar::future<store_statfs_t> stat() const final;
+  unsigned get_max_attr_name_length() const final;
+
+private:
+  constexpr static unsigned MAX_KEYS_PER_OMAP_GET_CALL = 32;
+  const std::string path;
+  uint64_t used_bytes = 0;
+  uuid_d osd_fsid;
+  std::unique_ptr<ObjectStore> store;
+  std::unique_ptr<CephContext> cct;
+  seastar::gate transaction_gate;
+  std::unordered_map<coll_t, CollectionRef> coll_map;
+  seastar::shared_mutex tp_mutex;
+};
+}
index b08859a43196de8c109a83312fc2362e50ac0cd5..0269c133957e35145cc74949c79dbec7dcde9c08 100644 (file)
@@ -416,6 +416,7 @@ seastar::future<> CyanStore::do_transaction(CollectionRef ch,
       t.get_on_applied_sync()}) {
     if (i) {
       i->complete(0);
+      delete i;
     }
   }
   return seastar::now();
index 0e535396b426a0799d43565f4568bbca326163ff..bb73c34787f126e7cd36c36dd79f195c5545a525 100644 (file)
@@ -1,14 +1,18 @@
 #include "futurized_store.h"
 #include "cyanstore/cyan_store.h"
+#include "alienstore/alien_store.h"
 
 namespace crimson::os {
 
 std::unique_ptr<FuturizedStore>
 FuturizedStore::create(const std::string& type,
-                       const std::string& data)
+                       const std::string& data,
+                       const ConfigValues& values)
 {
   if (type == "memstore") {
     return std::make_unique<crimson::os::CyanStore>(data);
+  } else if (type == "bluestore") {
+    return std::make_unique<crimson::os::AlienStore>(data, values);
   } else {
     ceph_abort_msgf("unsupported objectstore type: %s", type.c_str());
     return {};
index 6bc228a00d0030a6e7cda2669d84072f045dbbc1..5bc9d775bf3c39572665aec56ae45dd47d45ebf7 100644 (file)
@@ -27,7 +27,8 @@ class FuturizedStore {
 
 public:
   static std::unique_ptr<FuturizedStore> create(const std::string& type,
-                                                const std::string& data);
+                                                const std::string& data,
+                                                const ConfigValues& values);
   FuturizedStore() = default;
   virtual ~FuturizedStore() = default;
 
index 147e6b9d3d8d355e958e7291a307dce2c00afbcc..935114a730916df7c8ba11238cf52605aadcee7b 100644 (file)
@@ -68,7 +68,8 @@ OSD::OSD(int id, uint32_t nonce,
     mgrc{new crimson::mgr::Client{*public_msgr, *this}},
     store{crimson::os::FuturizedStore::create(
       local_conf().get_val<std::string>("osd_objectstore"),
-      local_conf().get_val<std::string>("osd_data"))},
+      local_conf().get_val<std::string>("osd_data"),
+      local_conf().get_config_values())},
     shard_services{*this, *cluster_msgr, *public_msgr, *monc, *mgrc, *store},
     heartbeat{new Heartbeat{shard_services, *monc, hb_front_msgr, hb_back_msgr}},
     // do this in background
index f6c2672371fc0728878073620b0fe826da5a6a3c..b1e37bfbe595e06893cff8ccb2046a0d027d3000 100644 (file)
@@ -16,7 +16,7 @@
 
 #include <string.h>
 #include "common/ceph_context.h"
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #include "crimson/common/config_proxy.h"
 #endif
 
@@ -27,7 +27,7 @@
 namespace TOPNSPC::global {
 CephContext *g_ceph_context = NULL;
 ConfigProxy& g_conf() {
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
   return crimson::common::local_conf();
 #else
   return g_ceph_context->_conf;
index 6d39be55ba1a25fa0703a98fb6282a1c939c5746..26533b544993224e20885840b6188ff3b6d44311 100644 (file)
@@ -75,7 +75,9 @@ class Context {
   virtual ~Context() {}       // we want a virtual destructor!!!
   virtual void complete(int r) {
     finish(r);
-    delete this;
+#ifndef WITH_SEASTAR
+    delete this;   //alien store need its callback fun alive to get future.
+#endif
   }
   virtual bool sync_complete(int r) {
     if (sync_finish(r)) {
index e7ed9cae6a352021190c1787b7a8bb50c815e37e..d906aadfa460314f2727508e7ea2db5348f5138f 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#ifdef WITH_SEASTAR
+#if defined(WITH_SEASTAR) && !defined(WITH_ALIEN)
 #define TOPNSPC crimson
 #else
 #define TOPNSPC ceph
index 05637f2a208dfaf571282d30cddd9c2b0517ba78..f0fb32c7231756b0f2ee5c90afd56d9f5d9fa7d9 100644 (file)
 #include "common/Formatter.h"
 #include "common/safe_io.h"
 
+#ifndef  WITH_SEASTAR
 #include "filestore/FileStore.h"
 #include "memstore/MemStore.h"
+#endif
 #if defined(WITH_BLUESTORE)
 #include "bluestore/BlueStore.h"
 #endif
+#ifndef WITH_SEASTAR
 #include "kstore/KStore.h"
+#endif
 
 ObjectStore *ObjectStore::create(CephContext *cct,
                                 const string& type,
@@ -30,16 +34,19 @@ ObjectStore *ObjectStore::create(CephContext *cct,
                                 const string& journal,
                                 osflagbits_t flags)
 {
+#ifndef WITH_SEASTAR
   if (type == "filestore") {
     return new FileStore(cct, data, journal, flags);
   }
   if (type == "memstore") {
     return new MemStore(cct, data);
   }
+#endif
 #if defined(WITH_BLUESTORE)
   if (type == "bluestore") {
     return new BlueStore(cct, data);
   }
+#ifndef WITH_SEASTAR
   if (type == "random") {
     if (rand() % 2) {
       return new FileStore(cct, data, journal, flags);
@@ -47,15 +54,20 @@ ObjectStore *ObjectStore::create(CephContext *cct,
       return new BlueStore(cct, data);
     }
   }
+#endif
 #else
+#ifndef WITH_SEASTAR
   if (type == "random") {
     return new FileStore(cct, data, journal, flags);
   }
 #endif
+#endif
+#ifndef WITH_SEASTAR
   if (type == "kstore" &&
       cct->check_experimental_feature_enabled("kstore")) {
     return new KStore(cct, data);
   }
+#endif
   return NULL;
 }
 
@@ -77,6 +89,7 @@ int ObjectStore::probe_block_device_fsid(
   }
 #endif
 
+#ifndef WITH_SEASTAR
   // okay, try FileStore (journal).
   r = FileStore::get_block_device_fsid(cct, path, fsid);
   if (r == 0) {
@@ -84,6 +97,7 @@ int ObjectStore::probe_block_device_fsid(
                          << *fsid << dendl;
     return r;
   }
+#endif
 
   return -EINVAL;
 }
index ea4170d786c5b283379a2b2427eaa3a8cce5d58a..832f6b85393f84569feb60b7fe8e98b85b3fc7ee 100644 (file)
@@ -125,12 +125,13 @@ BlockDevice *BlockDevice::create(CephContext* cct, const string& path,
     return new KernelDevice(cct, cb, cbpriv, d_cb, d_cbpriv);
   }
 #endif
+#ifndef WITH_SEASTAR
 #if defined(HAVE_SPDK)
   if (type == "ust-nvme") {
     return new NVMEDevice(cct, cb, cbpriv);
   }
 #endif
-
+#endif
 
   derr << __func__ << " unknown backend " << type << dendl;
   ceph_abort();