diff --git a/conanfile.py b/conanfile.py index a1c2cdbea..092550c90 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ class HomeObjectConan(ConanFile): name = "homeobject" - version = "2.2.11" + version = "2.2.12" homepage = "https://github.com/eBay/HomeObject" description = "Blob Store built on HomeReplication" diff --git a/src/lib/homestore_backend/hs_blob_manager.cpp b/src/lib/homestore_backend/hs_blob_manager.cpp index b789d58f2..81d1ee599 100644 --- a/src/lib/homestore_backend/hs_blob_manager.cpp +++ b/src/lib/homestore_backend/hs_blob_manager.cpp @@ -156,6 +156,7 @@ BlobManager::AsyncResult< blob_id_t > HSHomeObject::_put_blob(ShardInfo const& s compute_blob_payload_hash(req->blob_header()->hash_algorithm, blob.body.cbytes(), blob_size, (uint8_t*)blob.user_key.data(), blob.user_key.size(), req->blob_header()->hash, BlobHeader::blob_max_hash_len); + req->blob_header()->seal(); // Add blob body to the request req->add_data_sg(std::move(blob.body)); @@ -360,8 +361,7 @@ HSHomeObject::blob_put_get_blk_alloc_hints(sisl::blob const& header, cintrusive< auto hs_pg = get_hs_pg(msg_header->pg_id); if (hs_pg == nullptr) { - LOGW("Received a blob_put on an unknown pg:{}, underlying engine will retry this later", - msg_header->pg_id); + LOGW("Received a blob_put on an unknown pg:{}, underlying engine will retry this later", msg_header->pg_id); return folly::makeUnexpected(homestore::ReplServiceError::RESULT_NOT_EXIST_YET); } diff --git a/src/lib/homestore_backend/hs_homeobject.hpp b/src/lib/homestore_backend/hs_homeobject.hpp index 4f66f676f..952eb2ada 100644 --- a/src/lib/homestore_backend/hs_homeobject.hpp +++ b/src/lib/homestore_backend/hs_homeobject.hpp @@ -157,7 +157,7 @@ class HSHomeObject : public HomeObjectImpl { data_type_t type{data_type_t::BLOB_INFO}; }; - struct shard_info_superblk : public DataHeader { + struct shard_info_superblk : DataHeader { ShardInfo info; homestore::chunk_num_t p_chunk_id; homestore::chunk_num_t v_chunk_id; @@ -301,7 +301,7 @@ class HSHomeObject : public HomeObjectImpl { #pragma pack(1) // Every blob payload stored in disk as blob header | blob data | blob metadata(optional) | padding. // Padding of zeroes is added to make sure the whole payload be aligned to device block size. - struct BlobHeader : public DataHeader { + struct BlobHeader : DataHeader { static constexpr uint64_t blob_max_hash_len = 32; enum class HashAlgorithm : uint8_t { @@ -312,6 +312,7 @@ class HSHomeObject : public HomeObjectImpl { }; HashAlgorithm hash_algorithm; + mutable uint8_t header_hash[blob_max_hash_len]{}; uint8_t hash[blob_max_hash_len]{}; shard_id_t shard_id; blob_id_t blob_id; @@ -325,6 +326,46 @@ class HSHomeObject : public HomeObjectImpl { magic, version, shard_id, blob_size, user_key_size, (uint8_t)hash_algorithm, spdlog::to_hex(hash, hash + blob_max_hash_len)); } + + bool valid() const { + if (!DataHeader::valid()) { return false; } + + uint8_t hash_arr[blob_max_hash_len]; + std::memcpy(hash_arr, header_hash, blob_max_hash_len); + if (!_do_seal()) { + std::memcpy(header_hash, hash_arr, blob_max_hash_len); + return false; + } + + bool hash_valid = std::memcmp(header_hash, hash_arr, blob_max_hash_len) == 0; + std::memcpy(header_hash, hash_arr, blob_max_hash_len); + return hash_valid; + } + + void seal() const { + if (!_do_seal()) { + DEBUG_ASSERT(false, "Invalid hash algorithm"); // Not implemented + } + } + + private: + bool _do_seal() const { + switch (hash_algorithm) { + case HashAlgorithm::NONE: + return true; + case HashAlgorithm::CRC32: { + std::memset(header_hash, 0, blob_max_hash_len); + uint32_t computed_hash = crc32_ieee(0, (uint8_t*)this, sizeof(BlobHeader)); + std::memcpy(header_hash, &computed_hash, sizeof(uint32_t)); + return true; + } + case HashAlgorithm::MD5: + case HashAlgorithm::SHA1: + default: + break; // Not implemented + } + return false; + } }; #pragma pack() diff --git a/src/lib/homestore_backend/tests/homeobj_misc_tests.cpp b/src/lib/homestore_backend/tests/homeobj_misc_tests.cpp index a11967ceb..0b27b2a47 100644 --- a/src/lib/homestore_backend/tests/homeobj_misc_tests.cpp +++ b/src/lib/homestore_backend/tests/homeobj_misc_tests.cpp @@ -303,6 +303,7 @@ TEST_F(HomeObjectFixture, SnapshotReceiveHandler) { reinterpret_cast< uint8_t* >(blob.user_key.data()), blob.user_key.size(), hdr.hash, HSHomeObject::BlobHeader::blob_max_hash_len); + hdr.seal(); std::memcpy(blob_raw.bytes(), &hdr, sizeof(HSHomeObject::BlobHeader)); if (!blob.user_key.empty()) {