]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
test/crimson: support multiple EphemeralSegmentManagers
authorYingxin Cheng <yingxin.cheng@intel.com>
Mon, 11 Apr 2022 12:40:03 +0000 (20:40 +0800)
committerYingxin Cheng <yingxin.cheng@intel.com>
Wed, 13 Apr 2022 05:17:11 +0000 (13:17 +0800)
Signed-off-by: Yingxin Cheng <yingxin.cheng@intel.com>
src/crimson/os/seastore/segment_manager/ephemeral.cc
src/crimson/os/seastore/segment_manager/ephemeral.h
src/test/crimson/seastore/test_btree_lba_manager.cc
src/test/crimson/seastore/test_seastore_cache.cc
src/test/crimson/seastore/test_seastore_journal.cc
src/test/crimson/seastore/transaction_manager_test_state.h

index 2123e3afb2c8358c4b65e592a9af4e3a0d429ea7..919155bebd1658c2a604ec4e3a59a2bb2c716be5 100644 (file)
@@ -29,6 +29,36 @@ EphemeralSegmentManagerRef create_test_ephemeral() {
     new EphemeralSegmentManager(DEFAULT_TEST_EPHEMERAL));
 }
 
+device_config_t get_ephemeral_device_config(
+    std::size_t index, std::size_t num_devices)
+{
+  assert(num_devices > index);
+  magic_t magic = 0xabcd;
+  auto type = device_type_t::SEGMENTED;
+  bool is_major_device;
+  secondary_device_set_t secondary_devices;
+  if (index == 0) {
+    is_major_device = true;
+    for (std::size_t secondary_index = index + 1;
+         secondary_index < num_devices;
+         ++secondary_index) {
+      device_id_t secondary_id = static_cast<device_id_t>(secondary_index);
+      secondary_devices.insert({
+        secondary_index, device_spec_t{magic, type, secondary_id}
+      });
+    }
+  } else { // index > 0
+    is_major_device = false;
+  }
+
+  device_id_t id = static_cast<device_id_t>(index);
+  seastore_meta_t meta = {};
+  return {is_major_device,
+          device_spec_t{magic, type, id},
+          meta,
+          secondary_devices};
+}
+
 EphemeralSegment::EphemeralSegment(
   EphemeralSegmentManager &manager, segment_id_t id)
   : manager(manager), id(id) {}
@@ -69,6 +99,16 @@ Segment::close_ertr::future<> EphemeralSegmentManager::segment_close(segment_id_
   });
 }
 
+EphemeralSegmentManager::mkfs_ret
+EphemeralSegmentManager::mkfs(device_config_t _config)
+{
+  logger().info(
+    "Mkfs ephemeral segment manager with {}",
+    _config);
+  device_config = _config;
+  return mkfs_ertr::now();
+}
+
 Segment::write_ertr::future<> EphemeralSegmentManager::segment_write(
   paddr_t addr,
   ceph::bufferlist bl,
@@ -94,12 +134,10 @@ Segment::write_ertr::future<> EphemeralSegmentManager::segment_write(
 
 EphemeralSegmentManager::init_ertr::future<> EphemeralSegmentManager::init()
 {
-  logger().debug(
+  logger().info(
     "Initing ephemeral segment manager with config {}",
     config);
 
-  meta = seastore_meta_t{};
-
   if (config.block_size % (4<<10) != 0) {
     return crimson::ct_error::invarg::make();
   }
index a57c87fc24b98c78da3a3bd14b442a8ef443e510..e282943626f1f7918809df08a3dc9cc6d8d3f438 100644 (file)
@@ -20,21 +20,21 @@ struct ephemeral_config_t {
   size_t size = 0;
   size_t block_size = 0;
   size_t segment_size = 0;
-  magic_t magic = 0;
-  device_id_t id = 0;
 };
 
 constexpr ephemeral_config_t DEFAULT_TEST_EPHEMERAL = {
   1 << 30,
   4 << 10,
-  8 << 20,
-  0xabcd,
-  0
+  8 << 20
 };
 
 std::ostream &operator<<(std::ostream &, const ephemeral_config_t &);
+
 EphemeralSegmentManagerRef create_test_ephemeral();
 
+device_config_t get_ephemeral_device_config(
+    std::size_t index, std::size_t num_devices);
+
 class EphemeralSegment final : public Segment {
   friend class EphemeralSegmentManager;
   EphemeralSegmentManager &manager;
@@ -57,7 +57,7 @@ class EphemeralSegmentManager final : public SegmentManager {
   using segment_state_t = Segment::segment_state_t;
 
   const ephemeral_config_t config;
-  std::optional<seastore_meta_t> meta;
+  std::optional<device_config_t> device_config;
 
   size_t get_offset(paddr_t addr) {
     auto& seg_addr = addr.as_seg_paddr();
@@ -71,8 +71,6 @@ class EphemeralSegmentManager final : public SegmentManager {
 
   Segment::close_ertr::future<> segment_close(segment_id_t id);
 
-  secondary_device_set_t sec_device_set;
-
 public:
   EphemeralSegmentManager(
     ephemeral_config_t config)
@@ -83,23 +81,16 @@ public:
     return close_ertr::now();
   }
 
-  device_id_t get_device_id() const {
-    return config.id;
+  device_id_t get_device_id() const final {
+    assert(device_config);
+    return device_config->spec.id;
   }
 
-  using init_ertr = crimson::errorator<
-    crimson::ct_error::enospc,
-    crimson::ct_error::invarg,
-    crimson::ct_error::erange>;
-  init_ertr::future<> init();
-
-  mount_ret mount() {
+  mount_ret mount() final {
     return mount_ertr::now();
   }
 
-  mkfs_ret mkfs(device_config_t) {
-    return mkfs_ertr::now();
-  }
+  mkfs_ret mkfs(device_config_t) final;
 
   open_ertr::future<SegmentRef> open(segment_id_t id) final;
 
@@ -121,18 +112,24 @@ public:
   }
 
   const seastore_meta_t &get_meta() const final {
-    assert(meta);
-    return *meta;
+    assert(device_config);
+    return device_config->meta;
   }
 
   secondary_device_set_t& get_secondary_devices() final {
-    return sec_device_set;
+    assert(device_config);
+    return device_config->secondary_devices;
   }
 
   magic_t get_magic() const final {
-    return config.magic;
+    return device_config->spec.magic;
   }
 
+  using init_ertr = crimson::errorator<
+    crimson::ct_error::enospc,
+    crimson::ct_error::invarg>;
+  init_ertr::future<> init();
+
   void remount();
 
   // public so tests can bypass segment interface when simpler
index 892e1bb806ca6554d6dd2384578a686a1e21cf2f..826cdc70f5280489deddc1f94f133fc5234642d2 100644 (file)
@@ -99,19 +99,22 @@ struct btree_test_base :
   virtual LBAManager::mkfs_ret test_structure_setup(Transaction &t) = 0;
   seastar::future<> set_up_fut() final {
     segment_manager = segment_manager::create_test_ephemeral();
-    sms.reset(new SegmentManagerGroup());
-    journal = journal::make_segmented(*this);
-    epm.reset(new ExtentPlacementManager());
-    cache.reset(new Cache(*epm));
-
-    block_size = segment_manager->get_block_size();
-    next = segment_id_t{segment_manager->get_device_id(), 0};
-    sms->add_segment_manager(segment_manager.get());
-    epm->add_device(segment_manager.get(), true);
-    journal->set_write_pipeline(&pipeline);
-
     return segment_manager->init(
     ).safe_then([this] {
+      return segment_manager->mkfs(
+        segment_manager::get_ephemeral_device_config(0, 1));
+    }).safe_then([this] {
+      sms.reset(new SegmentManagerGroup());
+      journal = journal::make_segmented(*this);
+      epm.reset(new ExtentPlacementManager());
+      cache.reset(new Cache(*epm));
+
+      block_size = segment_manager->get_block_size();
+      next = segment_id_t{segment_manager->get_device_id(), 0};
+      sms->add_segment_manager(segment_manager.get());
+      epm->add_device(segment_manager.get(), true);
+      journal->set_write_pipeline(&pipeline);
+
       return journal->open_for_write().discard_result();
     }).safe_then([this] {
       return epm->open();
index 5840739448bef66103b69cc02b1addc28182d53c..e778c5c62efb3a215fad8a060178cb89ea46615b 100644 (file)
@@ -83,12 +83,15 @@ struct cache_test_t : public seastar_test_suite_t {
 
   seastar::future<> set_up_fut() final {
     segment_manager = segment_manager::create_test_ephemeral();
-    epm.reset(new ExtentPlacementManager());
-    cache.reset(new Cache(*epm));
-    current = paddr_t::make_seg_paddr(segment_id_t(segment_manager->get_device_id(), 0), 0);
-    epm->add_device(segment_manager.get(), true);
     return segment_manager->init(
     ).safe_then([this] {
+      return segment_manager->mkfs(
+        segment_manager::get_ephemeral_device_config(0, 1));
+    }).safe_then([this] {
+      epm.reset(new ExtentPlacementManager());
+      cache.reset(new Cache(*epm));
+      current = paddr_t::make_seg_paddr(segment_id_t(segment_manager->get_device_id(), 0), 0);
+      epm->add_device(segment_manager.get(), true);
       return seastar::do_with(
           get_transaction(),
           [this](auto &ref_t) {
index ba173bab0d6eefa314850f67d8966f0b80611f40..0c65e3a3ca10b72f796b56a1eecbdd63dcbc88ad 100644 (file)
@@ -126,14 +126,17 @@ struct journal_test_t : seastar_test_suite_t, SegmentProvider {
 
   seastar::future<> set_up_fut() final {
     segment_manager = segment_manager::create_test_ephemeral();
-    block_size = segment_manager->get_block_size();
-    sms.reset(new SegmentManagerGroup());
-    next = segment_id_t(segment_manager->get_device_id(), 0);
-    journal = journal::make_segmented(*this);
-    journal->set_write_pipeline(&pipeline);
-    sms->add_segment_manager(segment_manager.get());
     return segment_manager->init(
     ).safe_then([this] {
+      return segment_manager->mkfs(
+        segment_manager::get_ephemeral_device_config(0, 1));
+    }).safe_then([this] {
+      block_size = segment_manager->get_block_size();
+      sms.reset(new SegmentManagerGroup());
+      next = segment_id_t(segment_manager->get_device_id(), 0);
+      journal = journal::make_segmented(*this);
+      journal->set_write_pipeline(&pipeline);
+      sms->add_segment_manager(segment_manager.get());
       return journal->open_for_write();
     }).safe_then(
       [](auto){},
index 356b55976bbdc4a2b061dc7389c879eab3cf5af0..73c8872982be244b15c0dc2c392ae715ff6a9832 100644 (file)
@@ -4,6 +4,7 @@
 #pragma once
 
 #include <random>
+#include <boost/iterator/counting_iterator.hpp>
 
 #include "crimson/os/seastore/segment_cleaner.h"
 #include "crimson/os/seastore/cache.h"
@@ -21,8 +22,16 @@ using namespace crimson::os::seastore;
 class EphemeralTestState {
 protected:
   segment_manager::EphemeralSegmentManagerRef segment_manager;
+  std::list<segment_manager::EphemeralSegmentManagerRef> secondary_segment_managers;
 
-  EphemeralTestState() = default;
+  EphemeralTestState(std::size_t num_segment_managers) {
+    assert(num_segment_managers > 0);
+    secondary_segment_managers.resize(num_segment_managers - 1);
+  }
+
+  std::size_t get_num_devices() const {
+    return secondary_segment_managers.size() + 1;
+  }
 
   virtual void _init() = 0;
   void init() {
@@ -41,23 +50,54 @@ protected:
   void restart() {
     _teardown().get0();
     destroy();
-    static_cast<segment_manager::EphemeralSegmentManager*>(&*segment_manager)->remount();
+    segment_manager->remount();
+    for (auto &sec_sm : secondary_segment_managers) {
+      sec_sm->remount();
+    }
     init();
     _mount().handle_error(crimson::ct_error::assert_all{}).get0();
   }
 
   seastar::future<> tm_setup() {
     segment_manager = segment_manager::create_test_ephemeral();
-    init();
+    for (auto &sec_sm : secondary_segment_managers) {
+      sec_sm = segment_manager::create_test_ephemeral();
+    }
     return segment_manager->init(
     ).safe_then([this] {
+      return crimson::do_for_each(
+        secondary_segment_managers.begin(),
+        secondary_segment_managers.end(),
+        [](auto &sec_sm)
+      {
+        return sec_sm->init();
+      });
+    }).safe_then([this] {
+      return segment_manager->mkfs(
+        segment_manager::get_ephemeral_device_config(0, get_num_devices()));
+    }).safe_then([this] {
+      return seastar::do_with(std::size_t(0), [this](auto &cnt) {
+        return crimson::do_for_each(
+          secondary_segment_managers.begin(),
+          secondary_segment_managers.end(),
+          [this, &cnt](auto &sec_sm)
+        {
+          ++cnt;
+          return sec_sm->mkfs(
+            segment_manager::get_ephemeral_device_config(cnt, get_num_devices()));
+        });
+      });
+    }).safe_then([this] {
+      init();
       return _mkfs();
     }).safe_then([this] {
       return _teardown();
     }).safe_then([this] {
       destroy();
-      static_cast<segment_manager::EphemeralSegmentManager*>(
-       &*segment_manager)->remount();
+      segment_manager->remount();
+      for (auto &sec_sm : secondary_segment_managers) {
+        sec_sm->remount();
+      }
       init();
       return _mount();
     }).handle_error(crimson::ct_error::assert_all{});
@@ -66,6 +106,9 @@ protected:
   seastar::future<> tm_teardown() {
     return _teardown().then([this] {
       segment_manager.reset();
+      for (auto &sec_sm : secondary_segment_managers) {
+        sec_sm.reset();
+      }
     });
   }
 };
@@ -89,7 +132,7 @@ protected:
   LBAManager *lba_manager;
   SegmentCleaner *segment_cleaner;
 
-  TMTestState() : EphemeralTestState() {}
+  TMTestState() : EphemeralTestState(1) {}
 
   virtual void _init() override {
     tm = make_transaction_manager(true);
@@ -258,7 +301,7 @@ class SeaStoreTestState : public EphemeralTestState {
 protected:
   std::unique_ptr<SeaStore> seastore;
 
-  SeaStoreTestState() : EphemeralTestState() {}
+  SeaStoreTestState() : EphemeralTestState(1) {}
 
   virtual void _init() final {
     seastore = get_seastore(