Skip to content

Commit 0b40663

Browse files
authored
Issue 45: Volume Destroy Implementation and its test case (#71)
* Issue 45: Volume Destroy Implementation and its test case
1 parent 12d0498 commit 0b40663

File tree

7 files changed

+95
-9
lines changed

7 files changed

+95
-9
lines changed

conanfile.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
class HomeBlocksConan(ConanFile):
1111
name = "homeblocks"
12-
version = "0.0.6"
12+
version = "0.0.7"
1313

1414
homepage = "https://github.com/eBay/HomeBlocks"
1515
description = "Block Store built on HomeStore"
@@ -44,9 +44,9 @@ def build_requirements(self):
4444
self.test_requires("gtest/1.14.0")
4545

4646
def requirements(self):
47-
self.requires("homestore/[^6.5]@oss/master")
47+
self.requires("homestore/[~6.9.0]@oss/master")
4848
self.requires("iomgr/[^11.3]@oss/master")
49-
self.requires("sisl/[^12.3, include_prerelease=True]@oss/master", transitive_headers=True)
49+
self.requires("sisl/[^12.2]@oss/master", transitive_headers=True)
5050
self.requires("lz4/1.9.4", override=True)
5151

5252
def validate(self):

src/lib/listener.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ bool HBListener::on_pre_commit(int64_t lsn, const sisl::blob& header, const sisl
2828
void HBListener::on_error(homestore::ReplServiceError error, const sisl::blob& header, const sisl::blob& key,
2929
cintrusive< homestore::repl_req_ctx >& ctx) {}
3030

31-
homestore::ReplResult< homestore::blk_alloc_hints > HBListener::get_blk_alloc_hints(sisl::blob const& header,
32-
uint32_t data_size) {
31+
homestore::ReplResult< homestore::blk_alloc_hints >
32+
HBListener::get_blk_alloc_hints(sisl::blob const& header, uint32_t data_size,
33+
cintrusive< homestore::repl_req_ctx >& hs_ctx) {
3334
return homestore::blk_alloc_hints();
3435
}
3536

src/lib/listener.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ class HBListener : public homestore::ReplDevListener {
3838
void on_error(homestore::ReplServiceError error, const sisl::blob& header, const sisl::blob& key,
3939
cintrusive< homestore::repl_req_ctx >& ctx) override;
4040

41-
homestore::ReplResult< homestore::blk_alloc_hints > get_blk_alloc_hints(sisl::blob const& header,
42-
uint32_t data_size) override;
41+
homestore::ReplResult< homestore::blk_alloc_hints >
42+
get_blk_alloc_hints(sisl::blob const& header, uint32_t data_size,
43+
cintrusive< homestore::repl_req_ctx >& hs_ctx) override;
4344
// group_id is the uuid generated by HomeBlocks when create_volume->create_repl_dev(gid) is called;
4445
// when volume is being destroyed, on_destroy is going to be triggered to listener that this volume's gid is
4546
// destroyed;

src/lib/volume/tests/test_volume.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,38 @@ class VolumeTest : public ::testing::Test {
4848
}
4949
};
5050

51+
TEST_F(VolumeTest, CreateDestroyVolume) {
52+
std::vector< volume_id_t > vol_ids;
53+
{
54+
auto hb = g_helper->inst();
55+
auto vol_mgr = hb->volume_manager();
56+
57+
auto num_vols = SISL_OPTIONS["num_vols"].as< uint32_t >();
58+
59+
for (uint32_t i = 0; i < num_vols; ++i) {
60+
auto vinfo = gen_vol_info(i);
61+
auto id = vinfo.id;
62+
vol_ids.emplace_back(id);
63+
auto ret = vol_mgr->create_volume(std::move(vinfo)).get();
64+
ASSERT_TRUE(ret);
65+
66+
auto vinfo_ptr = vol_mgr->lookup_volume(id);
67+
// verify the volume is there
68+
ASSERT_TRUE(vinfo_ptr != nullptr);
69+
}
70+
71+
for (uint32_t i = 0; i < num_vols; ++i) {
72+
auto id = vol_ids[i];
73+
auto ret = vol_mgr->remove_volume(id).get();
74+
ASSERT_TRUE(ret);
75+
76+
auto vinfo_ptr = vol_mgr->lookup_volume(id);
77+
// verify the volume is not there
78+
ASSERT_TRUE(vinfo_ptr == nullptr);
79+
}
80+
}
81+
}
82+
5183
TEST_F(VolumeTest, CreateVolumeThenRecover) {
5284
std::vector< volume_id_t > vol_ids;
5385
{

src/lib/volume/volume.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,24 @@ bool Volume::init(bool is_recovery) {
8484
return true;
8585
}
8686

87+
void Volume::destroy() {
88+
// destroy the repl dev;
89+
if (rd_) {
90+
LOGI("Destroying repl dev for volume: {}, uuid: {}", vol_info_->name, boost::uuids::to_string(id()));
91+
homestore::hs()->repl_service().remove_repl_dev(id()).get();
92+
rd_ = nullptr;
93+
}
94+
95+
// destroy the index table;
96+
if (indx_tbl_) {
97+
LOGI("Destroying index table for volume: {}, uuid: {}", vol_info_->name, boost::uuids::to_string(id()));
98+
homestore::hs()->index_service().remove_index_table(indx_tbl_);
99+
indx_tbl_->destroy();
100+
indx_tbl_ = nullptr;
101+
}
102+
103+
// destroy the superblock which will remove sb from meta svc;
104+
sb_.destroy();
105+
}
106+
87107
} // namespace homeblocks

src/lib/volume/volume.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ class Volume {
7171
Volume& operator=(Volume const& volume) = delete;
7272
Volume& operator=(Volume&& volume) = default;
7373

74-
// TODO: volume destructor should remove volume meta block;
7574
virtual ~Volume() = default;
7675

7776
// static APIs exposed to HomeBlks Implementation Layer;
@@ -100,6 +99,8 @@ class Volume {
10099
//
101100
shared< VolumeIndexTable > init_index_table(bool is_recovery, shared< VolumeIndexTable > tbl = nullptr);
102101

102+
void destroy();
103+
103104
private:
104105
//
105106
// this API will be called to initialize volume in both volume creation and volume recovery;

src/lib/volume_mgr.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,38 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::create_volume(VolumeInfo&& vol_in
8080
return folly::Unit();
8181
}
8282

83-
VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) { return folly::Unit(); }
83+
VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) {
84+
LOGI("remove_volume with input id: {}", boost::uuids::to_string(id));
85+
86+
std::string vol_id_str;
87+
// 1. remove destroy volume and remove volume from vol_map;
88+
{
89+
auto lg = std::scoped_lock(vol_lock_);
90+
if (auto it = vol_map_.find(id); it != vol_map_.end()) {
91+
auto vol_ptr = it->second;
92+
vol_id_str = vol_ptr->id_str();
93+
vol_map_.erase(it);
94+
vol_ptr->destroy();
95+
LOGI("Volume {} removed successfully", boost::uuids::to_string(id));
96+
} else {
97+
LOGW("remove_volume with input id: {} not found", boost::uuids::to_string(id));
98+
return folly::makeUnexpected(VolumeError::INVALID_ARG);
99+
}
100+
}
101+
102+
// 2. remove index handler from index_map if it exists;
103+
{
104+
auto lg = std::scoped_lock(index_lock_);
105+
auto it = idx_tbl_map_.find(vol_id_str);
106+
if (it != idx_tbl_map_.end()) {
107+
idx_tbl_map_.erase(it);
108+
LOGI("Volume {} index table removed successfully", boost::uuids::to_string(id));
109+
}
110+
}
111+
112+
// Volume Destructor will be called after vol_ptr goes out of scope;
113+
return folly::Unit();
114+
}
84115

85116
VolumeInfoPtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) {
86117
auto lg = std::shared_lock(vol_lock_);

0 commit comments

Comments
 (0)