From 83b8e2473826a5799269bde0daf36578d1e2e4a9 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Wed, 12 Feb 2025 22:34:34 -0700 Subject: [PATCH 1/8] Initial commit for HomeBlks 2.0 --- conanfile.py | 2 +- src/include/homeblks/.volume_mgr.hpp.swp | Bin 0 -> 12288 bytes .../{homeblocks => homeblks}/common.hpp | 0 .../homeblocks.hpp => homeblks/home_blks.hpp} | 0 .../volume_mgr.hpp} | 17 +++++++++++++++++ src/lib/CMakeLists.txt | 4 ++-- .../{homeblocks_impl.cpp => homeblks_impl.cpp} | 2 +- .../{homeblocks_impl.hpp => homeblks_impl.hpp} | 4 ++-- src/lib/memory_backend/CMakeLists.txt | 2 +- .../{mem_homeblocks.cpp => mem_homeblks.cpp} | 2 +- .../{mem_homeblocks.hpp => mem_homeblks.hpp} | 2 +- src/lib/tests/fixture_app.cpp | 2 +- src/lib/{volume_manager.cpp => volume_mgr.cpp} | 2 +- 13 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 src/include/homeblks/.volume_mgr.hpp.swp rename src/include/{homeblocks => homeblks}/common.hpp (100%) rename src/include/{homeblocks/homeblocks.hpp => homeblks/home_blks.hpp} (100%) rename src/include/{homeblocks/volume_manager.hpp => homeblks/volume_mgr.hpp} (79%) rename src/lib/{homeblocks_impl.cpp => homeblks_impl.cpp} (97%) rename src/lib/{homeblocks_impl.hpp => homeblks_impl.hpp} (97%) rename src/lib/memory_backend/{mem_homeblocks.cpp => mem_homeblks.cpp} (94%) rename src/lib/memory_backend/{mem_homeblocks.hpp => mem_homeblks.hpp} (94%) rename src/lib/{volume_manager.cpp => volume_mgr.cpp} (95%) diff --git a/conanfile.py b/conanfile.py index f759663..1087eeb 100644 --- a/conanfile.py +++ b/conanfile.py @@ -44,7 +44,7 @@ def build_requirements(self): self.test_requires("gtest/1.14.0") def requirements(self): - self.requires("homestore/[~6.4, include_prerelease=True]@oss/master", transitive_headers=True) + self.requires("homestore/[^6.5]@oss/master") self.requires("sisl/[~12.2, include_prerelease=True]@oss/master", transitive_headers=True) self.requires("lz4/1.9.4", override=True) diff --git a/src/include/homeblks/.volume_mgr.hpp.swp b/src/include/homeblks/.volume_mgr.hpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..397309ae4489b89e3411a98f6441a352b58badb4 GIT binary patch literal 12288 zcmeI2&u<$=6vwv(LHSWYEq}mkDuNT4I04jBCyp8tx3!4v;5exSht+s@Y!6xQnw?ok zAqq(Ci60k)#DP2FP?ZY@{sEA zt)pyfe!Eho3v=@pj%O_ElWR9SH=aB7(D}=Y)*jo5nBUQN?s-U8wj$xV^XKkqW))nf z*dXwt9xrqQ{75G#bc8Bg!G%}7z}b-n89D{wJ6_}_b}bJVlW}&h6V7$}{d-Sj?ivM* z0*4idRQrWjPFgR$xDapkvr}j2^r@}GHs;JIU=%P47zK<1MggOMQNSo*6nLN&Q2k@p zdsyM|bd~k=^Vq~^dTKt50!9I&fKk9GU=%P47zK<1MggOMQNSo*6!;%1z+B7v^H51s|5!JU(s z2Yd&<1UJDRcpjVq1b%wbvTlK|!3A&v90zxvu&lqq@8A~r5xff)z&tnwK6~7<-Ud6M z3p!u{%z)dES=KM$Q}8jUfhw29@M5rR>(I5~m zb-1$A7r2Bgb5gm*;($9U2$x`>UkI~>Yb#ow)~EPg&X5!MQc;QK6Mr;Yi2c$mUF@@v z^@f(z>~cz+kqSt{DJP|`#f}Ni=F*Wv2hFaK)Q)^diNL3jt5EO(m+>f1VAh~L4oedA z-NbEd(IeriFO>l9)zU|N762bVlr|ZE@eCNyuFbmn5oS?$ti%K z;jX}MIX>5!gQ(;OirPWsyEDU;4-*r|6Q?EQZTR+4A;^r*NhWRzT5q8QXcwN7gk?h# zo<}W2rL*ZyPJr2U(kp8^QDe75vtgPKOP}%H4nkri``i(2;iN%fP25+wfQ+{GNGOR3 zCbEN~Z`Rl9MF_;)!fq%OFGPNi^=W0JB9jclW|+iywQ56!Iw%*Zs@KD8!+M7tv$u%OuFe| zm)35(r;0@+uE$hvDpN*9NLSiFph$8z8H=+#Wqjd$Do@x@5+0%m{h(M>fi1D?{Z0_(5FL3We0A<+^sCG)i@GDKK%wRNQLhD6P@C~u5-Zm7u#I%* zK<`Q7Pu4hcHeSIZ{kJo1rR$SngUBumUHLDsag3Sjf|3=+?&euqNDu=~WA z1e2{zB-z&LO;plI-u?OXX*?>jv52F4la&&e&seQP&mKIQv0H}aZ==%F{fZtS+#GIW zH;w1WWi9p(4i{mZ3hXHCn@D0SrnRZtWeJTRUlDYDV^{YTz9u9A(ek3U&o-gOL>8*m z?ahsq)v~=_zSPXqTBEXEwy!oS&9Yr?H0lj#UaoCbQ;p-+lq_Z8oUQV-ReP;gzgol8 z3wf&4wpZ3GYxYXxa-N!%YPr4zm#K-pU0>g-mi77O*2YG?(JZgo^^H8OHdgIwWwW}{ zT)mRVpTBqcdZhQ<+4S9ZnsS0(FYxvI>{FS`OHxR$5GmmawO8QKSX(TQ$1TO>SJ162 f{$YzCvB;Pt%_}; + struct VolumeInfo { VolumeInfo(volume_id_t _id, uint64_t _num_bytes) : id(_id), size_bytes(_num_bytes) {} volume_id_t id; uint64_t size_bytes{0}; + uint64_t page_size{0}; + std::string vol_name; auto operator<=>(VolumeInfo const& rhs) const { return boost::uuids::hash_value(id) <=> boost::uuids::hash_value(rhs.id); } + auto operator==(VolumeInfo const& rhs) const { return id == rhs.id; } + + std::string to_string() { + return fmt::format("VolumeInfo: id={} size_bytes={}, page_size={}, name={}", boost::uuids::to_string(id), size_bytes, + page_size, vol_name); + } }; struct VolumeStats { @@ -40,6 +51,12 @@ class VolumeManager : public Manager< VolumeError > { public: virtual NullAsyncResult create_volume(VolumeInfo&& volume_info) = 0; + // virtual NullAsyncResult remove_volume(const volume_id_t& id) = 0; + + // virtual VolumtPtr lookup_volume(const volume_id_t& id) = 0; + + // TODO: read/write/unmap APIs + /** * Retrieves the statistics for a specific Volume identified by its ID. * diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index e33c075..279a79f 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -4,8 +4,8 @@ add_flags("-Wno-unused-parameter") add_library(${PROJECT_NAME}_core OBJECT) target_sources(${PROJECT_NAME}_core PRIVATE - homeblocks_impl.cpp - volume_manager.cpp + homeblks_impl.cpp + volume_mgr.cpp ) target_link_libraries(${PROJECT_NAME}_core ${COMMON_DEPS} diff --git a/src/lib/homeblocks_impl.cpp b/src/lib/homeblks_impl.cpp similarity index 97% rename from src/lib/homeblocks_impl.cpp rename to src/lib/homeblks_impl.cpp index 98acc08..3a6207a 100644 --- a/src/lib/homeblocks_impl.cpp +++ b/src/lib/homeblks_impl.cpp @@ -1,7 +1,7 @@ #include #include -#include "homeblocks_impl.hpp" +#include "homeblks_impl.hpp" SISL_OPTION_GROUP(homeblocks, (executor_type, "", "executor", "Executor to use for Future deferal", diff --git a/src/lib/homeblocks_impl.hpp b/src/lib/homeblks_impl.hpp similarity index 97% rename from src/lib/homeblocks_impl.hpp rename to src/lib/homeblks_impl.hpp index f623399..0bcface 100644 --- a/src/lib/homeblocks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -3,8 +3,8 @@ #include #include -#include -#include +#include +#include #define LOGT(...) LOGTRACEMOD(homeblocks, ##__VA_ARGS__) #define LOGD(...) LOGDEBUGMOD(homeblocks, ##__VA_ARGS__) diff --git a/src/lib/memory_backend/CMakeLists.txt b/src/lib/memory_backend/CMakeLists.txt index 9945ff4..6851a30 100644 --- a/src/lib/memory_backend/CMakeLists.txt +++ b/src/lib/memory_backend/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.11) add_library ("${PROJECT_NAME}_memory") target_sources("${PROJECT_NAME}_memory" PRIVATE - mem_homeblocks.cpp + mem_homeblks.cpp $ ) target_link_libraries("${PROJECT_NAME}_memory" diff --git a/src/lib/memory_backend/mem_homeblocks.cpp b/src/lib/memory_backend/mem_homeblks.cpp similarity index 94% rename from src/lib/memory_backend/mem_homeblocks.cpp rename to src/lib/memory_backend/mem_homeblks.cpp index 6ccf042..c70ce18 100644 --- a/src/lib/memory_backend/mem_homeblocks.cpp +++ b/src/lib/memory_backend/mem_homeblks.cpp @@ -1,4 +1,4 @@ -#include "mem_homeblocks.hpp" +#include "mem_homeblks.hpp" namespace homeblocks { diff --git a/src/lib/memory_backend/mem_homeblocks.hpp b/src/lib/memory_backend/mem_homeblks.hpp similarity index 94% rename from src/lib/memory_backend/mem_homeblocks.hpp rename to src/lib/memory_backend/mem_homeblks.hpp index 02e0b19..4cf751c 100644 --- a/src/lib/memory_backend/mem_homeblocks.hpp +++ b/src/lib/memory_backend/mem_homeblks.hpp @@ -4,7 +4,7 @@ #include #include -#include "lib/homeblocks_impl.hpp" +#include "lib/homeblks_impl.hpp" namespace homeblocks { diff --git a/src/lib/tests/fixture_app.cpp b/src/lib/tests/fixture_app.cpp index 0797b46..dc0296e 100644 --- a/src/lib/tests/fixture_app.cpp +++ b/src/lib/tests/fixture_app.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include SISL_LOGGING_INIT(HOMEBLOCKS_LOG_MODS) SISL_OPTIONS_ENABLE(logging, homeblocks) diff --git a/src/lib/volume_manager.cpp b/src/lib/volume_mgr.cpp similarity index 95% rename from src/lib/volume_manager.cpp rename to src/lib/volume_mgr.cpp index d77f0ac..23eb614 100644 --- a/src/lib/volume_manager.cpp +++ b/src/lib/volume_mgr.cpp @@ -1,6 +1,6 @@ #include -#include "homeblocks_impl.hpp" +#include "homeblks_impl.hpp" namespace homeblocks { From 14ee26e5e18b7bd9fe5eb64ae95df02d7c89e460 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Wed, 12 Feb 2025 22:37:52 -0700 Subject: [PATCH 2/8] update con ver --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 1087eeb..15f5cc2 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ class HomeBlocksConan(ConanFile): name = "homeblocks" - version = "0.0.1" + version = "0.0.2" homepage = "https://github.com/eBay/HomeBlocks" description = "Block Store built on HomeStore" From 94c7e4970d7a2851e341aab24198e064b78af435 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Wed, 12 Feb 2025 23:08:02 -0700 Subject: [PATCH 3/8] add remove_volume and lookup_volume api signature --- src/include/homeblks/.volume_mgr.hpp.swp | Bin 12288 -> 12288 bytes src/include/homeblks/volume_mgr.hpp | 8 ++++---- src/lib/homeblks_impl.hpp | 9 +++++++-- src/lib/volume_mgr.cpp | 8 ++++++++ 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/include/homeblks/.volume_mgr.hpp.swp b/src/include/homeblks/.volume_mgr.hpp.swp index 397309ae4489b89e3411a98f6441a352b58badb4..0031c6438cbeacf82c2d140e65b3e4428876d291 100644 GIT binary patch delta 362 zcmW;Iy-LGy6vp8r`LL~8#Hq%?I9SP$*rg3l4h~YmL5HG(nkphft0=8bk`Cg>B$7dK zu{YpQ{#tPG7J32dqG-V`9o(G!;R_EOc;Ub~wV)PQ8<|3W-k$O@LIy=X&hEGC<3pO2 zZ&;mCqpOR|L~(mIY$io6aE=Nr48y?pfJh4uPzd2-0%^SUi@f3)(?}u)13J2W^mxGu zeB_WqJt10m^oW)`+&QRJizU0TSE`n`qD{w-KAn_$bXt0J>ba`v H&Gq~N&YDE( delta 362 zcmWmAKTE@K5XSMdiM6eN(CSnNlR+hdNjinjf<>`H6+2g#Dn>Fn>1tVv>!VHT9&9HJinby4gedc?j zx2=nKLDIdNZq8rR^&p8ZetU@!Lk E0k diff --git a/src/include/homeblks/volume_mgr.hpp b/src/include/homeblks/volume_mgr.hpp index d41238f..70ebd58 100644 --- a/src/include/homeblks/volume_mgr.hpp +++ b/src/include/homeblks/volume_mgr.hpp @@ -12,8 +12,8 @@ namespace homeblocks { ENUM(VolumeError, uint16_t, UNKNOWN = 1, INVALID_ARG, TIMEOUT, UNKNOWN_VOLUME, UNSUPPORTED_OP, CRC_MISMATCH, NO_SPACE_LEFT, DRIVE_WRITE_ERROR); -// class Volume; -// using VolumePtr = std::shared_ptr< Volume >; +class Volume; +using VolumePtr = std::shared_ptr< Volume >; struct VolumeInfo { VolumeInfo(volume_id_t _id, uint64_t _num_bytes) : id(_id), size_bytes(_num_bytes) {} @@ -51,9 +51,9 @@ class VolumeManager : public Manager< VolumeError > { public: virtual NullAsyncResult create_volume(VolumeInfo&& volume_info) = 0; - // virtual NullAsyncResult remove_volume(const volume_id_t& id) = 0; + virtual NullAsyncResult remove_volume(const volume_id_t& id) = 0; - // virtual VolumtPtr lookup_volume(const volume_id_t& id) = 0; + virtual VolumePtr lookup_volume(const volume_id_t& id) = 0; // TODO: read/write/unmap APIs diff --git a/src/lib/homeblks_impl.hpp b/src/lib/homeblks_impl.hpp index 0bcface..50e7ef7 100644 --- a/src/lib/homeblks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -42,7 +42,8 @@ struct Volume { }; class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enable_shared_from_this< HomeBlocksImpl > { - virtual VolumeManager::NullAsyncResult _create_volume(VolumeInfo&& volume_info) = 0; + // TODO: we don't plan to have another HSHomeBlksImpl, so can remove _create_volume; + virtual VolumeManager::NullAsyncResult _create_volume(VolumeInfo&& volume_info) = 0; virtual bool _get_stats(volume_id_t id, VolumeStats& stats) const = 0; virtual void _get_volume_ids(std::vector< volume_id_t >& vol_ids) const = 0; @@ -80,7 +81,11 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab HomeBlocksStats get_stats() const final { return _get_stats(); } /// VolumeManager - VolumeManager::NullAsyncResult create_volume(VolumeInfo&& vol_info) final; + NullAsyncResult create_volume(VolumeInfo&& vol_info) final; + + NullAsyncResult remove_volume(const volume_id_t& id) final; + + VolumePtr lookup_volume(const volume_id_t& id) final; // see api comments in base class; bool get_stats(volume_id_t id, VolumeStats& stats) const final; diff --git a/src/lib/volume_mgr.cpp b/src/lib/volume_mgr.cpp index 23eb614..963ee76 100644 --- a/src/lib/volume_mgr.cpp +++ b/src/lib/volume_mgr.cpp @@ -11,6 +11,14 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::create_volume(VolumeInfo&& vol_in return _create_volume(std::move(vol_info)); } +VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) { + return folly::Unit(); +} + +VolumePtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) { + return nullptr; +} + bool HomeBlocksImpl::get_stats(volume_id_t id, VolumeStats& stats) const { return _get_stats(id, stats); } void HomeBlocksImpl::get_volume_ids(std::vector< volume_id_t >& vol_ids) const { return _get_volume_ids(vol_ids); } From 37959280d0da341b8936488e1dd0768f0c979563 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Fri, 14 Feb 2025 17:17:05 -0700 Subject: [PATCH 4/8] add listener and init_homestore --- conanfile.py | 1 + src/include/homeblks/.volume_mgr.hpp.swp | Bin 12288 -> 0 bytes src/include/homeblks/home_blks.hpp | 2 + src/lib/CMakeLists.txt | 3 +- src/lib/homeblks_impl.cpp | 183 +++++++++++++++++++++++ src/lib/homeblks_impl.hpp | 90 ++++++++--- src/lib/listener.cpp | 22 +++ src/lib/listener.hpp | 57 +++++++ src/lib/memory_backend/CMakeLists.txt | 1 + src/lib/memory_backend/mem_homeblks.cpp | 2 +- src/lib/memory_backend/mem_homeblks.hpp | 8 - src/lib/volume_mgr.cpp | 16 +- 12 files changed, 345 insertions(+), 40 deletions(-) delete mode 100644 src/include/homeblks/.volume_mgr.hpp.swp create mode 100644 src/lib/listener.cpp create mode 100644 src/lib/listener.hpp diff --git a/conanfile.py b/conanfile.py index 15f5cc2..8e4e728 100644 --- a/conanfile.py +++ b/conanfile.py @@ -45,6 +45,7 @@ def build_requirements(self): def requirements(self): self.requires("homestore/[^6.5]@oss/master") + self.requires("iomgr/[^11.3]@oss/master") self.requires("sisl/[~12.2, include_prerelease=True]@oss/master", transitive_headers=True) self.requires("lz4/1.9.4", override=True) diff --git a/src/include/homeblks/.volume_mgr.hpp.swp b/src/include/homeblks/.volume_mgr.hpp.swp deleted file mode 100644 index 0031c6438cbeacf82c2d140e65b3e4428876d291..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2&u<$=6vwyFLitfZqQdTwgk!ts!0{rc`_t*eh8zw<<8*4k#5VivUYoqZ4K$wn-EZ+d25Gt2gv zV!hChJKS!E_>)aww}i6K;lc}k=w6bxj9gm;t{;1;UBk!4bez*^MN{o=cmIjZU88_e zU{rxvHBUWz%zEm{)5%spIrbPme0*cn#+(@ii~>dhqkvJsC}0#Y3K#{90=KmSs(Z+~ zj1}IIt+JZE9@_JoothV;fKk9GU=%P47zK<1MggOMQNSo*6fg=H1^$N$Fwe5CAGWNe zyAVA7|KI=pf8#;R`Wbu=z5}0v_rVn)K?Gg{7r|c-Sk|}T8}KE#0^S1(oB)r4BjAr? z@CUvC*T7|P3OoVE!B6*F){o$8@H}_`90fO_ z2b=*m`28Ns`VD*nJ_Z-Tt6&B^15SZoj>0dv25R8XyYVap_y~LmJ^&7Q1^f-IZh)`A z=YWAX!0SNkI0wvO6fg=H1#W8vcGH7wn*!G1vddgf`pK?F@*tOG?ao?+qbDL2GoN~) z@TkR=lReBOJXw&+E0ucORbey-1O0HABRogZ!ni)gdpSXF7)V9)G@bgRNjvdNlXSMr zBG&0!QoYS7bw(;A38$QtzLq#9IGf5w_8rvQLQ*phTqVMQBCaCAdt4@?e1TcR<}fTt zEbvmdiA9G*kXUx3uqQn3Ws~onp`XYm6;ra17fEp@tma3yVVC?;dqgy3{olkspSa;%>G93Ta*E5;~5VCx(SS zQUX?D2!R+SiSX_|?Eo8fhhHhU3ZpOSU7}E0bYs$To{S`7f_YjJeW+LbDcD6Jwv{lsjlzy2!C3#oN4?G+W*850oBV zO8xBU;koP#Tqe2F9uJVDp^pP4iN)wPVV6e?-D7^fkgi+@m42vx%bk9ip{dNz z>pN2rjds&~534pS#?fMGGud`}%#XRQCYqaH*i&segVb}T-$;lUc8eI(VDhzzBs*HY zJ(V<&cV{~L93B+eP{hH#y_J%b&rq$APaS+HW4H9n-$A8k`xQMvcm>?XZW_)}$Xo2} zjuv5(3hby@VjpIOsT<`y`aQlG=;Fqf?kapcNTZ>J*^%}$n+ig!RcC!|ajEQ_FTYqX z(sHe`S#~beD)q8cuGOkFs9j#&Sjp5)no_!m(=(1L(#Gn`tJMpunD=y%Dyy4|=PS$3 zV(q0O)hjFI>IPh9CeCK{{KiUIpRaGMtyOFF^0HH1E7DSJ$yuqauPoM=&K2=9^d?`4 z^lm$uJ=;!WZrJIBfqtHSEO&WM3hCRi624H|Hix>}VqrLLE-5@)H?ic8Bf``oXOgz9 W{2)w*?@An(x)E!27#fDlt$zR<^os}p diff --git a/src/include/homeblks/home_blks.hpp b/src/include/homeblks/home_blks.hpp index 4e4b147..b922569 100644 --- a/src/include/homeblks/home_blks.hpp +++ b/src/include/homeblks/home_blks.hpp @@ -41,6 +41,8 @@ class HomeBlocksApplication { virtual bool spdk_mode() const = 0; virtual uint32_t threads() const = 0; virtual std::list< device_info_t > devices() const = 0; + // in bytes; + virtual uint64_t app_mem_size() const = 0; // Callback made after determining if a SvcId exists or not during initialization, will consume response virtual peer_id_t discover_svcid(std::optional< peer_id_t > const& found) const = 0; diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 279a79f..7c1904a 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -6,11 +6,12 @@ add_library(${PROJECT_NAME}_core OBJECT) target_sources(${PROJECT_NAME}_core PRIVATE homeblks_impl.cpp volume_mgr.cpp + listener.cpp ) target_link_libraries(${PROJECT_NAME}_core ${COMMON_DEPS} ) #add_subdirectory(homestore_backend) -add_subdirectory(memory_backend) +#add_subdirectory(memory_backend) add_subdirectory(tests) diff --git a/src/lib/homeblks_impl.cpp b/src/lib/homeblks_impl.cpp index 3a6207a..4be042b 100644 --- a/src/lib/homeblks_impl.cpp +++ b/src/lib/homeblks_impl.cpp @@ -1,7 +1,11 @@ #include +#include +#include +#include #include #include "homeblks_impl.hpp" +#include "listener.hpp" SISL_OPTION_GROUP(homeblocks, (executor_type, "", "executor", "Executor to use for Future deferal", @@ -10,6 +14,20 @@ SISL_OPTION_GROUP(homeblocks, SISL_LOGGING_DEF(HOMEBLOCKS_LOG_MODS) namespace homeblocks { + +extern std::shared_ptr< HomeBlocks > init_homeobject(std::weak_ptr< HomeBlocksApplication >&& application) { + LOGI("Initializing HomeBlocks"); + auto inst = std::make_shared< HomeBlocksImpl >(std::move(application)); + inst->init_homestore(); + inst->init_cp(); + return inst; +} + +HomeBlocksStats HomeBlocksImpl::get_stats() const { + HomeBlocksStats s; + return s; +} + HomeBlocksImpl::HomeBlocksImpl(std::weak_ptr< HomeBlocksApplication >&& application) : _application(std::move(application)) { auto exe_type = SISL_OPTIONS["executor"].as< std::string >(); @@ -25,4 +43,169 @@ HomeBlocksImpl::HomeBlocksImpl(std::weak_ptr< HomeBlocksApplication >&& applicat RELEASE_ASSERT(false, "Unknown Folly Executor type: [{}]", exe_type); LOGI("initialized with [executor={}]", exe_type); } + +DevType HomeBlocksImpl::get_device_type(std::string const& devname) { + const iomgr::drive_type dtype = iomgr::DriveInterface::get_drive_type(devname); + if (dtype == iomgr::drive_type::block_hdd || dtype == iomgr::drive_type::file_on_hdd) { return DevType::HDD; } + if (dtype == iomgr::drive_type::file_on_nvme || dtype == iomgr::drive_type::block_nvme) { return DevType::NVME; } + return DevType::UNSUPPORTED; +} + +// repl application to init homestore +class HBReplApp : public homestore::ReplApplication { +public: + HBReplApp(homestore::repl_impl_type impl_type, bool tl_consistency, HomeBlocksImpl* hb, + std::weak_ptr< HomeBlocksApplication > ho_app) : + impl_type_(impl_type), tl_consistency_(tl_consistency), hb_(hb), ho_app_(ho_app) {} + + // TODO: make this override after the base class in homestore adds a virtual destructor + virtual ~HBReplApp() = default; + + // overrides + homestore::repl_impl_type get_impl_type() const override { return impl_type_; } + + bool need_timeline_consistency() const override { return tl_consistency_; } + + // this will be called by homestore when create_repl_dev is called; + std::shared_ptr< homestore::ReplDevListener > create_repl_dev_listener(homestore::group_id_t group_id) override { + return std::make_shared< HBListener >(hb_); +#if 0 + std::scoped_lock lock_guard(_repl_sm_map_lock); + auto [it, inserted] = _repl_sm_map.emplace(group_id, nullptr); + if (inserted) { it->second = std::make_shared< ReplicationStateMachine >(hb_); } + return it->second; +#endif + } + + void on_repl_devs_init_completed() override { hb_->on_init_complete(); } + + std::pair< std::string, uint16_t > lookup_peer(homestore::replica_id_t uuid) const override { + // r1: should never come here; + RELEASE_ASSERT(false, "Unexpected to be called."); + return std::make_pair("", 0); + } + + homestore::replica_id_t get_my_repl_id() const override { return hb_->our_uuid(); } + +private: + homestore::repl_impl_type impl_type_; + bool tl_consistency_; // indicates whether this application needs timeline consistency; + HomeBlocksImpl* hb_; + std::weak_ptr< HomeBlocksApplication > ho_app_; +#if 0 + std::map< homestore::group_id_t, std::shared_ptr< HBListener> > _repl_sm_map; + std::mutex _repl_sm_map_lock; +#endif +}; + +void HomeBlocksImpl::init_homestore() { + auto app = _application.lock(); + RELEASE_ASSERT(app, "HomeObjectApplication lifetime unexpected!"); + + LOGI("Starting iomgr with {} threads, spdk: {}", app->threads(), false); + ioenvironment.with_iomgr(iomgr::iomgr_params{.num_threads = app->threads(), .is_spdk = app->spdk_mode()}) + .with_http_server(); + + const uint64_t app_mem_size = app->app_mem_size(); + LOGI("Initialize and start HomeStore with app_mem_size = {}", app_mem_size); + + std::vector< homestore::dev_info > device_info; + bool has_data_dev = false; + bool has_fast_dev = false; + for (auto const& dev : app->devices()) { + // TODO: Simplify this logic; + auto input_dev_type = dev.type; + auto detected_type = get_device_type(dev.path.string()); + LOGD("Device {} detected as {}", dev.path.string(), detected_type); + auto final_type = (dev.type == DevType::AUTO_DETECT) ? detected_type : input_dev_type; + if (final_type == DevType::UNSUPPORTED) { + LOGW("Device {} is not supported, skipping", dev.path.string()); + continue; + } + if (input_dev_type != DevType::AUTO_DETECT && detected_type != final_type) { + LOGW("Device {} detected as {}, but input type is {}, using input type", dev.path.string(), detected_type, + input_dev_type); + } + auto hs_type = (final_type == DevType::HDD) ? homestore::HSDevType::Data : homestore::HSDevType::Fast; + if (hs_type == homestore::HSDevType::Data) { has_data_dev = true; } + if (hs_type == homestore::HSDevType::Fast) { has_fast_dev = true; } + device_info.emplace_back(std::filesystem::canonical(dev.path).string(), hs_type); + } + + RELEASE_ASSERT(device_info.size() != 0, "No supported devices found!"); + using namespace homestore; + // Note: timeline_consistency doesn't matter as we are using solo repl dev; + auto repl_app = + std::make_shared< HBReplApp >(repl_impl_type::solo, false /*timeline_consistency*/, this, _application); + bool need_format = HomeStore::instance() + ->with_index_service(std::make_unique< HBIndexSvcCB >(this)) + .with_repl_data_service(repl_app) // chunk selector defaulted to round_robine + .start(hs_input_params{.devices = device_info, .app_mem_size = app_mem_size}, + [this]() { register_metablk_cb(); }); + + if (need_format) { + LOGI("We are starting for the first time. Formatting HomeStore. "); + if (has_data_dev && has_fast_dev) { + HomeStore::instance()->format_and_start({ + {HS_SERVICE::META, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 9.0, .num_chunks = 64}}, + {HS_SERVICE::LOG, + hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .chunk_size = 32 * Mi}}, + {HS_SERVICE::INDEX, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .num_chunks = 128}}, + {HS_SERVICE::REPLICATION, + hs_format_params{.dev_type = HSDevType::Data, + .size_pct = 95.0, + .num_chunks = 0, + .chunk_size = HS_CHUNK_SIZE, + .block_size = DATA_BLK_SIZE}}, + }); + } else { + auto run_on_type = has_fast_dev ? homestore::HSDevType::Fast : homestore::HSDevType::Data; + LOGD("Running with Single mode, all service on {}", run_on_type); + HomeStore::instance()->format_and_start({ + {HS_SERVICE::META, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}}, + {HS_SERVICE::LOG, hs_format_params{.dev_type = run_on_type, .size_pct = 10.0, .chunk_size = 32 * Mi}}, + {HS_SERVICE::INDEX, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}}, + {HS_SERVICE::REPLICATION, + hs_format_params{.dev_type = run_on_type, + .size_pct = 75.0, + .num_chunks = 0, + .chunk_size = HS_CHUNK_SIZE, + .block_size = DATA_BLK_SIZE}}, + }); + } + repl_app->on_repl_devs_init_completed(); + superblk_init(); + } + + recovery_done_ = true; + LOGI("Initialize and start HomeStore is successfully"); +} + +void HomeBlocksImpl::superblk_init() { + auto sb = homestore::superblk< homeblks_sb_t >(HB_META_NAME); + sb.create(sizeof(homeblks_sb_t)); + sb->magic = HB_SB_MAGIC; + sb->version = HB_SB_VER; + sb->boot_cnt = 0; + sb->init_flag(0); + sb.write(); +} + +void HomeBlocksImpl::register_metablk_cb() { + // register some callbacks for metadata recovery; + using namespace homestore; + HomeStore::instance()->meta_service().register_handler( + HB_META_NAME, + [this](homestore::meta_blk* mblk, sisl::byte_view buf, size_t size) { + auto sb = homestore::superblk< homeblks_sb_t >(HB_META_NAME); + sb.load(buf, mblk); + }, + nullptr /*recovery_comp_cb*/, true /* do_crc */); +} + +void HomeBlocksImpl::on_init_complete() { + // TODO: register to meta service for HomeBlks meta block handler; +} + +void HomeBlocksImpl::init_cp() {} } // namespace homeblocks diff --git a/src/lib/homeblks_impl.hpp b/src/lib/homeblks_impl.hpp index 50e7ef7..633dbdc 100644 --- a/src/lib/homeblks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -1,8 +1,10 @@ #pragma once - +#include #include #include - +#include +#include +#include #include #include @@ -29,7 +31,12 @@ using intrusive = boost::intrusive_ptr< T >; template < typename T > using cintrusive = const boost::intrusive_ptr< T >; - +#if 0 +class VolumeIndexKey; +class VolumeIndexValue; +using VolumeIndexTable = homestore::IndexTable< VolumeIndexKey, VolumeIndexValue >; +#endif +// TODO: move Volume to volume file struct Volume { explicit Volume(VolumeInfo info) : volume_info_(std::move(info)) {} Volume(Volume const& volume) = delete; @@ -42,27 +49,37 @@ struct Volume { }; class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enable_shared_from_this< HomeBlocksImpl > { - // TODO: we don't plan to have another HSHomeBlksImpl, so can remove _create_volume; - virtual VolumeManager::NullAsyncResult _create_volume(VolumeInfo&& volume_info) = 0; - virtual bool _get_stats(volume_id_t id, VolumeStats& stats) const = 0; - virtual void _get_volume_ids(std::vector< volume_id_t >& vol_ids) const = 0; - - virtual HomeBlocksStats _get_stats() const = 0; - -protected: - peer_id_t _our_id; - + struct homeblks_sb_t { + uint64_t magic; + uint32_t version; + uint32_t flag; + uint64_t boot_cnt; + + void init_flag(uint32_t f) { flag = f; } + void set_flag(uint32_t bit) { flag |= bit; } + void clear_flag(uint32_t bit) { flag &= ~bit; } + bool test_flag(uint32_t bit) { return flag & bit; } + }; + +private: + inline static auto const HB_META_NAME = std::string("HomeBlks2"); + static constexpr uint64_t HB_SB_MAGIC{0xCEEDDEEB}; + static constexpr uint32_t HB_SB_VER{0x1}; + static constexpr uint64_t HS_CHUNK_SIZE = 2 * Gi; + static constexpr uint32_t DATA_BLK_SIZE = 4096; + static constexpr uint32_t SB_FLAGS_CLEAN_SHUTDOWN{0x00000001}; + static constexpr uint32_t SB_FLAGS_RESTRICTED{0x00000002}; + +private: /// Our SvcId retrieval and SvcId->IP mapping std::weak_ptr< HomeBlocksApplication > _application; - folly::Executor::KeepAlive<> executor_; /// mutable std::shared_mutex _volume_lock; std::map< volume_id_t, unique< Volume > > _volume_map; - - auto _defer() const { return folly::makeSemiFuture().via(executor_); } + bool recovery_done_{false}; public: explicit HomeBlocksImpl(std::weak_ptr< HomeBlocksApplication >&& application); @@ -73,25 +90,58 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab HomeBlocksImpl& operator=(const HomeBlocksImpl&) = delete; HomeBlocksImpl& operator=(HomeBlocksImpl&&) noexcept = delete; - std::shared_ptr< VolumeManager > volume_manager() final; + shared< VolumeManager > volume_manager() final; /// HomeBlocks /// Returns the UUID of this HomeBlocks. - peer_id_t our_uuid() const final { return _our_id; } - HomeBlocksStats get_stats() const final { return _get_stats(); } + HomeBlocksStats get_stats() const final; + peer_id_t our_uuid() const final { + // not expected to be called; + return peer_id_t{}; + } /// VolumeManager NullAsyncResult create_volume(VolumeInfo&& vol_info) final; NullAsyncResult remove_volume(const volume_id_t& id) final; - + VolumePtr lookup_volume(const volume_id_t& id) final; // see api comments in base class; bool get_stats(volume_id_t id, VolumeStats& stats) const final; void get_volume_ids(std::vector< volume_id_t >& vol_ids) const final; + // Index + // shared< VolumeIndexTable > recover_index_table(homestore::superblk< homestore::index_table_sb >&& sb); + + // HomeStore + void init_homestore(); + void init_cp(); + uint64_t get_current_timestamp(); + + void on_init_complete(); + +private: + // Should only be called for first-time-boot + void superblk_init(); + void register_metablk_cb(); + + DevType get_device_type(std::string const& devname); + auto defer() const { return folly::makeSemiFuture().via(executor_); } }; +class HBIndexSvcCB : public homestore::IndexServiceCallbacks { +public: + HBIndexSvcCB(HomeBlocksImpl* hb) : hb_(hb) {} + shared< homestore::IndexTableBase > + on_index_table_found(homestore::superblk< homestore::index_table_sb >&& sb) override { + LOGI("Recovered index table to index service"); + // return hb_->recover_index_table(std::move(sb)); // TODO: + return nullptr; + } + +private: + HomeBlocksImpl* hb_; +}; } // namespace homeblocks diff --git a/src/lib/listener.cpp b/src/lib/listener.cpp new file mode 100644 index 0000000..945b141 --- /dev/null +++ b/src/lib/listener.cpp @@ -0,0 +1,22 @@ +#include "listener.hpp" + +namespace homeblocks { + +void HBListener::on_commit(int64_t lsn, sisl::blob const& header, sisl::blob const& key, + homestore::MultiBlkId const& blkids, cintrusive< homestore::repl_req_ctx >& ctx) {} + +bool HBListener::on_pre_commit(int64_t lsn, const sisl::blob& header, const sisl::blob& key, + cintrusive< homestore::repl_req_ctx >& ctx) { + return true; +} + +void HBListener::on_error(homestore::ReplServiceError error, const sisl::blob& header, const sisl::blob& key, + cintrusive< homestore::repl_req_ctx >& ctx) {} + +homestore::ReplResult< homestore::blk_alloc_hints > get_blk_alloc_hints(sisl::blob const& header, uint32_t data_size) { + return homestore::blk_alloc_hints(); +} + +void on_destroy(const homestore::group_id_t& group_id) {} + +} // namespace homeblocks diff --git a/src/lib/listener.hpp b/src/lib/listener.hpp new file mode 100644 index 0000000..2c24f5d --- /dev/null +++ b/src/lib/listener.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include "homeblks_impl.hpp" + +namespace homeblocks { + +class HomeBlocksImpl; + +class HBListener : public homestore::ReplDevListener { +public: + explicit HBListener(HomeBlocksImpl* hb) : hb_(hb) {} + + virtual ~HBListener() = default; + + void on_commit(int64_t lsn, sisl::blob const& header, sisl::blob const& key, homestore::MultiBlkId const& blkids, + cintrusive< homestore::repl_req_ctx >& ctx) override; + + bool on_pre_commit(int64_t lsn, const sisl::blob& header, const sisl::blob& key, + cintrusive< homestore::repl_req_ctx >& ctx) override; + + void on_error(homestore::ReplServiceError error, const sisl::blob& header, const sisl::blob& key, + cintrusive< homestore::repl_req_ctx >& ctx) override; + + homestore::ReplResult< homestore::blk_alloc_hints > get_blk_alloc_hints(sisl::blob const& header, + uint32_t data_size) override; + // group_id is the uuid generated by HomeBlocks when create_volume->create_repl_dev(gid) is called; + // when volume is being destroyed, on_destroy is going to be triggered to listener that this volume's gid is + // destroyed; + void on_destroy(const homestore::group_id_t& group_id) override; + + // <<<<< with r1: mock apis that will never be triggered >>>> + void on_replace_member(const homestore::replica_member_info& member_out, + const homestore::replica_member_info& member_in) override {} + void on_rollback(int64_t lsn, const sisl::blob& header, const sisl::blob& key, + cintrusive< homestore::repl_req_ctx >& ctx) override {} + void on_restart() override { LOGD("HBListener::on_restart()"); } + /// @brief Called when the snapshot is being created by nuraft; + homestore::AsyncReplResult<> create_snapshot(std::shared_ptr< homestore::snapshot_context > context) override { + return folly::makeSemiFuture< homestore::ReplResult< folly::Unit > >(folly::Unit{}); + } + virtual bool apply_snapshot(std::shared_ptr< homestore::snapshot_context > context) override { return true; } + virtual std::shared_ptr< homestore::snapshot_context > last_snapshot() override { return nullptr; } + virtual int read_snapshot_obj(std::shared_ptr< homestore::snapshot_context > context, + std::shared_ptr< homestore::snapshot_obj > snp_obj) override { + return 0; + } + virtual void write_snapshot_obj(std::shared_ptr< homestore::snapshot_context > context, + std::shared_ptr< homestore::snapshot_obj > snp_obj) override {} + virtual void free_user_snp_ctx(void*& user_snp_ctx) override {} + // <<<<< end of r1: mockup apis >>>>>>>>>> + +private: + HomeBlocksImpl* hb_{nullptr}; +}; +} // namespace homeblocks diff --git a/src/lib/memory_backend/CMakeLists.txt b/src/lib/memory_backend/CMakeLists.txt index 6851a30..2290273 100644 --- a/src/lib/memory_backend/CMakeLists.txt +++ b/src/lib/memory_backend/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable (memory_test) target_sources(memory_test PRIVATE $ ) + target_link_libraries(memory_test ${PROJECT_NAME}_memory ${COMMON_TEST_DEPS} diff --git a/src/lib/memory_backend/mem_homeblks.cpp b/src/lib/memory_backend/mem_homeblks.cpp index c70ce18..63d3213 100644 --- a/src/lib/memory_backend/mem_homeblks.cpp +++ b/src/lib/memory_backend/mem_homeblks.cpp @@ -9,7 +9,7 @@ extern std::shared_ptr< HomeBlocks > init_homeblocks(std::weak_ptr< HomeBlocksAp MemoryHomeBlocks::MemoryHomeBlocks(std::weak_ptr< HomeBlocksApplication >&& application) : HomeBlocksImpl::HomeBlocksImpl(std::move(application)) { - _our_id = _application.lock()->discover_svcid(std::nullopt); + // _our_id = _application.lock()->discover_svcid(std::nullopt); } } // namespace homeblocks diff --git a/src/lib/memory_backend/mem_homeblks.hpp b/src/lib/memory_backend/mem_homeblks.hpp index 4cf751c..8f8fa97 100644 --- a/src/lib/memory_backend/mem_homeblks.hpp +++ b/src/lib/memory_backend/mem_homeblks.hpp @@ -9,14 +9,6 @@ namespace homeblocks { class MemoryHomeBlocks : public HomeBlocksImpl { - // VolumeManager - VolumeManager::NullAsyncResult _create_volume(VolumeInfo&& vol_info) override; - - bool _get_stats(volume_id_t id, VolumeStats& stats) const override; - void _get_volume_ids(std::vector< volume_id_t >& volume_ids) const override; - - HomeBlocksStats _get_stats() const override; - public: MemoryHomeBlocks(std::weak_ptr< HomeBlocksApplication >&& application); ~MemoryHomeBlocks() override = default; diff --git a/src/lib/volume_mgr.cpp b/src/lib/volume_mgr.cpp index 963ee76..5610740 100644 --- a/src/lib/volume_mgr.cpp +++ b/src/lib/volume_mgr.cpp @@ -8,18 +8,14 @@ std::shared_ptr< VolumeManager > HomeBlocksImpl::volume_manager() { return share VolumeManager::NullAsyncResult HomeBlocksImpl::create_volume(VolumeInfo&& vol_info) { LOGI("[vol={}] is of capacity [{}B]", boost::uuids::to_string(vol_info.id), vol_info.size_bytes); - return _create_volume(std::move(vol_info)); -} - -VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) { return folly::Unit(); } -VolumePtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) { - return nullptr; -} +VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) { return folly::Unit(); } + +VolumePtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) { return nullptr; } -bool HomeBlocksImpl::get_stats(volume_id_t id, VolumeStats& stats) const { return _get_stats(id, stats); } -void HomeBlocksImpl::get_volume_ids(std::vector< volume_id_t >& vol_ids) const { return _get_volume_ids(vol_ids); } +bool HomeBlocksImpl::get_stats(volume_id_t id, VolumeStats& stats) const { return true; } -} // namespace homeobject +void HomeBlocksImpl::get_volume_ids(std::vector< volume_id_t >& vol_ids) const {} +} // namespace homeblocks From d7ade63edb29392cc6d4bcce7180b61754c4bb34 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Fri, 21 Feb 2025 11:58:16 -0700 Subject: [PATCH 5/8] homestore init --- src/lib/homeblks_impl.cpp | 55 +++++++++++++++++++++------------------ src/lib/homeblks_impl.hpp | 2 ++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/lib/homeblks_impl.cpp b/src/lib/homeblks_impl.cpp index 4be042b..772d1c3 100644 --- a/src/lib/homeblks_impl.cpp +++ b/src/lib/homeblks_impl.cpp @@ -98,22 +98,9 @@ class HBReplApp : public homestore::ReplApplication { #endif }; -void HomeBlocksImpl::init_homestore() { - auto app = _application.lock(); - RELEASE_ASSERT(app, "HomeObjectApplication lifetime unexpected!"); - - LOGI("Starting iomgr with {} threads, spdk: {}", app->threads(), false); - ioenvironment.with_iomgr(iomgr::iomgr_params{.num_threads = app->threads(), .is_spdk = app->spdk_mode()}) - .with_http_server(); - - const uint64_t app_mem_size = app->app_mem_size(); - LOGI("Initialize and start HomeStore with app_mem_size = {}", app_mem_size); - - std::vector< homestore::dev_info > device_info; - bool has_data_dev = false; - bool has_fast_dev = false; +void HomeBlocksImpl::get_dev_info(shared< HomeBlocksApplication > app, std::vector< homestore::dev_info >& dev_info, + bool& has_data_dev, bool& has_fast_dev) { for (auto const& dev : app->devices()) { - // TODO: Simplify this logic; auto input_dev_type = dev.type; auto detected_type = get_device_type(dev.path.string()); LOGD("Device {} detected as {}", dev.path.string(), detected_type); @@ -129,8 +116,24 @@ void HomeBlocksImpl::init_homestore() { auto hs_type = (final_type == DevType::HDD) ? homestore::HSDevType::Data : homestore::HSDevType::Fast; if (hs_type == homestore::HSDevType::Data) { has_data_dev = true; } if (hs_type == homestore::HSDevType::Fast) { has_fast_dev = true; } - device_info.emplace_back(std::filesystem::canonical(dev.path).string(), hs_type); + dev_info.emplace_back(std::filesystem::canonical(dev.path).string(), hs_type); } +} + +void HomeBlocksImpl::init_homestore() { + auto app = _application.lock(); + RELEASE_ASSERT(app, "HomeObjectApplication lifetime unexpected!"); + + LOGI("Starting iomgr with {} threads, spdk: {}", app->threads(), false); + ioenvironment.with_iomgr(iomgr::iomgr_params{.num_threads = app->threads(), .is_spdk = app->spdk_mode()}) + .with_http_server(); + + const uint64_t app_mem_size = app->app_mem_size(); + LOGI("Initialize and start HomeStore with app_mem_size = {}", app_mem_size); + + std::vector< homestore::dev_info > device_info; + bool has_data_dev{false}, has_fast_dev{false}; + get_dev_info(app, device_info, has_data_dev, has_fast_dev); RELEASE_ASSERT(device_info.size() != 0, "No supported devices found!"); using namespace homestore; @@ -142,19 +145,20 @@ void HomeBlocksImpl::init_homestore() { .with_repl_data_service(repl_app) // chunk selector defaulted to round_robine .start(hs_input_params{.devices = device_info, .app_mem_size = app_mem_size}, [this]() { register_metablk_cb(); }); - if (need_format) { LOGI("We are starting for the first time. Formatting HomeStore. "); if (has_data_dev && has_fast_dev) { + // NOTE: chunk_size, num_chunks only has to specify one, can be deduced from each other. HomeStore::instance()->format_and_start({ - {HS_SERVICE::META, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 9.0, .num_chunks = 64}}, + {HS_SERVICE::META, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 9.0}}, {HS_SERVICE::LOG, - hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .chunk_size = 32 * Mi}}, - {HS_SERVICE::INDEX, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0, .num_chunks = 128}}, + hs_format_params{ + .dev_type = HSDevType::Fast, .size_pct = 45.0, .num_chunks = 0, .chunk_size = 32 * Mi}}, + {HS_SERVICE::INDEX, hs_format_params{.dev_type = HSDevType::Fast, .size_pct = 45.0}}, {HS_SERVICE::REPLICATION, hs_format_params{.dev_type = HSDevType::Data, .size_pct = 95.0, - .num_chunks = 0, + .num_chunks = 0, // num_chunks will be deduced from chunk_size .chunk_size = HS_CHUNK_SIZE, .block_size = DATA_BLK_SIZE}}, }); @@ -162,13 +166,14 @@ void HomeBlocksImpl::init_homestore() { auto run_on_type = has_fast_dev ? homestore::HSDevType::Fast : homestore::HSDevType::Data; LOGD("Running with Single mode, all service on {}", run_on_type); HomeStore::instance()->format_and_start({ - {HS_SERVICE::META, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}}, - {HS_SERVICE::LOG, hs_format_params{.dev_type = run_on_type, .size_pct = 10.0, .chunk_size = 32 * Mi}}, - {HS_SERVICE::INDEX, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0, .num_chunks = 1}}, + {HS_SERVICE::META, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0}}, + {HS_SERVICE::LOG, + hs_format_params{.dev_type = run_on_type, .size_pct = 10.0, .num_chunks = 0, .chunk_size = 32 * Mi}}, + {HS_SERVICE::INDEX, hs_format_params{.dev_type = run_on_type, .size_pct = 5.0}}, {HS_SERVICE::REPLICATION, hs_format_params{.dev_type = run_on_type, .size_pct = 75.0, - .num_chunks = 0, + .num_chunks = 0, // num_chunks will be deduced from chunk_size; .chunk_size = HS_CHUNK_SIZE, .block_size = DATA_BLK_SIZE}}, }); diff --git a/src/lib/homeblks_impl.hpp b/src/lib/homeblks_impl.hpp index 633dbdc..dd3ad8a 100644 --- a/src/lib/homeblks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -127,6 +127,8 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab void superblk_init(); void register_metablk_cb(); + void get_dev_info(shared< HomeBlocksApplication > app, std::vector< homestore::dev_info >& device_info, + bool& has_data_dev, bool& has_fast_dev); DevType get_device_type(std::string const& devname); auto defer() const { return folly::makeSemiFuture().via(executor_); } }; From 5f53de66100b378056b3d8e09f457899a459be92 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Fri, 21 Feb 2025 12:27:31 -0700 Subject: [PATCH 6/8] upgrade sisl ver --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 8e4e728..adee492 100644 --- a/conanfile.py +++ b/conanfile.py @@ -46,7 +46,7 @@ def build_requirements(self): def requirements(self): self.requires("homestore/[^6.5]@oss/master") self.requires("iomgr/[^11.3]@oss/master") - self.requires("sisl/[~12.2, include_prerelease=True]@oss/master", transitive_headers=True) + self.requires("sisl/[^12.3, include_prerelease=True]@oss/master", transitive_headers=True) self.requires("lz4/1.9.4", override=True) def validate(self): From ae7e64f3ea6dab4a02fbcb0d61e85c5e06ccbef9 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Fri, 21 Feb 2025 16:19:03 -0700 Subject: [PATCH 7/8] incorperate comment --- src/include/homeblks/volume_mgr.hpp | 12 +++++------- src/lib/homeblks_impl.hpp | 2 +- src/lib/volume_mgr.cpp | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/include/homeblks/volume_mgr.hpp b/src/include/homeblks/volume_mgr.hpp index 70ebd58..427ee91 100644 --- a/src/include/homeblks/volume_mgr.hpp +++ b/src/include/homeblks/volume_mgr.hpp @@ -12,9 +12,6 @@ namespace homeblocks { ENUM(VolumeError, uint16_t, UNKNOWN = 1, INVALID_ARG, TIMEOUT, UNKNOWN_VOLUME, UNSUPPORTED_OP, CRC_MISMATCH, NO_SPACE_LEFT, DRIVE_WRITE_ERROR); -class Volume; -using VolumePtr = std::shared_ptr< Volume >; - struct VolumeInfo { VolumeInfo(volume_id_t _id, uint64_t _num_bytes) : id(_id), size_bytes(_num_bytes) {} @@ -30,11 +27,12 @@ struct VolumeInfo { auto operator==(VolumeInfo const& rhs) const { return id == rhs.id; } std::string to_string() { - return fmt::format("VolumeInfo: id={} size_bytes={}, page_size={}, name={}", boost::uuids::to_string(id), size_bytes, - page_size, vol_name); + return fmt::format("VolumeInfo: id={} size_bytes={}, page_size={}, name={}", boost::uuids::to_string(id), + size_bytes, page_size, vol_name); } }; +using VolumeInfoPtr = std::shared_ptr< VolumeInfo >; struct VolumeStats { volume_id_t id; @@ -52,8 +50,8 @@ class VolumeManager : public Manager< VolumeError > { virtual NullAsyncResult create_volume(VolumeInfo&& volume_info) = 0; virtual NullAsyncResult remove_volume(const volume_id_t& id) = 0; - - virtual VolumePtr lookup_volume(const volume_id_t& id) = 0; + + virtual VolumeInfoPtr lookup_volume(const volume_id_t& id) = 0; // TODO: read/write/unmap APIs diff --git a/src/lib/homeblks_impl.hpp b/src/lib/homeblks_impl.hpp index dd3ad8a..f2b6e8f 100644 --- a/src/lib/homeblks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -105,7 +105,7 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab NullAsyncResult remove_volume(const volume_id_t& id) final; - VolumePtr lookup_volume(const volume_id_t& id) final; + VolumeInfoPtr lookup_volume(const volume_id_t& id) final; // see api comments in base class; bool get_stats(volume_id_t id, VolumeStats& stats) const final; diff --git a/src/lib/volume_mgr.cpp b/src/lib/volume_mgr.cpp index 5610740..a0b434f 100644 --- a/src/lib/volume_mgr.cpp +++ b/src/lib/volume_mgr.cpp @@ -13,7 +13,7 @@ VolumeManager::NullAsyncResult HomeBlocksImpl::create_volume(VolumeInfo&& vol_in VolumeManager::NullAsyncResult HomeBlocksImpl::remove_volume(const volume_id_t& id) { return folly::Unit(); } -VolumePtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) { return nullptr; } +VolumeInfoPtr HomeBlocksImpl::lookup_volume(const volume_id_t& id) { return nullptr; } bool HomeBlocksImpl::get_stats(volume_id_t id, VolumeStats& stats) const { return true; } From 09391cf38b1314203e6eeb43724cd51d63381c08 Mon Sep 17 00:00:00 2001 From: Yaming Kuang Date: Fri, 21 Feb 2025 18:15:42 -0700 Subject: [PATCH 8/8] add HB and vol meta svc register and recovery cb --- src/lib/homeblks_impl.cpp | 57 ++++++++++++++++++++++++++++++++------- src/lib/homeblks_impl.hpp | 9 ++++++- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/lib/homeblks_impl.cpp b/src/lib/homeblks_impl.cpp index 772d1c3..1a10cf9 100644 --- a/src/lib/homeblks_impl.cpp +++ b/src/lib/homeblks_impl.cpp @@ -187,29 +187,66 @@ void HomeBlocksImpl::init_homestore() { } void HomeBlocksImpl::superblk_init() { - auto sb = homestore::superblk< homeblks_sb_t >(HB_META_NAME); - sb.create(sizeof(homeblks_sb_t)); - sb->magic = HB_SB_MAGIC; - sb->version = HB_SB_VER; - sb->boot_cnt = 0; - sb->init_flag(0); - sb.write(); + sb_ = homestore::superblk< homeblks_sb_t >(HB_META_NAME); + sb_.create(sizeof(homeblks_sb_t)); + sb_->magic = HB_SB_MAGIC; + sb_->version = HB_SB_VER; + sb_->boot_cnt = 0; + sb_->init_flag(0); + sb_.write(); +} + +void HomeBlocksImpl::on_vol_meta_blk_found(sisl::byte_view const& buf, void* cookie) { + // auto sb = homestore::superblk< vol_sb_t >(VOL_META_NAME); + // sb.load(buf, cookie); + // TODO: +} + +void HomeBlocksImpl::on_hb_meta_blk_found(sisl::byte_view const& buf, void* cookie) { + sb_ = homestore::superblk< homeblks_sb_t >(HB_META_NAME); + sb_.load(buf, cookie); + // sb verification + RELEASE_ASSERT_EQ(sb_->version, HB_SB_VER); + RELEASE_ASSERT_EQ(sb_->magic, HB_SB_MAGIC); + + if (sb_->test_flag(SB_FLAGS_GRACEFUL_SHUTDOWN)) { + // if it is a gracefuln shutdown, this flag should be set again in shutdown routine; + sb_->clear_flag(SB_FLAGS_GRACEFUL_SHUTDOWN); + LOGI("System was shutdown gracefully"); + } else { + LOGI("System experienced sudden crash since last boot"); + } + + ++sb_->boot_cnt; + + // avoid doing sb meta blk write in callback which will cause deadlock; + // the 1st CP should flush all dirty SB before taking traffic; } void HomeBlocksImpl::register_metablk_cb() { // register some callbacks for metadata recovery; using namespace homestore; + + // HomeBlks SB HomeStore::instance()->meta_service().register_handler( HB_META_NAME, [this](homestore::meta_blk* mblk, sisl::byte_view buf, size_t size) { - auto sb = homestore::superblk< homeblks_sb_t >(HB_META_NAME); - sb.load(buf, mblk); + on_hb_meta_blk_found(std::move(buf), voidptr_cast(mblk)); + }, + nullptr /*recovery_comp_cb*/, true /* do_crc */); + + // Volume SB + HomeStore::instance()->meta_service().register_handler( + VOL_META_NAME, + [this](homestore::meta_blk* mblk, sisl::byte_view buf, size_t size) { + on_vol_meta_blk_found(std::move(buf), voidptr_cast(mblk)); }, nullptr /*recovery_comp_cb*/, true /* do_crc */); } void HomeBlocksImpl::on_init_complete() { - // TODO: register to meta service for HomeBlks meta block handler; + // this is called after HomeStore all recovery completed. + // Add anything that needs to be done here. } void HomeBlocksImpl::init_cp() {} diff --git a/src/lib/homeblks_impl.hpp b/src/lib/homeblks_impl.hpp index f2b6e8f..34ef546 100644 --- a/src/lib/homeblks_impl.hpp +++ b/src/lib/homeblks_impl.hpp @@ -63,11 +63,12 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab private: inline static auto const HB_META_NAME = std::string("HomeBlks2"); + inline static auto const VOL_META_NAME = std::string("Volume2"); static constexpr uint64_t HB_SB_MAGIC{0xCEEDDEEB}; static constexpr uint32_t HB_SB_VER{0x1}; static constexpr uint64_t HS_CHUNK_SIZE = 2 * Gi; static constexpr uint32_t DATA_BLK_SIZE = 4096; - static constexpr uint32_t SB_FLAGS_CLEAN_SHUTDOWN{0x00000001}; + static constexpr uint32_t SB_FLAGS_GRACEFUL_SHUTDOWN{0x00000001}; static constexpr uint32_t SB_FLAGS_RESTRICTED{0x00000002}; private: @@ -80,6 +81,7 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab std::map< volume_id_t, unique< Volume > > _volume_map; bool recovery_done_{false}; + homestore::superblk< homeblks_sb_t > sb_; public: explicit HomeBlocksImpl(std::weak_ptr< HomeBlocksApplication >&& application); @@ -129,8 +131,13 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab void get_dev_info(shared< HomeBlocksApplication > app, std::vector< homestore::dev_info >& device_info, bool& has_data_dev, bool& has_fast_dev); + DevType get_device_type(std::string const& devname); auto defer() const { return folly::makeSemiFuture().via(executor_); } + + // recovery apis + void on_hb_meta_blk_found(sisl::byte_view const& buf, void* cookie); + void on_vol_meta_blk_found(sisl::byte_view const& buf, void* cookie); }; class HBIndexSvcCB : public homestore::IndexServiceCallbacks {