This commit adds init step for rbm ool before starting unittest-transaction-manager
Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
}
RBMCleaner::RBMCleaner(
+ RBMDeviceGroupRef&& rb_group,
BackrefManager &backref_manager,
bool detailed)
: detailed(detailed),
+ rb_group(std::move(rb_group)),
backref_manager(backref_manager)
{}
RBMCleaner::mount_ret RBMCleaner::mount()
{
stats = {};
- return mount_ertr::now();
+ return seastar::do_with(
+ rb_group->get_rb_managers(),
+ [](auto &rbs) {
+ return crimson::do_for_each(
+ rbs.begin(),
+ rbs.end(),
+ [](auto& it) {
+ return it->open(
+ ).handle_error(
+ crimson::ct_error::input_output_error::pass_further(),
+ crimson::ct_error::assert_all{
+ "Invalid error when opening RBM"}
+ );
+ });
+ });
}
}
#include "crimson/os/seastore/seastore_types.h"
#include "crimson/os/seastore/segment_manager.h"
#include "crimson/os/seastore/segment_manager_group.h"
+#include "crimson/os/seastore/randomblock_manager_group.h"
#include "crimson/os/seastore/transaction.h"
#include "crimson/os/seastore/segment_seq_allocator.h"
class RBMCleaner : public AsyncCleaner {
public:
RBMCleaner(
+ RBMDeviceGroupRef&& rb_group,
BackrefManager &backref_manager,
bool detailed);
static RBMCleanerRef create(
+ RBMDeviceGroupRef&& rb_group,
BackrefManager &backref_manager,
bool detailed) {
return std::make_unique<RBMCleaner>(
- backref_manager, detailed);
+ std::move(rb_group), backref_manager, detailed);
+ }
+
+ RBMDeviceGroup* get_rb_group() {
+ return rb_group.get();
}
/*
clean_space_ret clean_space() final;
+ RandomBlockManager* get_rbm(paddr_t paddr) {
+ auto rbs = rb_group->get_rb_managers();
+ for (auto p : rbs) {
+ if (p->get_device_id() == paddr.get_device_id()) {
+ return p;
+ }
+ }
+ return nullptr;
+ }
+
// Testing interfaces
bool check_usage() final {
private:
const bool detailed;
-
+ RBMDeviceGroupRef rb_group;
BackrefManager &backref_manager;
{
writer_refs.clear();
- auto segment_cleaner = dynamic_cast<SegmentCleaner*>(cleaner.get());
- ceph_assert(segment_cleaner != nullptr);
- auto num_writers = generation_to_writer(REWRITE_GENERATIONS);
- data_writers_by_gen.resize(num_writers, {});
- for (rewrite_gen_t gen = OOL_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
- writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
- data_category_t::DATA, gen, *segment_cleaner,
- segment_cleaner->get_ool_segment_seq_allocator()));
- data_writers_by_gen[generation_to_writer(gen)] = writer_refs.back().get();
- }
+ if (trimmer->get_journal_type() == journal_type_t::SEGMENTED) {
+ auto segment_cleaner = dynamic_cast<SegmentCleaner*>(cleaner.get());
+ ceph_assert(segment_cleaner != nullptr);
+ auto num_writers = generation_to_writer(REWRITE_GENERATIONS);
+ data_writers_by_gen.resize(num_writers, {});
+ for (rewrite_gen_t gen = OOL_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+ writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
+ data_category_t::DATA, gen, *segment_cleaner,
+ segment_cleaner->get_ool_segment_seq_allocator()));
+ data_writers_by_gen[generation_to_writer(gen)] = writer_refs.back().get();
+ }
- md_writers_by_gen.resize(num_writers, {});
- for (rewrite_gen_t gen = OOL_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
- writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
- data_category_t::METADATA, gen, *segment_cleaner,
- segment_cleaner->get_ool_segment_seq_allocator()));
- md_writers_by_gen[generation_to_writer(gen)] = writer_refs.back().get();
- }
+ md_writers_by_gen.resize(num_writers, {});
+ for (rewrite_gen_t gen = OOL_GENERATION; gen < REWRITE_GENERATIONS; ++gen) {
+ writer_refs.emplace_back(std::make_unique<SegmentedOolWriter>(
+ data_category_t::METADATA, gen, *segment_cleaner,
+ segment_cleaner->get_ool_segment_seq_allocator()));
+ md_writers_by_gen[generation_to_writer(gen)] = writer_refs.back().get();
+ }
- for (auto *device : segment_cleaner->get_segment_manager_group()
- ->get_segment_managers()) {
- add_device(device);
+ for (auto *device : segment_cleaner->get_segment_manager_group()
+ ->get_segment_managers()) {
+ add_device(device);
+ }
+ } else {
+ assert(trimmer->get_journal_type() == journal_type_t::RANDOM_BLOCK);
+ auto rb_cleaner = dynamic_cast<RBMCleaner*>(cleaner.get());
+ ceph_assert(rb_cleaner != nullptr);
+ auto num_writers = generation_to_writer(REWRITE_GENERATIONS);
+ data_writers_by_gen.resize(num_writers, {});
+ md_writers_by_gen.resize(num_writers, {});
+ writer_refs.emplace_back(std::make_unique<RandomBlockOolWriter>(
+ rb_cleaner));
+ // TODO: implement eviction in RBCleaner and introduce further writers
+ data_writers_by_gen[generation_to_writer(OOL_GENERATION)] = writer_refs.back().get();
+ md_writers_by_gen[generation_to_writer(OOL_GENERATION)] = writer_refs.back().get();
+ for (auto *rb : rb_cleaner->get_rb_group()->get_rb_managers()) {
+ add_device(rb->get_device());
+ }
}
background_process.init(std::move(trimmer), std::move(cleaner));
primary_device = device;
if (device->get_backend_type() == backend_type_t::SEGMENTED) {
prefer_ool = false;
- ceph_assert(devices_by_id[device->get_device_id()] == device);
} else {
- // RBM device is not in the cleaner.
ceph_assert(device->get_backend_type() == backend_type_t::RANDOM_BLOCK);
prefer_ool = true;
- add_device(primary_device);
}
+ ceph_assert(devices_by_id[device->get_device_id()] == device);
}
ExtentPlacementManager::open_ertr::future<>
INFO("started with {} devices", num_devices);
ceph_assert(primary_device != nullptr);
return crimson::do_for_each(data_writers_by_gen, [](auto &writer) {
- return writer->open();
+ if (writer) {
+ return writer->open();
+ }
+ return open_ertr::now();
}).safe_then([this] {
return crimson::do_for_each(md_writers_by_gen, [](auto &writer) {
- return writer->open();
+ if (writer) {
+ return writer->open();
+ }
+ return open_ertr::now();
});
});
}
LOG_PREFIX(ExtentPlacementManager::close);
INFO("started");
return crimson::do_for_each(data_writers_by_gen, [](auto &writer) {
- return writer->close();
+ if (writer) {
+ return writer->close();
+ }
+ return close_ertr::now();
}).safe_then([this] {
return crimson::do_for_each(md_writers_by_gen, [](auto &writer) {
- return writer->close();
+ if (writer) {
+ return writer->close();
+ }
+ return close_ertr::now();
});
});
}
#include "crimson/os/seastore/cached_extent.h"
#include "crimson/os/seastore/journal/segment_allocator.h"
#include "crimson/os/seastore/transaction.h"
+#include "crimson/os/seastore/random_block_manager.h"
+#include "crimson/os/seastore/random_block_manager/block_rb_manager.h"
+#include "crimson/os/seastore/randomblock_manager_group.h"
namespace crimson::os::seastore {
virtual extent_len_t get_block_size() const = 0;
virtual uint64_t get_free_blocks() const = 0;
virtual device_id_t get_device_id() const = 0;
+ virtual const seastore_meta_t &get_meta() const = 0;
+ virtual Device* get_device() = 0;
virtual ~RandomBlockManager() {}
};
using RandomBlockManagerRef = std::unique_ptr<RandomBlockManager>;
assert(device);
return get_size() / get_block_size();
}
+ const seastore_meta_t &get_meta() const final {
+ return device->get_meta();
+ }
+ RBMDevice* get_device() {
+ return device;
+ }
private:
/*
super.journal_size = size;
}
};
+using RBMDeviceRef = std::unique_ptr<RBMDevice>;
class EphemeralRBMDevice : public RBMDevice {
public:
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:nil -*-
+// vim: ts=8 sw=2 smarttab expandtab
+
+#pragma once
+
+#include <set>
+
+#include "crimson/common/errorator.h"
+#include "crimson/os/seastore/seastore_types.h"
+#include "crimson/os/seastore/random_block_manager.h"
+#include "crimson/os/seastore/random_block_manager/block_rb_manager.h"
+
+namespace crimson::os::seastore {
+
+class RBMDeviceGroup {
+public:
+ RBMDeviceGroup() {
+ rb_devices.resize(DEVICE_ID_MAX);
+ }
+
+ const std::set<device_id_t>& get_device_ids() const {
+ return device_ids;
+ }
+
+ std::vector<RandomBlockManager*> get_rb_managers() const {
+ assert(device_ids.size());
+ std::vector<RandomBlockManager*> ret;
+ for (auto& device_id : device_ids) {
+ auto rb_device = rb_devices[device_id].get();
+ assert(rb_device->get_device_id() == device_id);
+ ret.emplace_back(rb_device);
+ }
+ return ret;
+ }
+
+ void add_rb_manager(RandomBlockManagerRef rbm) {
+ auto device_id = rbm->get_device_id();
+ ceph_assert(!has_device(device_id));
+ rb_devices[device_id] = std::move(rbm);
+ device_ids.insert(device_id);
+ }
+
+ void reset() {
+ rb_devices.clear();
+ rb_devices.resize(DEVICE_ID_MAX);
+ device_ids.clear();
+ }
+
+ auto get_block_size() const {
+ assert(device_ids.size());
+ return rb_devices[*device_ids.begin()]->get_block_size();
+ }
+
+ const seastore_meta_t &get_meta() const {
+ assert(device_ids.size());
+ return rb_devices[*device_ids.begin()]->get_meta();
+ }
+
+private:
+ bool has_device(device_id_t id) const {
+ assert(id <= DEVICE_ID_MAX_VALID);
+ return device_ids.count(id) >= 1;
+ }
+
+ std::vector<RandomBlockManagerRef> rb_devices;
+ std::set<device_id_t> device_ids;
+};
+
+using RBMDeviceGroupRef = std::unique_ptr<RBMDeviceGroup>;
+
+}
auto cache = std::make_unique<Cache>(*epm);
auto lba_manager = lba_manager::create_lba_manager(*cache);
auto sms = std::make_unique<SegmentManagerGroup>();
+ auto rbs = std::make_unique<RBMDeviceGroup>();
auto backref_manager = create_backref_manager(*cache);
auto p_backend_type = primary_device->get_backend_type();
if (p_backend_type == backend_type_t::SEGMENTED) {
sms->add_segment_manager(static_cast<SegmentManager*>(primary_device));
+ } else {
+ auto rbm = std::make_unique<BlockRBManager>(
+ static_cast<RBMDevice*>(primary_device), "");
+ rbs->add_rb_manager(std::move(rbm));
}
for (auto &p_dev : secondary_devices) {
- ceph_assert(p_dev->get_backend_type() == backend_type_t::SEGMENTED);
- sms->add_segment_manager(static_cast<SegmentManager*>(p_dev));
+ if (p_dev->get_backend_type() == backend_type_t::SEGMENTED) {
+ sms->add_segment_manager(static_cast<SegmentManager*>(p_dev));
+ } else {
+ auto rbm = std::make_unique<BlockRBManager>(static_cast<RBMDevice*>(p_dev), "");
+ rbs->add_rb_manager(std::move(rbm));
+ }
}
auto journal_type = p_backend_type;
journal_type, roll_start, roll_size);
AsyncCleanerRef cleaner;
+ JournalRef journal;
if (journal_type == journal_type_t::SEGMENTED) {
cleaner = SegmentCleaner::create(
auto segment_cleaner = static_cast<SegmentCleaner*>(cleaner.get());
cache->set_segment_provider(*segment_cleaner);
segment_cleaner->set_journal_trimmer(*journal_trimmer);
- } else {
- cleaner = RBMCleaner::create(
- *backref_manager,
- cleaner_is_detailed);
- }
-
- JournalRef journal;
- if (journal_type == journal_type_t::SEGMENTED) {
- auto segment_cleaner = static_cast<SegmentCleaner*>(cleaner.get());
journal = journal::make_segmented(
*segment_cleaner,
*journal_trimmer);
} else {
+ cleaner = RBMCleaner::create(
+ std::move(rbs),
+ *backref_manager,
+ cleaner_is_detailed);
journal = journal::make_circularbounded(
*journal_trimmer,
static_cast<random_block_device::RBMDevice*>(primary_device),
}
bool check_usage() {
+ std::string j_type = GetParam();
+ if (j_type == "circularbounded") {
+ // TODO: add check_usage for RBM
+ return true;
+ }
return epm->check_usage();
}
protected:
segment_manager::EphemeralSegmentManagerRef segment_manager;
std::list<segment_manager::EphemeralSegmentManagerRef> secondary_segment_managers;
- std::unique_ptr<random_block_device::RBMDevice> rb_device;
+ random_block_device::RBMDeviceRef rb_device;
+ std::list<random_block_device::RBMDeviceRef> secondary_rb_devices;
journal_type_t journal_type;
- EphemeralTestState(std::size_t num_segment_managers) {
- assert(num_segment_managers > 0);
- secondary_segment_managers.resize(num_segment_managers - 1);
+ EphemeralTestState(std::size_t num_device_managers) {
+ assert(num_device_managers > 0);
+ secondary_segment_managers.resize(num_device_managers - 1);
+ secondary_rb_devices.resize(num_device_managers - 1);
}
std::size_t get_num_devices() const {
- return secondary_segment_managers.size() + 1;
+ if (journal_type == journal_type_t::SEGMENTED) {
+ return secondary_segment_managers.size() + 1;
+ } else {
+ assert(journal_type == journal_type_t::RANDOM_BLOCK);
+ return secondary_rb_devices.size() + 1;
+ }
}
virtual void _init() = 0;
LOG_PREFIX(EphemeralTestState::restart_fut);
SUBINFO(test, "begin ...");
return teardown().then([this] {
- segment_manager->remount();
- for (auto &sec_sm : secondary_segment_managers) {
- sec_sm->remount();
+ if (journal_type == journal_type_t::SEGMENTED) {
+ segment_manager->remount();
+ for (auto &sec_sm : secondary_segment_managers) {
+ sec_sm->remount();
+ }
}
_init();
return _mount().handle_error(crimson::ct_error::assert_all{});
seastar::future<> randomblock_setup()
{
+ LOG_PREFIX(EphemeralTestState::randomblock_setup);
rb_device = random_block_device::create_test_ephemeral(
- journal::DEFAULT_TEST_CBJOURNAL_SIZE, 0);
+ journal::DEFAULT_TEST_CBJOURNAL_SIZE, journal::DEFAULT_TEST_CBJOURNAL_SIZE);
return rb_device->mount().handle_error(crimson::ct_error::assert_all{}
).then([this]() {
device_config_t config = get_rbm_ephemeral_device_config(0, 1);
seastar::future<> tm_setup(
journal_type_t type = journal_type_t::SEGMENTED) {
LOG_PREFIX(EphemeralTestState::tm_setup);
- SUBINFO(test, "begin with {} devices ...", get_num_devices());
journal_type = type;
+ SUBINFO(test, "begin with {} devices ...", get_num_devices());
// FIXME: should not initialize segment_manager with circularbounded-journal
if (journal_type == journal_type_t::SEGMENTED) {
return segment_setup();
sec_sm.reset();
}
rb_device.reset();
+ for (auto &sec_rb : secondary_rb_devices) {
+ sec_rb.reset();
+ }
SUBINFO(test, "finish");
});
}
virtual void _init() override {
std::vector<Device*> sec_devices;
- for (auto &sec_sm : secondary_segment_managers) {
- sec_devices.emplace_back(sec_sm.get());
- }
if (journal_type == journal_type_t::RANDOM_BLOCK) {
// FIXME: should not initialize segment_manager with circularbounded-journal
// FIXME: no secondary device in the single device test
- sec_devices.emplace_back(segment_manager.get());
+ for (auto &sec_rb : secondary_rb_devices) {
+ sec_devices.emplace_back(sec_rb.get());
+ }
tm = make_transaction_manager(rb_device.get(), sec_devices, true);
} else {
+ for (auto &sec_sm : secondary_segment_managers) {
+ sec_devices.emplace_back(sec_sm.get());
+ }
tm = make_transaction_manager(segment_manager.get(), sec_devices, true);
}
epm = tm->get_epm();