using namespace crimson::os;
using namespace crimson::os::seastore;
-class EphemeralTestState {
-protected:
+class EphemeralDevices {
+public:
+ virtual seastar::future<> setup() = 0;
+ virtual void remount() = 0;
+ virtual std::size_t get_num_devices() const = 0;
+ virtual void reset() = 0;
+ virtual std::vector<Device*> get_secondary_devices() = 0;
+ virtual ~EphemeralDevices() {}
+ virtual Device* get_primary_device() = 0;
+ virtual DeviceRef get_primary_device_ref() = 0;
+};
+using EphemeralDevicesRef = std::unique_ptr<EphemeralDevices>;
+
+class EphemeralSegmentedDevices : public EphemeralDevices {
segment_manager::EphemeralSegmentManagerRef segment_manager;
std::list<segment_manager::EphemeralSegmentManagerRef> secondary_segment_managers;
- 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_device_managers) {
+public:
+ EphemeralSegmentedDevices(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 {
- 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;
-
- virtual void _destroy() = 0;
- virtual seastar::future<> _teardown() = 0;
- seastar::future<> teardown() {
- return _teardown().then([this] {
- _destroy();
- });
- }
-
-
- virtual FuturizedStore::mkfs_ertr::future<> _mkfs() = 0;
- virtual FuturizedStore::mount_ertr::future<> _mount() = 0;
-
- seastar::future<> restart_fut() {
- LOG_PREFIX(EphemeralTestState::restart_fut);
- SUBINFO(test, "begin ...");
- return teardown().then([this] {
- 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{});
- }).then([FNAME] {
- SUBINFO(test, "finish");
- });
}
- void restart() {
- restart_fut().get0();
- }
-
- seastar::future<> segment_setup()
- {
- LOG_PREFIX(EphemeralTestState::segment_setup);
+ seastar::future<> setup() final {
segment_manager = segment_manager::create_test_ephemeral();
for (auto &sec_sm : secondary_segment_managers) {
sec_sm = segment_manager::create_test_ephemeral();
segment_manager::get_ephemeral_device_config(cnt, get_num_devices()));
});
});
- }).safe_then([this] {
- _init();
- return _mkfs();
- }).safe_then([this] {
- return restart_fut();
}).handle_error(
crimson::ct_error::assert_all{}
- ).then([FNAME] {
- SUBINFO(test, "finish");
- });
+ );
+ }
+
+ void remount() final {
+ segment_manager->remount();
+ for (auto &sec_sm : secondary_segment_managers) {
+ sec_sm->remount();
+ }
}
- seastar::future<> randomblock_setup()
- {
- LOG_PREFIX(EphemeralTestState::randomblock_setup);
+ std::size_t get_num_devices() const final {
+ return secondary_segment_managers.size() + 1;
+ }
+
+ void reset() final {
+ segment_manager.reset();
+ for (auto &sec_sm : secondary_segment_managers) {
+ sec_sm.reset();
+ }
+ }
+
+ std::vector<Device*> get_secondary_devices() final {
+ std::vector<Device*> sec_devices;
+ for (auto &sec_sm : secondary_segment_managers) {
+ sec_devices.emplace_back(sec_sm.get());
+ }
+ return sec_devices;
+ }
+
+ Device* get_primary_device() final {
+ return segment_manager.get();
+ }
+ DeviceRef get_primary_device_ref() final;
+};
+
+class EphemeralRandomBlockDevices : public EphemeralDevices {
+ random_block_device::RBMDeviceRef rb_device;
+ std::list<random_block_device::RBMDeviceRef> secondary_rb_devices;
+
+public:
+ EphemeralRandomBlockDevices(std::size_t num_device_managers) {
+ assert(num_device_managers > 0);
+ secondary_rb_devices.resize(num_device_managers - 1);
+ }
+
+ seastar::future<> setup() final {
rb_device = random_block_device::create_test_ephemeral(
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);
rb_device->set_journal_size(journal::DEFAULT_TEST_CBJOURNAL_SIZE);
- return rb_device->mkfs(config).handle_error(crimson::ct_error::assert_all{}
- ).then([this]() {
- return segment_setup();
- });
+ return rb_device->mkfs(config).handle_error(crimson::ct_error::assert_all{});
});
}
+ void remount() final {}
+
+ std::size_t get_num_devices() const final {
+ return secondary_rb_devices.size() + 1;
+ }
+
+ void reset() final {
+ rb_device.reset();
+ for (auto &sec_rb : secondary_rb_devices) {
+ sec_rb.reset();
+ }
+ }
+
+ std::vector<Device*> get_secondary_devices() final {
+ std::vector<Device*> sec_devices;
+ for (auto &sec_rb : secondary_rb_devices) {
+ sec_devices.emplace_back(sec_rb.get());
+ }
+ return sec_devices;
+ }
+
+ Device* get_primary_device() final {
+ return rb_device.get();
+ }
+ DeviceRef get_primary_device_ref() final;
+};
+
+class EphemeralTestState {
+protected:
+ journal_type_t journal_type;
+ size_t num_device_managers = 0;
+ EphemeralDevicesRef devices;
+ EphemeralTestState(std::size_t num_device_managers) :
+ num_device_managers(num_device_managers) {}
+
+ virtual void _init() = 0;
+
+ virtual void _destroy() = 0;
+ virtual seastar::future<> _teardown() = 0;
+ seastar::future<> teardown() {
+ return _teardown().then([this] {
+ _destroy();
+ });
+ }
+
+ virtual FuturizedStore::mkfs_ertr::future<> _mkfs() = 0;
+ virtual FuturizedStore::mount_ertr::future<> _mount() = 0;
+
+ seastar::future<> restart_fut() {
+ LOG_PREFIX(EphemeralTestState::restart_fut);
+ SUBINFO(test, "begin ...");
+ return teardown().then([this] {
+ devices->remount();
+ _init();
+ return _mount().handle_error(crimson::ct_error::assert_all{});
+ }).then([FNAME] {
+ SUBINFO(test, "finish");
+ });
+ }
+
+ void restart() {
+ restart_fut().get0();
+ }
+
seastar::future<> tm_setup(
journal_type_t type = journal_type_t::SEGMENTED) {
LOG_PREFIX(EphemeralTestState::tm_setup);
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();
+ devices.reset(new EphemeralSegmentedDevices(num_device_managers));
} else {
assert(journal_type == journal_type_t::RANDOM_BLOCK);
- return randomblock_setup();
+ //TODO: multiple devices
+ ceph_assert(num_device_managers == 1);
+ devices.reset(new EphemeralRandomBlockDevices(1));
}
+ SUBINFO(test, "begin with {} devices ...", devices->get_num_devices());
+ return devices->setup(
+ ).then([this, FNAME]() {
+ _init();
+ return _mkfs(
+ ).safe_then([this] {
+ return restart_fut();
+ }).handle_error(
+ crimson::ct_error::assert_all{}
+ ).then([FNAME] {
+ SUBINFO(test, "finish");
+ });
+ });
}
seastar::future<> tm_teardown() {
LOG_PREFIX(EphemeralTestState::tm_teardown);
SUBINFO(test, "begin");
return teardown().then([this, FNAME] {
- segment_manager.reset();
- for (auto &sec_sm : secondary_segment_managers) {
- sec_sm.reset();
- }
- rb_device.reset();
- for (auto &sec_rb : secondary_rb_devices) {
- sec_rb.reset();
- }
+ devices->reset();
SUBINFO(test, "finish");
});
}
TMTestState(std::size_t num_devices) : EphemeralTestState(num_devices) {}
virtual void _init() override {
- std::vector<Device*> sec_devices;
- 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
- 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);
- }
+ auto sec_devices = devices->get_secondary_devices();
+ auto p_dev = devices->get_primary_device();
+ tm = make_transaction_manager(p_dev, sec_devices, true);
epm = tm->get_epm();
lba_manager = tm->get_lba_manager();
cache = tm->get_cache();
~TestSegmentManagerWrapper() final {}
};
+DeviceRef EphemeralSegmentedDevices::get_primary_device_ref() {
+ return std::make_unique<TestSegmentManagerWrapper>(*segment_manager);
+}
+
+class TestRandomBlockDeviceWrapper final : public Device {
+ RBMDevice &rb_device;
+ device_id_t device_id = 0;
+ secondary_device_set_t set;
+public:
+ TestRandomBlockDeviceWrapper(
+ RBMDevice &rb_device,
+ device_id_t device_id = 0)
+ : rb_device(rb_device), device_id(device_id) {}
+
+ device_id_t get_device_id() const {
+ return device_id;
+ }
+
+ mount_ret mount() final {
+ return mount_ertr::now(); // we handle this above
+ }
+
+ mkfs_ret mkfs(device_config_t c) final {
+ return mkfs_ertr::now(); // we handle this above
+ }
+
+ close_ertr::future<> close() final {
+ return rb_device.close();
+ }
+
+ secondary_device_set_t& get_secondary_devices() final {
+ return rb_device.get_secondary_devices();
+ }
+
+ magic_t get_magic() const final {
+ return rb_device.get_magic();
+ }
+ read_ertr::future<> read(
+ paddr_t addr, size_t len, ceph::bufferptr &out) final {
+ return rb_device.read(addr, len, out);
+ }
+
+ size_t get_available_size() const final { return rb_device.get_available_size(); }
+ extent_len_t get_block_size() const final { return rb_device.get_block_size(); }
+ const seastore_meta_t &get_meta() const final {
+ return rb_device.get_meta();
+ }
+ device_type_t get_device_type() const final {
+ return device_type_t::RANDOM_BLOCK_SSD;
+ }
+
+ backend_type_t get_backend_type() const final {
+ return backend_type_t::RANDOM_BLOCK;
+ }
+
+ ~TestRandomBlockDeviceWrapper() final {}
+};
+
+DeviceRef EphemeralRandomBlockDevices::get_primary_device_ref() {
+ return std::make_unique<TestRandomBlockDeviceWrapper>(*rb_device);
+}
+
class SeaStoreTestState : public EphemeralTestState {
class TestMDStoreState {
std::map<std::string, std::string> md;
virtual void _init() final {
seastore = make_test_seastore(
- std::make_unique<TestSegmentManagerWrapper>(*segment_manager),
+ devices->get_primary_device_ref(),
std::make_unique<TestMDStoreState::Store>(mdstore_state.get_mdstore()));
}