Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MetaService Fixes #450

Merged
merged 4 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class HomestoreConan(ConanFile):
name = "homestore"
version = "6.4.19"
version = "6.4.20"
homepage = "https://github.com/eBay/Homestore"
description = "HomeStore Storage Engine"
topics = ("ebay", "nublox")
Expand Down
7 changes: 7 additions & 0 deletions src/lib/common/homestore_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ bool hs_utils::mod_aligned_sz(size_t size_to_check, size_t align_sz) {
return !(size_to_check & static_cast< size_t >(align_sz - 1)); // return true if it is aligned.
}

bool hs_utils::is_ptr_aligned(void* ptr, std::size_t alignment) {
// Cast the pointer to uintptr_t, which is an integer type capable of holding a pointer
auto intptr = reinterpret_cast<std::uintptr_t>(ptr);
// Check if the pointer is a multiple of the alignment
return (intptr % alignment) == 0;
}

sisl::byte_view hs_utils::create_byte_view(const uint64_t size, const bool is_aligned_needed, const sisl::buftag tag,
const size_t alignment) {
return (is_aligned_needed) ? sisl::byte_view{static_cast< uint32_t >(aligned_size(size, alignment)),
Expand Down
1 change: 1 addition & 0 deletions src/lib/common/homestore_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class hs_utils {
static void iobuf_free(uint8_t* const ptr, const sisl::buftag tag, const size_t size);
static uint64_t aligned_size(const size_t size, const size_t alignment);
static bool mod_aligned_sz(const size_t size_to_check, const size_t align_sz);
static bool is_ptr_aligned(void* ptr, std::size_t alignment);
static sisl::byte_view create_byte_view(const uint64_t size, const bool is_aligned_needed, const sisl::buftag tag,
const size_t alignment);
static sisl::io_blob create_io_blob(const uint64_t size, const bool is_aligned_needed, const sisl::buftag tag,
Expand Down
8 changes: 5 additions & 3 deletions src/lib/meta/meta_blk_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ void MetaBlkService::write_ovf_blk_to_disk(meta_blk_ovf_hdr* ovf_hdr, const uint
uint8_t* write_context_data = (const_cast< uint8_t* >(context_data) + offset);
size_t write_size = ovf_hdr->h.context_sz;
uint8_t* context_data_aligned{nullptr};
if (!hs_utils::mod_aligned_sz(write_size, align_sz)) {
HS_LOG_EVERY_N(WARN, metablk, 50, "[type={}] Unaligned address found for input context_data.", type);
if (!hs_utils::is_ptr_aligned(write_context_data, align_sz) || !hs_utils::mod_aligned_sz(write_size, align_sz)) {
HS_LOG_EVERY_N(WARN, metablk, 50, "[type={}] Unaligned address found for input context_data, ptr {}, size {}, align {} ", type, (void *)write_context_data, write_size, align_sz);
const size_t aligned_write_size = uint64_cast(sisl::round_up(write_size, align_sz));
context_data_aligned = hs_utils::iobuf_alloc(aligned_write_size, sisl::buftag::metablk, align_size());
std::memcpy(context_data_aligned, write_context_data, write_size);
Expand Down Expand Up @@ -506,6 +506,8 @@ void MetaBlkService::write_ovf_blk_to_disk(meta_blk_ovf_hdr* ovf_hdr, const uint
size_written += (ovf_hdr->h.context_sz - size_written);
}

// check if the buffer is aligned
HS_REL_ASSERT(hs_utils::is_ptr_aligned(cur_ptr, align_sz) || hs_utils::mod_aligned_sz(cur_size, align_sz), "Unaligned address found for input context_data, ptr {}, size {}, align {} ", (void *)cur_ptr, cur_size, align_sz);
auto error = m_sb_vdev->sync_write(r_cast< const char* >(cur_ptr), cur_size, data_bid[i]);
if (error.value()) {
// the offset and buffer length is printed in the error messages of iomgr.
Expand Down Expand Up @@ -609,7 +611,7 @@ void MetaBlkService::write_meta_blk_ovf(BlkId& out_obid, const uint8_t* context_
context_data_blkids.clear();
alloc_meta_blks(sisl::round_up(sz, block_size()), context_data_blkids);

HS_LOG(DEBUG, metablk, "Start to allocate nblks(data): {}, mstore used size: {}", context_data_blkids.size(),
HS_LOG(DEBUG, metablk, "Context data size {}, rounded up to {}, block_size {}, allocated {} blkIDs, mstore used size: {}", sz, sisl::round_up(sz, block_size()), block_size(), context_data_blkids.size(),
m_sb_vdev->used_size());

// return the 1st ovf header blk id to caller;
Expand Down
31 changes: 20 additions & 11 deletions src/tests/test_meta_blk_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class VMetaBlkMgrTest : public ::testing::Test {
if (!done_read) {
done_read = true;
m_mbm->read_sub_sb(mtype);
const auto read_buf_str = m_cb_blks[mblk->hdr.h.bid.to_integer()];
const auto read_buf_str = m_cb_blks[mblk->hdr.h.bid.to_integer()].str;
const std::string write_buf_str = m_write_sbs[mblk->hdr.h.bid.to_integer()].str;
const auto ret = read_buf_str.compare(write_buf_str);
if (mblk->hdr.h.compressed == false) {
Expand Down Expand Up @@ -327,7 +327,7 @@ class VMetaBlkMgrTest : public ::testing::Test {

{
std::unique_lock< std::mutex > lg{m_mtx};
const auto read_buf_str = m_cb_blks[mblk->hdr.h.bid.to_integer()];
const auto read_buf_str = m_cb_blks[mblk->hdr.h.bid.to_integer()].str;
const std::string write_buf_str{str};
const auto ret = read_buf_str.compare(write_buf_str);
HS_DBG_ASSERT(ret == 0, "Context data mismatch: Saved: {}, read: {}.", write_buf_str, read_buf_str);
Expand Down Expand Up @@ -422,8 +422,8 @@ class VMetaBlkMgrTest : public ::testing::Test {
HS_DBG_ASSERT(it_cb != std::cend(m_cb_blks), "Saved bid during write not found in recover callback.");

// the saved buf should be equal to the buf received in the recover callback;
const int ret = it->second.str.compare(it_cb->second);
HS_DBG_ASSERT(ret == 0, "Context data mismatch: Saved: {}, callback: {}.", it->second.str, it_cb->second);
const int ret = it->second.str.compare(it_cb->second.str);
HS_DBG_ASSERT(ret == 0, "Context data mismatch: Saved: {}, callback: {}.", it->second.str, it_cb->second.str);
}
}

Expand Down Expand Up @@ -497,13 +497,16 @@ class VMetaBlkMgrTest : public ::testing::Test {

void recover_with_on_complete() {
// restart will cause recovery and callbacks will be triggered
++m_restart_cnt;
m_cb_blks.clear();
restart_homestore();
}

void validate() {
// verify received blks via callbaks are all good;
verify_cb_blks();
m_write_sbs.swap(m_cb_blks);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use m_cb_blks to replace m_write_sbs, as all the cookies saved in m_write_sbs is invalid after restart

m_cb_blks.clear();
}

meta_op_type get_op() {
Expand Down Expand Up @@ -537,7 +540,7 @@ class VMetaBlkMgrTest : public ::testing::Test {
}
}

uint64_t total_op_cnt() const { return m_update_cnt + m_wrt_cnt + m_rm_cnt; }
uint64_t total_op_cnt() const { return m_update_cnt + m_wrt_cnt + m_rm_cnt + m_restart_cnt; }

uint32_t write_ratio() const {
if (m_wrt_cnt == 0) return 0;
Expand Down Expand Up @@ -579,24 +582,28 @@ class VMetaBlkMgrTest : public ::testing::Test {
m_update_cnt = 0;
m_rm_cnt = 0;
m_total_wrt_sz = 0;
m_restart_cnt = 0;
}

void register_client() {
m_mbm = &(meta_service());
m_total_wrt_sz = m_mbm->used_size();

HS_REL_ASSERT_EQ(m_mbm->total_size() - m_total_wrt_sz, m_mbm->available_blks() * m_mbm->block_size());

m_mbm->deregister_handler(mtype);
m_mbm->register_handler(
mtype,
[this](meta_blk* mblk, sisl::byte_view buf, size_t size) {
if (mblk) {
std::unique_lock< std::mutex > lg{m_mtx};
m_cb_blks[mblk->hdr.h.bid.to_integer()] = md5_sum(r_cast< const char* >(buf.bytes()), size);
m_cb_blks[mblk->hdr.h.bid.to_integer()] = sb_info_t {
mblk, md5_sum(r_cast< const char* >(buf.bytes()), size)};
}
},
[this](bool success) { HS_DBG_ASSERT_EQ(success, true); });
[this](bool success) {
HS_DBG_ASSERT_EQ(success, true);
m_total_wrt_sz = m_mbm->used_size();
HS_REL_ASSERT_EQ(m_mbm->total_size() - m_total_wrt_sz, m_mbm->available_blks() * m_mbm->block_size());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the m_total_wrt_sz at the end of recovery. it was set to 0 in L590 before MetaService recovered.

});
}

void register_client_inlcuding_dependencies() {
Expand Down Expand Up @@ -682,7 +689,8 @@ class VMetaBlkMgrTest : public ::testing::Test {
[this](meta_blk* mblk, sisl::byte_view buf, size_t size) {
if (mblk) {
std::unique_lock< std::mutex > lg{m_mtx};
m_cb_blks[mblk->hdr.h.bid.to_integer()] = std::string{r_cast< const char* >(buf.bytes()), size};
m_cb_blks[mblk->hdr.h.bid.to_integer()] = sb_info_t {
mblk, md5_sum(r_cast< const char* >(buf.bytes()), size)};
}
},
[this](bool success) { HS_DBG_ASSERT_EQ(success, true); });
Expand All @@ -702,10 +710,11 @@ class VMetaBlkMgrTest : public ::testing::Test {
uint64_t m_wrt_cnt{0};
uint64_t m_update_cnt{0};
uint64_t m_rm_cnt{0};
uint64_t m_restart_cnt{0};
uint64_t m_total_wrt_sz{0};
MetaBlkService* m_mbm{nullptr};
std::map< uint64_t, sb_info_t > m_write_sbs; // during write, save blkid to buf map;
std::map< uint64_t, std::string > m_cb_blks; // during recover, save blkid to buf map;
std::map< uint64_t, sb_info_t > m_cb_blks; // during recover, save blkid to buf map;
std::mutex m_mtx;
#ifdef _PRERELEASE
flip::FlipClient m_fc{HomeStoreFlip::instance()};
Expand Down
Loading