diff --git a/src/blockstore/blockstore.cpp b/src/blockstore/blockstore.cpp index 645580c3..65d8ad33 100644 --- a/src/blockstore/blockstore.cpp +++ b/src/blockstore/blockstore.cpp @@ -3,98 +3,7 @@ #include "blockstore_impl.h" -blockstore_t::blockstore_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd) +blockstore_i* blockstore_i::create(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd) { - impl = new blockstore_impl_t(config, ringloop, tfd); -} - -blockstore_t::~blockstore_t() -{ - delete impl; -} - -void blockstore_t::parse_config(blockstore_config_t & config) -{ - impl->parse_config(config, false); -} - -void blockstore_t::loop() -{ - impl->loop(); -} - -bool blockstore_t::is_started() -{ - return impl->is_started(); -} - -bool blockstore_t::is_stalled() -{ - return impl->is_stalled(); -} - -bool blockstore_t::is_safe_to_stop() -{ - return impl->is_safe_to_stop(); -} - -void blockstore_t::enqueue_op(blockstore_op_t *op) -{ - impl->enqueue_op(op); -} - -int blockstore_t::read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version) -{ - return impl->read_bitmap(oid, target_version, bitmap, result_version); -} - -const std::map & blockstore_t::get_inode_space_stats() -{ - return impl->get_inode_space_stats(); -} - -void blockstore_t::dump_diagnostics() -{ - return impl->dump_diagnostics(); -} - -std::string blockstore_t::get_op_diag(blockstore_op_t *op) -{ - char buf[256]; - auto priv = PRIV(op); - if (priv->wait_for) - snprintf(buf, sizeof(buf), "state=%d wait=%d (detail=%ju)", priv->op_state, priv->wait_for, priv->wait_detail); - else - snprintf(buf, sizeof(buf), "state=%d", priv->op_state); - return std::string(buf); -} - -uint32_t blockstore_t::get_block_size() -{ - return impl->get_block_size(); -} - -uint64_t blockstore_t::get_block_count() -{ - return impl->get_block_count(); -} - -uint64_t blockstore_t::get_free_block_count() -{ - return impl->get_free_block_count(); -} - -uint64_t blockstore_t::get_journal_size() -{ - return impl->get_journal_size(); -} - -uint32_t blockstore_t::get_bitmap_granularity() -{ - return impl->get_bitmap_granularity(); -} - -void blockstore_t::set_no_inode_stats(const std::vector & pool_ids) -{ - impl->set_no_inode_stats(pool_ids); + return new blockstore_impl_t(config, ringloop, tfd); } diff --git a/src/blockstore/blockstore.h b/src/blockstore/blockstore.h index f72d9326..d6b5e51d 100644 --- a/src/blockstore/blockstore.h +++ b/src/blockstore/blockstore.h @@ -173,56 +173,54 @@ struct __attribute__ ((visibility("default"))) blockstore_op_t typedef std::map blockstore_config_t; -class blockstore_impl_t; - -class __attribute__((visibility("default"))) blockstore_t +class __attribute__((visibility("default"))) blockstore_i { - blockstore_impl_t *impl; public: - blockstore_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd); - ~blockstore_t(); + static blockstore_i* create(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd); + + virtual ~blockstore_i() = default; // Update configuration - void parse_config(blockstore_config_t & config); + virtual void parse_config(blockstore_config_t & config) = 0; // Event loop - void loop(); + virtual void loop() = 0; // Returns true when blockstore is ready to process operations // (Although you're free to enqueue them before that) - bool is_started(); + virtual bool is_started() = 0; // Returns true when blockstore is stalled - bool is_stalled(); + virtual bool is_stalled() = 0; // Returns true when it's safe to destroy the instance. If destroying the instance // requires to purge some queues, starts that process. Should be called in the event // loop until it returns true. - bool is_safe_to_stop(); + virtual bool is_safe_to_stop() = 0; // Submission - void enqueue_op(blockstore_op_t *op); + virtual void enqueue_op(blockstore_op_t *op) = 0; // Simplified synchronous operation: get object bitmap & current version - int read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version = NULL); + virtual int read_bitmap(object_id oid, uint64_t target_version, void *bitmap, uint64_t *result_version = NULL) = 0; // Get per-inode space usage statistics - const std::map & get_inode_space_stats(); + virtual const std::map & get_inode_space_stats() = 0; // Set per-pool no_inode_stats - void set_no_inode_stats(const std::vector & pool_ids); + virtual void set_no_inode_stats(const std::vector & pool_ids) = 0; // Print diagnostics to stdout - void dump_diagnostics(); + virtual void dump_diagnostics() = 0; // Get diagnostic string for an operation - std::string get_op_diag(blockstore_op_t *op); + virtual std::string get_op_diag(blockstore_op_t *op) = 0; - uint32_t get_block_size(); - uint64_t get_block_count(); - uint64_t get_free_block_count(); + virtual uint32_t get_block_size() = 0; + virtual uint64_t get_block_count() = 0; + virtual uint64_t get_free_block_count() = 0; - uint64_t get_journal_size(); + virtual uint64_t get_journal_size() = 0; - uint32_t get_bitmap_granularity(); + virtual uint32_t get_bitmap_granularity() = 0; }; diff --git a/src/blockstore/blockstore_impl.cpp b/src/blockstore/blockstore_impl.cpp index e9bf569b..7f81c56f 100644 --- a/src/blockstore/blockstore_impl.cpp +++ b/src/blockstore/blockstore_impl.cpp @@ -792,3 +792,14 @@ void blockstore_impl_t::recalc_inode_space_stats(uint64_t pool_id, bool per_inod dirty_it++; } } + +std::string blockstore_impl_t::get_op_diag(blockstore_op_t *op) +{ + char buf[256]; + auto priv = PRIV(op); + if (priv->wait_for) + snprintf(buf, sizeof(buf), "state=%d wait=%d (detail=%ju)", priv->op_state, priv->wait_for, priv->wait_detail); + else + snprintf(buf, sizeof(buf), "state=%d", priv->op_state); + return std::string(buf); +} diff --git a/src/blockstore/blockstore_impl.h b/src/blockstore/blockstore_impl.h index 465df7fc..50259237 100644 --- a/src/blockstore/blockstore_impl.h +++ b/src/blockstore/blockstore_impl.h @@ -196,7 +196,7 @@ struct pool_shard_settings_t #define STAB_SPLIT_SYNC 3 #define STAB_SPLIT_TODO 4 -class blockstore_impl_t +class blockstore_impl_t: public blockstore_i { blockstore_disk_t dsk; @@ -361,6 +361,7 @@ public: blockstore_impl_t(blockstore_config_t & config, ring_loop_t *ringloop, timerfd_manager_t *tfd); ~blockstore_impl_t(); + void parse_config(blockstore_config_t & config); void parse_config(blockstore_config_t & config, bool init); // Event loop @@ -396,6 +397,9 @@ public: // Print diagnostics to stdout void dump_diagnostics(); + // Get diagnostic string for an operation + std::string get_op_diag(blockstore_op_t *op); + inline uint32_t get_block_size() { return dsk.data_block_size; } inline uint64_t get_block_count() { return dsk.block_count; } inline uint64_t get_free_block_count() { return dsk.block_count - used_blocks; } diff --git a/src/blockstore/blockstore_journal.h b/src/blockstore/blockstore_journal.h index 5929c1c3..aa92db93 100644 --- a/src/blockstore/blockstore_journal.h +++ b/src/blockstore/blockstore_journal.h @@ -3,6 +3,8 @@ #pragma once +class blockstore_impl_t; + struct journal_sector_info_t { uint64_t offset; diff --git a/src/blockstore/blockstore_open.cpp b/src/blockstore/blockstore_open.cpp index 252c6f88..4341150e 100644 --- a/src/blockstore/blockstore_open.cpp +++ b/src/blockstore/blockstore_open.cpp @@ -4,6 +4,11 @@ #include #include "blockstore_impl.h" +void blockstore_impl_t::parse_config(blockstore_config_t & config) +{ + return parse_config(config, false); +} + void blockstore_impl_t::parse_config(blockstore_config_t & config, bool init) { // Online-configurable options: diff --git a/src/blockstore/fio_engine.cpp b/src/blockstore/fio_engine.cpp index 4ea3e600..ae938e82 100644 --- a/src/blockstore/fio_engine.cpp +++ b/src/blockstore/fio_engine.cpp @@ -32,7 +32,7 @@ struct bs_data { - blockstore_t *bs; + blockstore_i *bs; epoll_manager_t *epmgr; ring_loop_t *ringloop; /* The list of completed io_u structs. */ @@ -162,7 +162,7 @@ static int bs_init(struct thread_data *td) } bsd->ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE); bsd->epmgr = new epoll_manager_t(bsd->ringloop); - bsd->bs = new blockstore_t(config, bsd->ringloop, bsd->epmgr->tfd); + bsd->bs = blockstore_i::create(config, bsd->ringloop, bsd->epmgr->tfd); bsd->imm = config.find("immediate_commit") == config.end() || config["immediate_commit"] == "all"; while (1) diff --git a/src/osd/osd.cpp b/src/osd/osd.cpp index 86f1a734..e766e367 100644 --- a/src/osd/osd.cpp +++ b/src/osd/osd.cpp @@ -34,7 +34,7 @@ osd_t::osd_t(const json11::Json & config, ring_loop_t *ringloop) if (!json_is_true(this->config["disable_blockstore"])) { auto bs_cfg = json_to_string_map(this->config); - this->bs = new blockstore_t(bs_cfg, ringloop, tfd); + this->bs = blockstore_i::create(bs_cfg, ringloop, tfd); // Wait for blockstore initialisation before actually starting OSD logic // to prevent peering timeouts during restart with filled databases while (!bs->is_started()) diff --git a/src/osd/osd.h b/src/osd/osd.h index fc189f10..99bcbc5a 100644 --- a/src/osd/osd.h +++ b/src/osd/osd.h @@ -202,7 +202,7 @@ class osd_t bool stopping = false; int inflight_ops = 0; - blockstore_t *bs = NULL; + blockstore_i *bs = NULL; void *zero_buffer = NULL; uint64_t zero_buffer_size = 0; uint32_t bs_block_size, bs_bitmap_granularity, clean_entry_bitmap_size; diff --git a/src/test/test_blockstore.cpp b/src/test/test_blockstore.cpp index e8d5623b..89acb6ec 100644 --- a/src/test/test_blockstore.cpp +++ b/src/test/test_blockstore.cpp @@ -13,7 +13,7 @@ int main(int narg, char *args[]) config["data_device"] = "./test_data.bin"; ring_loop_t *ringloop = new ring_loop_t(RINGLOOP_DEFAULT_SIZE); epoll_manager_t *epmgr = new epoll_manager_t(ringloop); - blockstore_t *bs = new blockstore_t(config, ringloop, epmgr->tfd); + blockstore_i *bs = blockstore_i::create(config, ringloop, epmgr->tfd); blockstore_op_t op; int main_state = 0;