Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/include/homestore/homestore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,14 @@ class HomeStore {
unique< CrashSimulator > m_crash_simulator;
#endif

public:
/*** for metacli tool ***/
bool start_tool(const hs_input_params& input, const std::string& scan_type,
std::optional< uint16_t > debug_chunk_id = std::nullopt,
std::optional< blk_num_t > debug_blk_num = std::nullopt);
void stop_tool();
shared< VirtualDev > create_vdev_cb_for_tool(const vdev_info& vinfo, bool load_existing);

private:
void init_cache();
shared< VirtualDev > create_vdev_cb(const vdev_info& vinfo, bool load_existing);
Expand Down
8 changes: 8 additions & 0 deletions src/include/homestore/meta_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ class MetaBlkService {

nlohmann::json get_status(const int log_level);

public:
/************************* metacli function **********************/
void scan(const std::string& scan_type, std::optional< uint16_t > debug_chunk_id = std::nullopt,
std::optional< uint32_t > debug_blk_num = std::nullopt);
void scan_blks_on_all_chunks(std::optional< uint16_t > debug_chunk_id = std::nullopt,
std::optional< uint32_t > debug_blk_num = std::nullopt) const;
void scan_blks_by_chain() const;

public:
/*********************** static public function **********************/
uint64_t ovf_blk_max_num_data_blk() const;
Expand Down
4 changes: 2 additions & 2 deletions src/lib/device/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ class DeviceManager {
void format_devices();
uint32_t format_single_device(dev_info& dinfo);
void commit_formatting();
void load_devices();
void load_devices(bool ignore_unkown_vdevs=false);
void close_devices();
bool is_boot_in_degraded_mode() const { return m_boot_in_degraded_mode; }

Expand Down Expand Up @@ -195,7 +195,7 @@ class DeviceManager {
void remove_chunk_locked(shared< Chunk > chunk);

private:
void load_vdevs();
void load_vdevs(bool ignore_unkown_vdevs);
int device_open_flags(const std::string& devname) const;

std::vector< vdev_info > read_vdev_infos(const std::vector< PhysicalDev* >& pdevs);
Expand Down
19 changes: 14 additions & 5 deletions src/lib/device/device_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ void DeviceManager::format_devices() {
// Get common iomgr_attributes
for (auto& dinfo : m_dev_infos) {
format_single_device(dinfo);
}
}

// Verify the first blocks to see if the devs are unique
HS_REL_ASSERT(verify_unique_devs(), "Found duplicate physical devices in the system");
Expand Down Expand Up @@ -186,7 +186,7 @@ bool DeviceManager::verify_unique_devs() const {
return ret;
}

void DeviceManager::load_devices() {
void DeviceManager::load_devices(bool ignore_unkown_vdevs) {
RELEASE_ASSERT_EQ(m_first_blk_hdr.version, first_block_header::CURRENT_SUPERBLOCK_VERSION,
"We don't support superblock version upgrade yet");

Expand Down Expand Up @@ -241,7 +241,7 @@ void DeviceManager::load_devices() {
}

// 3. Recover vdevs from the physical devices.
load_vdevs();
load_vdevs(ignore_unkown_vdevs);

if (pdevs_to_format.empty() && !stale_first_blk_found) return;

Expand Down Expand Up @@ -565,7 +565,7 @@ void DeviceManager::add_pdev_to_vdev(shared< VirtualDev > vdev, PhysicalDev* pde
}
}

void DeviceManager::load_vdevs() {
void DeviceManager::load_vdevs(bool ignore_unkown_vdevs) {
std::unique_lock lg{m_vdev_mutex};

for (auto& [dtype, pdevs] : m_pdevs_by_type) {
Expand All @@ -583,9 +583,14 @@ void DeviceManager::load_vdevs() {
// we might have some missing pdevs in the sparse_vector m_all_pdevs, so skip them
if (!pdev) continue;
// Empty device will skip this callback.
pdev->load_chunks([this](cshared< Chunk >& chunk) -> bool {
pdev->load_chunks([this, &ignore_unkown_vdevs](cshared< Chunk >& chunk) -> bool {
// Found a chunk for which vdev information is missing
if (m_vdevs[chunk->vdev_id()] == nullptr) {
if (ignore_unkown_vdevs) {
LOGWARN("Ignoring chunk id={} belonging to unknown vdev_id={}", chunk->chunk_id(),
chunk->vdev_id());
return true;
}
LOGWARN("Found a chunk id={}, which is expected to be part of vdev_id={}, but that vdev "
"information is missing, may be before vdev is created, system crashed. Need upper layer "
"to retry vdev create",
Expand All @@ -603,6 +608,10 @@ void DeviceManager::load_vdevs() {

// Run initialization of all vdevs.
for (auto& vdev : m_vdevs) {
if (ignore_unkown_vdevs && vdev == nullptr) {
LOGWARN("Ignoring initialization of vdev of unknown device type");
continue;
}
vdev->init();
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/lib/device/virtual_dev.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,13 @@ void VirtualDev::recovery_completed() {
}
}

void VirtualDev::foreach_chunks(std::function< void(cshared< Chunk >&) >&& cb) {
std::unique_lock lg{m_mgmt_mutex};
for (auto& [_, chunk] : m_all_chunks) {
cb(chunk);
}
}

///////////////////////// VirtualDev Private Methods /////////////////////////////
uint64_t VirtualDev::to_dev_offset(BlkId const& b, Chunk** chunk) const {
*chunk = m_dmgr.get_chunk_mutable(b.chunk_num());
Expand Down
2 changes: 2 additions & 0 deletions src/lib/device/virtual_dev.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,8 @@ class VirtualDev {
///////////////////////// Meta operations on vdev ////////////////////////
void update_vdev_private(const sisl::blob& data);

void foreach_chunks(std::function< void(cshared< Chunk >&) >&& cb);

private:
uint64_t to_dev_offset(BlkId const& b, Chunk** chunk) const;
bool is_chunk_available(cshared< Chunk >& chunk) const;
Expand Down
80 changes: 80 additions & 0 deletions src/lib/homestore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,65 @@ bool HomeStore::start(const hs_input_params& input, hs_before_services_starting_
}
}

// TODO: change to tool file with well structure and tool related parameters
bool HomeStore::start_tool(const hs_input_params& input, const std::string& scan_type,
std::optional< uint16_t > debug_chunk_id, std::optional< blk_num_t > debug_blk_num) {
auto& hs_config = HomeStoreStaticConfig::instance();
hs_config.input = input;

if (input.devices.empty()) {
LOGERROR("No devices provided to start tool");
throw std::invalid_argument("null device list");
}

///////////// Startup resource status and other manager outside core services /////////////////////////
sisl::ObjCounterRegistry::enable_metrics_reporting();
sisl::MallocMetrics::enable();

LOGINFO("HomeStore version: {}", version);
static std::once_flag flag1;
std::call_once(flag1, [this]() {
sisl::VersionMgr::addVersion(PACKAGE_NAME, version::Semver200_version(PACKAGE_VERSION));
m_periodic_logger =
sisl::logging::CreateCustomLogger("homestore", "_periodic", false, true /* tee_to_stdout_stderr */);
sisl::logging::SetLogPattern("[%D %T.%f] [%^%L%$] [%t] %v", m_periodic_logger);
});

HomeStoreDynamicConfig::init_settings_default();

LOGINFO("HS tool is loading with meta service", m_services.list());
m_meta_service = std::make_unique< MetaBlkService >();

m_dev_mgr = std::make_unique< DeviceManager >(input.devices, bind_this(HomeStore::create_vdev_cb_for_tool, 2));
if (m_dev_mgr->is_first_time_boot()) {
LOGERROR("HS tool requires existing homestore setup on the devices");
return false;
}

m_dev_mgr->load_devices(true /* ignore unknown vdevs */);
if (input.has_fast_dev()) {
hs_utils::set_btree_mempool_size(m_dev_mgr->atomic_page_size({HSDevType::Fast}));
} else {
hs_utils::set_btree_mempool_size(m_dev_mgr->atomic_page_size({HSDevType::Data}));
}

LOGINFO("HS tool loaded devices successfully");
LOGINFO("HS tool starting scan meta blks, dynamic_config_version={}, static_config: {}", HS_DYNAMIC_CONFIG(version),
HomeStoreStaticConfig::instance().to_json().dump(4));
m_meta_service->scan(scan_type, debug_chunk_id, debug_blk_num);
return true;
}

void HomeStore::stop_tool() {
LOGINFO("HS tool stopping services");
m_meta_service->stop();
m_meta_service.reset();

m_dev_mgr->close_devices();
m_dev_mgr.reset();
LOGINFO("HS tool stopped all services");
}

void HomeStore::format_and_start(std::map< uint32_t, hs_format_params >&& format_opts) {
std::map< HSDevType, float > total_pct_by_type = {{HSDevType::Fast, 0.0f}, {HSDevType::Data, 0.0f}};
// Accumulate total percentage of services on each device type
Expand Down Expand Up @@ -465,6 +524,27 @@ shared< VirtualDev > HomeStore::create_vdev_cb(const vdev_info& vinfo, bool load
return ret_vdev;
}

shared< VirtualDev > HomeStore::create_vdev_cb_for_tool(const vdev_info& vinfo, bool load_existing) {
shared< VirtualDev > ret_vdev;
auto& hs_config = HomeStoreStaticConfig::instance();
auto vdev_context = r_cast< const hs_vdev_context* >(vinfo.get_user_private());

switch (vdev_context->type) {
case hs_vdev_type_t::META_VDEV:
if (has_meta_service()) {
ret_vdev = m_meta_service->open_vdev(vinfo, load_existing);
} else {
LOGERROR("HS tool requires meta service to be enabled");
}
break;
default:
LOGINFO("[HS_TOOL] skip vdev_type {}", vdev_context->type);
break;
}

return ret_vdev;
}

uint64_t HomeStore::pct_to_size(float pct, HSDevType dev_type) const {
uint64_t sz = uint64_cast((pct * static_cast< double >(m_dev_mgr->total_capacity(dev_type))) / 100);
return sisl::round_up(sz, m_dev_mgr->optimal_page_size(dev_type));
Expand Down
Loading
Loading