From 8baf433a7cccd239a719c3d1c2b39e1932cdccf5 Mon Sep 17 00:00:00 2001 From: qinyufei Date: Tue, 21 Jul 2026 14:40:38 +0800 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=E5=9F=BA=E4=BA=8E=20UBDIAG=5FDIS?= =?UTF-8?q?ABLE=20=E9=87=8D=E6=9E=84=20ubdiag=20=E9=9B=86=E6=88=90,FetchCo?= =?UTF-8?q?ntent=20=E6=9B=BF=E4=BB=A3=20submodule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 mooncake-common/FindUbDiag.cmake: 始终 FetchContent 拉源码,默认 UBDIAG_DISABLE constexpr 空函数,可选编译真实库+CLI。锁定 ubdiag v0.5.1。 三个子模块 CMakeLists: find_package(UbDiag) 改为 include(FindUbDiag.cmake)。 p2p-store/build.sh: 新增 UBDIAG_LAYER 参数,vendored 模式链接真实库,mock 模式跳过。 p2p-store/CMakeLists.txt: 传 MOONCAKE_UBDIAG_ACTIVE_LAYER 给 build.sh。 --- mooncake-common/FindUbDiag.cmake | 68 +++++++++++++++++++++ mooncake-integration/CMakeLists.txt | 2 +- mooncake-p2p-store/CMakeLists.txt | 9 ++- mooncake-p2p-store/build.sh | 21 ++++++- mooncake-store/src/CMakeLists.txt | 4 +- mooncake-transfer-engine/src/CMakeLists.txt | 2 +- 6 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 mooncake-common/FindUbDiag.cmake diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake new file mode 100644 index 0000000000..489b3c7606 --- /dev/null +++ b/mooncake-common/FindUbDiag.cmake @@ -0,0 +1,68 @@ +# FindUbDiag.cmake v2 — 基于 UBDIAG_DISABLE 的两层集成 +# +# Layer 0 (默认): FetchContent 拉源码 + 定义 UBDIAG_DISABLE → constexpr 空函数 +# Layer 1 (可选): FetchContent 拉源码 + 编译 ubdiag 库 + CLI +# +# Usage: +# include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) +# target_link_libraries(your_target PRIVATE UbDiag::ubdiag_lib) +# +# Options: +# -DMOONCAKE_ENABLE_UBDIAG=ON 编译真实 ubdiag (库 + CLI) +# -DMOONCAKE_ENABLE_UBDIAG=OFF (默认) 使用 UBDIAG_DISABLE 空函数 +# -DMOONCAKE_UBDIAG_GIT_TAG=v0.5.0 指定 ubdiag 版本 +# -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag 离线模式指定本地源码 + +if(TARGET UbDiag::ubdiag_lib) + return() +endif() + +option(MOONCAKE_ENABLE_UBDIAG "编译 ubdiag 真实库(否则用 UBDIAG_DISABLE 空函数)" OFF) +set(MOONCAKE_UBDIAG_GIT_TAG "v0.5.1" CACHE STRING "ubdiag 版本(tag/branch/commit)") +set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") + +include(FetchContent) + +# ===== 始终 FetchContent 拉取 ubdiag 源码(头文件必备) ===== +if(MOONCAKE_UBDIAG_SOURCE_DIR AND EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + FetchContent_Declare(ubdiag SOURCE_DIR ${MOONCAKE_UBDIAG_SOURCE_DIR}) +else() + FetchContent_Declare(ubdiag + GIT_REPOSITORY https://atomgit.com/liusiyu60/ubdiag.git + GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG}) +endif() + +# ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== +if(NOT MOONCAKE_ENABLE_UBDIAG) + FetchContent_MakeAvailable(ubdiag) + + # PerfPoint 变成 constexpr 空函数,编译器完全优化掉 + add_compile_definitions(UBDIAG_DISABLE) + + # 提供头文件路径 + add_library(ubdiag_mock INTERFACE) + target_include_directories(ubdiag_mock INTERFACE ${ubdiag_SOURCE_DIR}/include) + add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock) + + set(MOONCAKE_UBDIAG_ACTIVE_LAYER "mock" CACHE STRING "" FORCE) + message(STATUS "UbDiag: UBDIAG_DISABLE(空函数,零依赖)") + return() +endif() + +# ===== Layer 1: 编译真实 ubdiag ===== +set(BUILD_TESTS OFF CACHE BOOL "" FORCE) +set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) +set(UBDIAG_BUILD_SHARED ON CACHE BOOL "" FORCE) +set(ENABLE_PERCENTILE ON CACHE BOOL "" FORCE) +set(ENABLE_PERFLOG ON CACHE BOOL "" FORCE) +set(ENABLE_OB_MEMORY OFF CACHE BOOL "" FORCE) +set(ENABLE_OB_CACHE OFF CACHE BOOL "" FORCE) +set(ENABLE_MEMPOINT OFF CACHE BOOL "" FORCE) + +FetchContent_MakeAvailable(ubdiag) + +if(TARGET ubdiag_lib) + add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) + set(MOONCAKE_UBDIAG_ACTIVE_LAYER "vendored" CACHE STRING "" FORCE) + message(STATUS "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI)") +endif() diff --git a/mooncake-integration/CMakeLists.txt b/mooncake-integration/CMakeLists.txt index 42e3d1d97c..5bd064941b 100644 --- a/mooncake-integration/CMakeLists.txt +++ b/mooncake-integration/CMakeLists.txt @@ -107,7 +107,7 @@ if(WITH_STORE) store/engram_store_py.cpp integration_utils.h) set_target_properties(store PROPERTIES INSTALL_RPATH "$ORIGIN") - find_package(UbDiag REQUIRED) + include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) target_include_directories(store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/store) target_link_libraries(store PRIVATE UbDiag::ubdiag_lib) diff --git a/mooncake-p2p-store/CMakeLists.txt b/mooncake-p2p-store/CMakeLists.txt index 5b9980de90..04b5fe706b 100644 --- a/mooncake-p2p-store/CMakeLists.txt +++ b/mooncake-p2p-store/CMakeLists.txt @@ -2,7 +2,14 @@ add_custom_target(build_p2p_store DEPENDS transfer_engine) add_custom_command( TARGET build_p2p_store - COMMAND bash build.sh ${CMAKE_CURRENT_BINARY_DIR} ${USE_ETCD} ${USE_REDIS} ${USE_HTTP} ${USE_ETCD_LEGACY} ${CMAKE_BINARY_DIR} + COMMAND bash build.sh + ${CMAKE_CURRENT_BINARY_DIR} + ${USE_ETCD} + ${USE_REDIS} + ${USE_HTTP} + ${USE_ETCD_LEGACY} + ${CMAKE_BINARY_DIR} + ${MOONCAKE_UBDIAG_ACTIVE_LAYER} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) set_property(TARGET build_p2p_store PROPERTY EXCLUDE_FROM_ALL FALSE) diff --git a/mooncake-p2p-store/build.sh b/mooncake-p2p-store/build.sh index 520227b0c2..9ba1a6151c 100644 --- a/mooncake-p2p-store/build.sh +++ b/mooncake-p2p-store/build.sh @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -if [ "$#" -ne 6 ]; then - echo "Usage: $0 TARGET_PATH USE_ETCD USE_REDIS USE_HTTP USE_ETCD_LEGACY BUILD_DIR" +if [ "$#" -ne 7 ]; then + echo "Usage: $0 TARGET_PATH USE_ETCD USE_REDIS USE_HTTP USE_ETCD_LEGACY BUILD_DIR UBDIAG_LAYER" exit 1 fi @@ -24,6 +24,7 @@ USE_REDIS=$3 USE_HTTP=$4 USE_ETCD_LEGACY=$5 BUILD_DIR=$6 +UBDIAG_LAYER=$7 cd "src/p2pstore" if [ $? -ne 0 ]; then @@ -35,7 +36,21 @@ EXT_LDFLAGS="-L$BUILD_DIR/mooncake-transfer-engine/src" EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-transfer-engine/src/common/base" EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common" EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common/src" -EXT_LDFLAGS+=" -ltransfer_engine -lubdiag -lbase -lasio -lstdc++ -lnuma -lglog -libverbs -lmlx5 -ljsoncpp -lmooncake_common -lm" +EXT_LDFLAGS+=" -ltransfer_engine -lbase -lasio -lstdc++ -lnuma -lglog -libverbs -lmlx5 -ljsoncpp -lmooncake_common -lm" + +# ubdiag 链接: vendored 模式链接真实库, mock 模式跳过(空函数无库) +case "$UBDIAG_LAYER" in + vendored) + UBDIAG_LIB_DIR="$BUILD_DIR/_deps/ubdiag-build/src/sdk" + EXT_LDFLAGS+=" -L$UBDIAG_LIB_DIR -lubdiag" + ;; + mock) + echo "P2P Store: ubdiag DISABLE 模式,跳过 -lubdiag" + ;; + *) + echo "P2P Store: 未知 ubdiag layer: $UBDIAG_LAYER,跳过 -lubdiag" + ;; +esac if [ -d "/usr/local/cuda/lib64/stubs" ]; then EXT_LDFLAGS+=" -L/usr/local/cuda/lib64/stubs" diff --git a/mooncake-store/src/CMakeLists.txt b/mooncake-store/src/CMakeLists.txt index c6328b703e..0f8d7db6b5 100644 --- a/mooncake-store/src/CMakeLists.txt +++ b/mooncake-store/src/CMakeLists.txt @@ -250,8 +250,8 @@ target_link_libraries( ${EXTRA_LIBS} ${SPDK_STATIC_LIBS} asio_shared mooncake_common PRIVATE transfer_engine) -# UbDiag instrumentation -find_package(UbDiag REQUIRED) +# UbDiag instrumentation (FetchContent + UBDIAG_DISABLE 两层集成) +include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) target_link_libraries(mooncake_store PRIVATE UbDiag::ubdiag_lib) target_include_directories(mooncake_store PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../mooncake-integration/store) diff --git a/mooncake-transfer-engine/src/CMakeLists.txt b/mooncake-transfer-engine/src/CMakeLists.txt index 80c1cd0a3b..79eb64ce9b 100644 --- a/mooncake-transfer-engine/src/CMakeLists.txt +++ b/mooncake-transfer-engine/src/CMakeLists.txt @@ -1,5 +1,5 @@ file(GLOB ENGINE_SOURCES "*.cpp") -find_package(UbDiag REQUIRED) +include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) add_subdirectory(common) add_subdirectory(transport) From 411e9b838d9a344fe50755831b8aa5fccb20e939 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 21 Jul 2026 15:41:14 +0800 Subject: [PATCH 02/18] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=20DISABLE=20?= =?UTF-8?q?=E5=B1=82=E6=BA=90=E7=A0=81=E6=8B=89=E5=8F=96=E5=92=8C=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=BC=80=E5=85=B3=E4=BC=A0=E6=92=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 489b3c7606..d124e4a9d5 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -34,14 +34,31 @@ endif() # ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== if(NOT MOONCAKE_ENABLE_UBDIAG) - FetchContent_MakeAvailable(ubdiag) + # Populate the source tree only. FetchContent_MakeAvailable() would also add + # UbDiag's library, CLI, tests and examples to the Mooncake build. + FetchContent_GetProperties(ubdiag) + if(NOT ubdiag_POPULATED) + FetchContent_Populate(ubdiag) + endif() - # PerfPoint 变成 constexpr 空函数,编译器完全优化掉 - add_compile_definitions(UBDIAG_DISABLE) + set(_MOONCAKE_UBDIAG_PERF_POINT_HEADER + "${ubdiag_SOURCE_DIR}/include/ubdiag/perf_point.h") + if(NOT EXISTS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}") + message(FATAL_ERROR + "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} is missing include/ubdiag/perf_point.h") + endif() + file(STRINGS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}" + _MOONCAKE_UBDIAG_DISABLE_LINES REGEX "UBDIAG_DISABLE") + if(NOT _MOONCAKE_UBDIAG_DISABLE_LINES) + message(FATAL_ERROR + "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} does not support UBDIAG_DISABLE. " + "Select an UbDiag release that contains the compile-time disabled PerfPoint implementation.") + endif() - # 提供头文件路径 + # Consumers inherit both the source include path and the compile-time switch. add_library(ubdiag_mock INTERFACE) target_include_directories(ubdiag_mock INTERFACE ${ubdiag_SOURCE_DIR}/include) + target_compile_definitions(ubdiag_mock INTERFACE UBDIAG_DISABLE) add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock) set(MOONCAKE_UBDIAG_ACTIVE_LAYER "mock" CACHE STRING "" FORCE) From 14a15a70423a88ecf85203b48b209a3b6a47987c Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 21 Jul 2026 15:59:53 +0800 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20=E5=88=87=E6=8D=A2=20UbDiag=20Git?= =?UTF-8?q?Hub=20=E9=95=9C=E5=83=8F=E5=B9=B6=E5=9B=BA=E5=AE=9A=E4=B8=BB?= =?UTF-8?q?=E4=BB=93=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 62 +++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index d124e4a9d5..ce107f660f 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -10,7 +10,7 @@ # Options: # -DMOONCAKE_ENABLE_UBDIAG=ON 编译真实 ubdiag (库 + CLI) # -DMOONCAKE_ENABLE_UBDIAG=OFF (默认) 使用 UBDIAG_DISABLE 空函数 -# -DMOONCAKE_UBDIAG_GIT_TAG=v0.5.0 指定 ubdiag 版本 +# -DMOONCAKE_UBDIAG_GIT_TAG= 指定 ubdiag 版本 # -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag 离线模式指定本地源码 if(TARGET UbDiag::ubdiag_lib) @@ -18,27 +18,30 @@ if(TARGET UbDiag::ubdiag_lib) endif() option(MOONCAKE_ENABLE_UBDIAG "编译 ubdiag 真实库(否则用 UBDIAG_DISABLE 空函数)" OFF) -set(MOONCAKE_UBDIAG_GIT_TAG "v0.5.1" CACHE STRING "ubdiag 版本(tag/branch/commit)") +set(MOONCAKE_UBDIAG_GIT_REPOSITORY + "https://github.com/LinQuickDev/ubdiag.git" + CACHE STRING "ubdiag Git repository") +set(MOONCAKE_UBDIAG_GIT_TAG + "705c6c37da45df2be4bc64c134dca0b7f30b2113" + CACHE STRING "ubdiag 版本(tag/branch/commit)") set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") include(FetchContent) -# ===== 始终 FetchContent 拉取 ubdiag 源码(头文件必备) ===== -if(MOONCAKE_UBDIAG_SOURCE_DIR AND EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") - FetchContent_Declare(ubdiag SOURCE_DIR ${MOONCAKE_UBDIAG_SOURCE_DIR}) -else() - FetchContent_Declare(ubdiag - GIT_REPOSITORY https://atomgit.com/liusiyu60/ubdiag.git - GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG}) -endif() - # ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== if(NOT MOONCAKE_ENABLE_UBDIAG) - # Populate the source tree only. FetchContent_MakeAvailable() would also add - # UbDiag's library, CLI, tests and examples to the Mooncake build. - FetchContent_GetProperties(ubdiag) - if(NOT ubdiag_POPULATED) - FetchContent_Populate(ubdiag) + # Populate the source tree only. The full FetchContent_Populate() form stays + # source-only without the deprecated single-argument call on newer CMake. + if(MOONCAKE_UBDIAG_SOURCE_DIR AND + EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") + else() + FetchContent_Populate(ubdiag + GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} + GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG} + SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" + BINARY_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-build" + SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") endif() set(_MOONCAKE_UBDIAG_PERF_POINT_HEADER @@ -67,6 +70,14 @@ if(NOT MOONCAKE_ENABLE_UBDIAG) endif() # ===== Layer 1: 编译真实 ubdiag ===== +if(MOONCAKE_UBDIAG_SOURCE_DIR AND EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + FetchContent_Declare(ubdiag SOURCE_DIR ${MOONCAKE_UBDIAG_SOURCE_DIR}) +else() + FetchContent_Declare(ubdiag + GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} + GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG}) +endif() + set(BUILD_TESTS OFF CACHE BOOL "" FORCE) set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(UBDIAG_BUILD_SHARED ON CACHE BOOL "" FORCE) @@ -79,6 +90,25 @@ set(ENABLE_MEMPOINT OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(ubdiag) if(TARGET ubdiag_lib) + # UbDiag master still uses CMAKE_SOURCE_DIR internally. When consumed by + # FetchContent that variable points at Mooncake, so add the real source paths + # to every UbDiag target without modifying the mirrored upstream sources. + foreach(_MOONCAKE_UBDIAG_LIB_TARGET + ubdiag_logger ubdiag_lib ubdiag_runtime_lib ubdiag_manager_lib + ubdiag_bpf_loader) + if(TARGET ${_MOONCAKE_UBDIAG_LIB_TARGET}) + target_include_directories(${_MOONCAKE_UBDIAG_LIB_TARGET} PUBLIC + $ + $) + endif() + endforeach() + if(TARGET ubdiag) + target_include_directories(ubdiag PRIVATE + ${ubdiag_SOURCE_DIR}/include + ${ubdiag_SOURCE_DIR}/src + ${ubdiag_SOURCE_DIR}/src/cli) + endif() + add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) set(MOONCAKE_UBDIAG_ACTIVE_LAYER "vendored" CACHE STRING "" FORCE) message(STATUS "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI)") From f240448ff8359aeaaae06d1919feebd3f5863448 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 21 Jul 2026 17:01:43 +0800 Subject: [PATCH 04/18] =?UTF-8?q?fix:=20=E5=9B=BA=E5=AE=9A=20UbDiag=20v0.5?= =?UTF-8?q?.1=20=E5=B9=B6=E4=BF=AE=E6=AD=A3=E5=85=A8=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index ce107f660f..99143a058d 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -22,7 +22,7 @@ set(MOONCAKE_UBDIAG_GIT_REPOSITORY "https://github.com/LinQuickDev/ubdiag.git" CACHE STRING "ubdiag Git repository") set(MOONCAKE_UBDIAG_GIT_TAG - "705c6c37da45df2be4bc64c134dca0b7f30b2113" + "v0.5.1" CACHE STRING "ubdiag 版本(tag/branch/commit)") set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") From e5b447b79b9ec4eb83c3c67876915108ed9b583d Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Wed, 22 Jul 2026 16:20:33 +0800 Subject: [PATCH 05/18] =?UTF-8?q?fix:=20=E9=9A=94=E7=A6=BBUbDiag=E6=9E=84?= =?UTF-8?q?=E5=BB=BA=E9=80=89=E9=A1=B9=E5=B9=B6=E8=A3=81=E5=89=AACachePoin?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 58 ++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 99143a058d..e0cf8d66a8 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -78,38 +78,46 @@ else() GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG}) endif() -set(BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(UBDIAG_BUILD_SHARED ON CACHE BOOL "" FORCE) set(ENABLE_PERCENTILE ON CACHE BOOL "" FORCE) set(ENABLE_PERFLOG ON CACHE BOOL "" FORCE) set(ENABLE_OB_MEMORY OFF CACHE BOOL "" FORCE) set(ENABLE_OB_CACHE OFF CACHE BOOL "" FORCE) set(ENABLE_MEMPOINT OFF CACHE BOOL "" FORCE) +set(UBDIAG_ENABLE_CACHEPOINT OFF CACHE BOOL "" FORCE) -FetchContent_MakeAvailable(ubdiag) +function(_mooncake_make_ubdiag_available) + # UbDiag still exposes generic BUILD_* options. Keep the overrides inside a + # function scope so Mooncake's own BUILD_EXAMPLES value is not changed. + set(BUILD_TESTS OFF) + set(BUILD_EXAMPLES OFF) + FetchContent_MakeAvailable(ubdiag) + set(ubdiag_SOURCE_DIR "${ubdiag_SOURCE_DIR}" PARENT_SCOPE) +endfunction() +_mooncake_make_ubdiag_available() -if(TARGET ubdiag_lib) - # UbDiag master still uses CMAKE_SOURCE_DIR internally. When consumed by - # FetchContent that variable points at Mooncake, so add the real source paths - # to every UbDiag target without modifying the mirrored upstream sources. - foreach(_MOONCAKE_UBDIAG_LIB_TARGET - ubdiag_logger ubdiag_lib ubdiag_runtime_lib ubdiag_manager_lib - ubdiag_bpf_loader) - if(TARGET ${_MOONCAKE_UBDIAG_LIB_TARGET}) - target_include_directories(${_MOONCAKE_UBDIAG_LIB_TARGET} PUBLIC - $ - $) - endif() - endforeach() - if(TARGET ubdiag) - target_include_directories(ubdiag PRIVATE - ${ubdiag_SOURCE_DIR}/include - ${ubdiag_SOURCE_DIR}/src - ${ubdiag_SOURCE_DIR}/src/cli) +if(NOT TARGET ubdiag_lib OR NOT TARGET ubdiag) + message(FATAL_ERROR + "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} did not create both ubdiag_lib and CLI targets") +endif() + +# UbDiag master still uses CMAKE_SOURCE_DIR internally. When consumed by +# FetchContent that variable points at Mooncake, so add the real source paths +# to every UbDiag target without modifying the mirrored upstream sources. +foreach(_MOONCAKE_UBDIAG_LIB_TARGET + ubdiag_logger ubdiag_lib ubdiag_runtime_lib ubdiag_manager_lib + ubdiag_bpf_loader) + if(TARGET ${_MOONCAKE_UBDIAG_LIB_TARGET}) + target_include_directories(${_MOONCAKE_UBDIAG_LIB_TARGET} PUBLIC + $ + $) endif() +endforeach() +target_include_directories(ubdiag PRIVATE + ${ubdiag_SOURCE_DIR}/include + ${ubdiag_SOURCE_DIR}/src + ${ubdiag_SOURCE_DIR}/src/cli) - add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) - set(MOONCAKE_UBDIAG_ACTIVE_LAYER "vendored" CACHE STRING "" FORCE) - message(STATUS "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI)") -endif() +add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) +set(MOONCAKE_UBDIAG_ACTIVE_LAYER "vendored" CACHE STRING "" FORCE) +message(STATUS "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI)") From 9dbac6b23fef46a20a1f68ff72b8f9242d64cfc5 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Wed, 22 Jul 2026 16:52:27 +0800 Subject: [PATCH 06/18] =?UTF-8?q?docs:=20=E8=A1=A5=E5=85=85UbDiag=E4=B8=A4?= =?UTF-8?q?=E5=B1=82=E5=88=86=E5=8F=91=E7=94=A8=E6=88=B7=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 155 +++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 docs/ubdiag_integration_guide.md diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md new file mode 100644 index 0000000000..5a80fcde3b --- /dev/null +++ b/docs/ubdiag_integration_guide.md @@ -0,0 +1,155 @@ +# Mooncake UbDiag 两层分发使用指南 + +Mooncake 通过统一的 CMake 接口提供 UbDiag 两层分发能力。默认模式将 +PerfPoint 编译为空实现;启用模式从同一份 UbDiag 源码同步构建 SDK 动态库 +与命令行工具,供 Mooncake 性能采集与分析使用。 + +## 1. 模式选择 + +| 模式 | CMake 选项 | 适用场景 | 构建产物 | +|------|------------|----------|----------| +| Layer 0:禁用模式 | `MOONCAKE_ENABLE_UBDIAG=OFF`(默认) | 不需要性能采集,保持零运行时依赖 | 仅使用 UbDiag 头文件;不生成或链接 `libubdiag` | +| Layer 1:启用模式 | `MOONCAKE_ENABLE_UBDIAG=ON` | 使用 PerfPoint、分位数、PerfLog 和 CSV 分析 Mooncake | 同步生成 `libubdiag.so` 与 `ubdiag` CLI | + +模式由编译期选项决定,不能在运行时切换。建议为两种模式使用独立构建目录。 + +## 2. 默认禁用模式 + +未指定 `MOONCAKE_ENABLE_UBDIAG` 时,Mooncake 默认使用 Layer 0: + +```bash +cmake -S . -B build +cmake --build build -j +``` + +也可以显式指定: + +```bash +cmake -S . -B build -DMOONCAKE_ENABLE_UBDIAG=OFF +cmake --build build -j +``` + +CMake 配置阶段应输出: + +```text +UbDiag: UBDIAG_DISABLE(空函数,零依赖) +``` + +该模式使用 UbDiag `v0.5.1` 的同一份公共头文件,并通过 +`UBDIAG_DISABLE` 将 PerfPoint 编译为空函数。Mooncake 无需启动 UbDiag, +也不需要安装 CLI 或动态库。可使用以下命令确认目标程序未链接 UbDiag: + +```bash +ldd | grep libubdiag +``` + +命令应无输出。 + +## 3. 启用 UbDiag + +需要采集 Mooncake PerfPoint 数据时,使用独立目录重新配置并构建: + +```bash +cmake -S . -B build-ubdiag -DMOONCAKE_ENABLE_UBDIAG=ON +cmake --build build-ubdiag -j +``` + +CMake 配置阶段应输出: + +```text +UbDiag: FetchContent 编译 v0.5.1(库+CLI) +``` + +默认构建目录下的关键产物为: + +```text +build-ubdiag/_deps/ubdiag-build/src/sdk/libubdiag.so +build-ubdiag/_deps/ubdiag-build/src/cli/ubdiag +``` + +运行前应使用本次构建生成的 CLI 和动态库: + +```bash +export UBDIAG_BUILD="$PWD/build-ubdiag/_deps/ubdiag-build" +export UBDIAG_CLI="$UBDIAG_BUILD/src/cli/ubdiag" +export LD_LIBRARY_PATH="$UBDIAG_BUILD/src/sdk${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +``` + +不得混用系统中其他版本的 `ubdiag` CLI 或 `libubdiag.so`。CLI 与 SDK +必须来自同一源码版本和同一次构建,以保证共享内存布局及功能开关一致。 + +## 4. 采集与分析 + +启动 UbDiag 共享内存,并启用 PerfLog: + +```bash +"$UBDIAG_CLI" start --perflog +"$UBDIAG_CLI" status +``` + +随后按 Mooncake 原有方式启动服务和业务负载。负载运行期间可执行: + +```bash +"$UBDIAG_CLI" show +"$UBDIAG_CLI" show --detail +"$UBDIAG_CLI" show --perflog +"$UBDIAG_CLI" watch --interval 1000 +"$UBDIAG_CLI" history -n 5 +``` + +其中 `show` 输出聚合统计及 P99/P999/P9999,`show --detail` 输出按核数据, +`show --perflog` 输出最近的单次探针记录。`watch` 使用 `Ctrl+C` 结束。 + +将分析结果导出为 CSV: + +```bash +mkdir -p ./ubdiag-results +"$UBDIAG_CLI" show --csv ./ubdiag-results +"$UBDIAG_CLI" show --detail --csv ./ubdiag-results +"$UBDIAG_CLI" history --csv ./ubdiag-results +``` + +分析结束后销毁共享内存: + +```bash +"$UBDIAG_CLI" stop +``` + +## 5. 离线源码 + +构建环境无法访问 GitHub 时,预先准备精确版本的 UbDiag 源码,并通过 +`MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: + +```bash +git clone --branch v0.5.1 https://github.com/LinQuickDev/ubdiag.git /opt/src/ubdiag +cmake -S . -B build-ubdiag \ + -DMOONCAKE_ENABLE_UBDIAG=ON \ + -DMOONCAKE_UBDIAG_SOURCE_DIR=/opt/src/ubdiag +cmake --build build-ubdiag -j +``` + +`MOONCAKE_UBDIAG_SOURCE_DIR` 同样适用于默认禁用模式;将上述命令中的 +`MOONCAKE_ENABLE_UBDIAG` 改为 `OFF` 即可。两种模式均不会在已指定本地 +源码时访问 UbDiag 远端仓库。 + +推荐校验源码版本: + +```bash +git -C /opt/src/ubdiag rev-parse HEAD +``` + +预期提交为 `705c6c37da45df2be4bc64c134dca0b7f30b2113`。 + +## 6. 验收标准 + +| 检查项 | Layer 0 | Layer 1 | +|--------|---------|---------| +| Mooncake 可正常编译和运行 | 必须 | 必须 | +| 目标程序链接 `libubdiag` | 否 | 是 | +| 生成 `ubdiag` CLI | 否 | 是 | +| `show` 返回 Mooncake PerfPoint 数据 | 不适用 | 必须 | +| P99/P999/P9999、PerfLog、CSV | 不适用 | 必须 | + +若启用模式下 CLI 无数据,应依次确认共享内存已启动、Mooncake 使用的是 +`build-ubdiag` 产物、运行时加载的是同目录 `libubdiag.so`,以及业务负载已 +实际经过 Mooncake PerfPoint 打点路径。 From 8e8074ce7b6af2b13f0a2712f11d96fa0985f69b Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Sat, 25 Jul 2026 18:41:43 +0800 Subject: [PATCH 07/18] =?UTF-8?q?fix:=20=E9=94=81=E5=AE=9ARPM=E5=86=85?= =?UTF-8?q?=E7=BD=AEUbDiag=E6=BA=90=E7=A0=81=E4=B8=8E=E6=9E=84=E5=BB=BA?= =?UTF-8?q?=E4=BA=A7=E7=89=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 66 +++++++-- mooncake-common/FindUbDiag.cmake | 161 +++++++++++++++++---- scripts/build_rpm.sh | 233 ++++++++++++++++++++++++++++++- 3 files changed, 423 insertions(+), 37 deletions(-) diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md index 5a80fcde3b..a18036756f 100644 --- a/docs/ubdiag_integration_guide.md +++ b/docs/ubdiag_integration_guide.md @@ -29,10 +29,10 @@ cmake -S . -B build -DMOONCAKE_ENABLE_UBDIAG=OFF cmake --build build -j ``` -CMake 配置阶段应输出: +CMake 配置阶段应输出(末尾同时打印已验证提交): ```text -UbDiag: UBDIAG_DISABLE(空函数,零依赖) +UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified 705c6c37da45df2be4bc64c134dca0b7f30b2113 ``` 该模式使用 UbDiag `v0.5.1` 的同一份公共头文件,并通过 @@ -54,10 +54,10 @@ cmake -S . -B build-ubdiag -DMOONCAKE_ENABLE_UBDIAG=ON cmake --build build-ubdiag -j ``` -CMake 配置阶段应输出: +CMake 配置阶段应输出(末尾同时打印已验证提交): ```text -UbDiag: FetchContent 编译 v0.5.1(库+CLI) +UbDiag: FetchContent 编译 v0.5.1(库+CLI), verified 705c6c37da45df2be4bc64c134dca0b7f30b2113 ``` 默认构建目录下的关键产物为: @@ -117,8 +117,8 @@ mkdir -p ./ubdiag-results ## 5. 离线源码 -构建环境无法访问 GitHub 时,预先准备精确版本的 UbDiag 源码,并通过 -`MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: +构建环境无法访问 GitHub 时,预先准备精确版本且保留 `.git` 元数据的 +UbDiag 洁净工作树,并通过 `MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: ```bash git clone --branch v0.5.1 https://github.com/LinQuickDev/ubdiag.git /opt/src/ubdiag @@ -132,15 +132,63 @@ cmake --build build-ubdiag -j `MOONCAKE_ENABLE_UBDIAG` 改为 `OFF` 即可。两种模式均不会在已指定本地 源码时访问 UbDiag 远端仓库。 -推荐校验源码版本: +配置阶段会自动执行以下等价校验,不需要人工确认: ```bash git -C /opt/src/ubdiag rev-parse HEAD +git -C /opt/src/ubdiag status --porcelain --untracked-files=all ``` -预期提交为 `705c6c37da45df2be4bc64c134dca0b7f30b2113`。 +提交必须为 `705c6c37da45df2be4bc64c134dca0b7f30b2113`,工作树必须无修改和 +未跟踪文件。升级 UbDiag 版本时,必须同时更新 +`MOONCAKE_UBDIAG_GIT_TAG` 和完整的 +`MOONCAKE_UBDIAG_EXPECTED_COMMIT`,不能只更换标签。 -## 6. 验收标准 +## 6. RPM 打包与来源保证 + +CMake 每次配置都会在当前构建目录生成 +`mooncake_ubdiag_rpm.env`。该清单记录当前层、UbDiag 源码目录、期望提交 +和实际提交。CLI 与动态库路径固定从当前 Mooncake build 的 +`_deps/ubdiag-build` 推导,清单不能把它们重定向到其他目录。 + +完成构建后执行: + +```bash +bash scripts/build_rpm.sh build-ubdiag rpm-output "$(uname -m)" +``` + +打包脚本不会搜索 `$PATH`、`LD_LIBRARY_PATH`、`/usr/bin`、`/usr/lib64` +或 `/usr/local` 中的 UbDiag,也不会使用 `find_package(UbDiag)`。它只接受 +CMake 清单指定的 FetchContent 源码和构建产物,并在出包前再次执行以下 +硬校验: + +1. 源码仓当前提交、配置时解析的提交和期望提交三者完全一致。 +2. 源码工作树保持洁净,避免同一 SHA 下混入本地修改。 +3. UbDiag 子构建目录的提交标记与当前源码一致;版本变化时只清理并重建 + 该子目录。 +4. CLI 和全部 `libubdiag.so*` 位于当前 Mooncake build 的 + `_deps/ubdiag-build` 内。 +5. CLI 确实依赖同一构建目录生成的 `libubdiag.so`。 +6. 复制到 RPM BUILDROOT 后逐文件比较,防止打包阶段替换产物。 + +Layer 0 的 RPM 不包含 UbDiag CLI 或动态库,并检查待打包 ELF 不依赖 +`libubdiag.so`。Layer 1 的 RPM 包含同一次构建生成的 CLI、动态库和配置, +同时写入 `/usr/share/doc/mooncake/ubdiag-provenance.txt`,记录提交 SHA +以及 CLI、动态库 SHA256。 + +同一构建目录先配置 Layer 0、后续再切换到 Layer 1 时,必须重新执行 CMake +配置和构建,再执行 RPM 脚本: + +```bash +cmake -S . -B build -DMOONCAKE_ENABLE_UBDIAG=ON +cmake --build build -j +bash scripts/build_rpm.sh build rpm-output "$(uname -m)" +``` + +重新配置会刷新来源清单;打包脚本只按最新清单处理。反向切回 Layer 0 时, +即使构建目录残留旧的 `libubdiag.so`,也不会将其打入 RPM。 + +## 7. 验收标准 | 检查项 | Layer 0 | Layer 1 | |--------|---------|---------| diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index e0cf8d66a8..25fa8860f4 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -11,9 +11,18 @@ # -DMOONCAKE_ENABLE_UBDIAG=ON 编译真实 ubdiag (库 + CLI) # -DMOONCAKE_ENABLE_UBDIAG=OFF (默认) 使用 UBDIAG_DISABLE 空函数 # -DMOONCAKE_UBDIAG_GIT_TAG= 指定 ubdiag 版本 +# -DMOONCAKE_UBDIAG_EXPECTED_COMMIT=<40-char SHA> 指定允许的精确提交 # -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag 离线模式指定本地源码 if(TARGET UbDiag::ubdiag_lib) + get_property(_MOONCAKE_UBDIAG_TARGET_OWNER GLOBAL + PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER) + if(NOT _MOONCAKE_UBDIAG_TARGET_OWNER STREQUAL "${CMAKE_BINARY_DIR}") + message(FATAL_ERROR + "UbDiag::ubdiag_lib already exists but was not created by Mooncake's " + "FetchContent integration. Remove any find_package(UbDiag), system " + "UbDiag target, or injected parent-project target before configuring.") + endif() return() endif() @@ -24,26 +33,100 @@ set(MOONCAKE_UBDIAG_GIT_REPOSITORY set(MOONCAKE_UBDIAG_GIT_TAG "v0.5.1" CACHE STRING "ubdiag 版本(tag/branch/commit)") +set(MOONCAKE_UBDIAG_EXPECTED_COMMIT + "705c6c37da45df2be4bc64c134dca0b7f30b2113" + CACHE STRING "Mooncake 允许使用的 ubdiag 精确提交 SHA") set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") include(FetchContent) -# ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== -if(NOT MOONCAKE_ENABLE_UBDIAG) - # Populate the source tree only. The full FetchContent_Populate() form stays - # source-only without the deprecated single-argument call on newer CMake. - if(MOONCAKE_UBDIAG_SOURCE_DIR AND - EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") - set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") - else() - FetchContent_Populate(ubdiag - GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} - GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG} - SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" - BINARY_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-build" - SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") +function(_mooncake_verify_ubdiag_source source_dir) + get_filename_component(_source_dir "${source_dir}" REALPATH) + string(TOLOWER "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" _expected_commit) + string(LENGTH "${_expected_commit}" _expected_commit_length) + if(NOT _expected_commit_length EQUAL 40 OR + NOT _expected_commit MATCHES "^[0-9a-f]+$") + message(FATAL_ERROR + "MOONCAKE_UBDIAG_EXPECTED_COMMIT must be a full 40-character Git SHA, " + "got: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}") + endif() + + find_program(_MOONCAKE_UBDIAG_GIT_EXECUTABLE NAMES git) + if(NOT _MOONCAKE_UBDIAG_GIT_EXECUTABLE OR + NOT EXISTS "${_source_dir}/CMakeLists.txt") + message(FATAL_ERROR + "UbDiag source is incomplete or git is unavailable: ${_source_dir}") endif() + execute_process( + COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" + rev-parse --verify HEAD + RESULT_VARIABLE _git_result + OUTPUT_VARIABLE _resolved_commit + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(TOLOWER "${_resolved_commit}" _resolved_commit) + if(NOT _git_result EQUAL 0 OR + NOT _resolved_commit STREQUAL _expected_commit) + message(FATAL_ERROR + "UbDiag source commit mismatch.\n" + " expected: ${_expected_commit}\n" + " resolved: ${_resolved_commit}\n" + " source: ${_source_dir}\n" + "Remove the stale _deps/ubdiag-src directory or select the matching " + "MOONCAKE_UBDIAG_EXPECTED_COMMIT.") + endif() + + execute_process( + COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" + status --porcelain --untracked-files=all + RESULT_VARIABLE _git_result + OUTPUT_VARIABLE _git_status + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT _git_result EQUAL 0 OR NOT _git_status STREQUAL "") + message(FATAL_ERROR + "UbDiag source worktree is not clean, so its HEAD SHA does not fully " + "describe the code that would be built:\n${_git_status}") + endif() + + set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "${_source_dir}" + CACHE PATH "Verified UbDiag source selected by Mooncake" FORCE) + set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "${_resolved_commit}" + CACHE STRING "Verified UbDiag source commit selected by Mooncake" FORCE) + set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "${_source_dir}" PARENT_SCOPE) + set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "${_resolved_commit}" PARENT_SCOPE) +endfunction() + +function(_mooncake_write_ubdiag_rpm_manifest layer) + set(_manifest "${CMAKE_BINARY_DIR}/mooncake_ubdiag_rpm.env") + file(WRITE "${_manifest}" "MOONCAKE_UBDIAG_LAYER=${layer}\n") + file(APPEND "${_manifest}" + "MOONCAKE_UBDIAG_GIT_REPOSITORY=${MOONCAKE_UBDIAG_GIT_REPOSITORY}\n" + "MOONCAKE_UBDIAG_GIT_TAG=${MOONCAKE_UBDIAG_GIT_TAG}\n" + "MOONCAKE_UBDIAG_EXPECTED_COMMIT=${MOONCAKE_UBDIAG_EXPECTED_COMMIT}\n" + "MOONCAKE_UBDIAG_RESOLVED_COMMIT=${MOONCAKE_UBDIAG_RESOLVED_COMMIT}\n" + "MOONCAKE_UBDIAG_SOURCE_DIR=${MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR}\n") + set(MOONCAKE_UBDIAG_RPM_MANIFEST "${_manifest}" + CACHE FILEPATH "Verified UbDiag RPM packaging manifest" FORCE) + set(MOONCAKE_UBDIAG_ACTIVE_LAYER "${layer}" + CACHE STRING "Active UbDiag integration layer: mock or vendored" FORCE) +endfunction() + +set(ubdiag_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-build") +if(MOONCAKE_UBDIAG_SOURCE_DIR AND + EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") +else() + FetchContent_Populate(ubdiag + GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} + GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG} + SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" + BINARY_DIR "${ubdiag_BINARY_DIR}" + SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") +endif() +_mooncake_verify_ubdiag_source("${ubdiag_SOURCE_DIR}") + +# ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== +if(NOT MOONCAKE_ENABLE_UBDIAG) set(_MOONCAKE_UBDIAG_PERF_POINT_HEADER "${ubdiag_SOURCE_DIR}/include/ubdiag/perf_point.h") if(NOT EXISTS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}") @@ -64,19 +147,42 @@ if(NOT MOONCAKE_ENABLE_UBDIAG) target_compile_definitions(ubdiag_mock INTERFACE UBDIAG_DISABLE) add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock) - set(MOONCAKE_UBDIAG_ACTIVE_LAYER "mock" CACHE STRING "" FORCE) - message(STATUS "UbDiag: UBDIAG_DISABLE(空函数,零依赖)") + set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER + "${CMAKE_BINARY_DIR}") + _mooncake_write_ubdiag_rpm_manifest("mock") + message(STATUS + "UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") return() endif() # ===== Layer 1: 编译真实 ubdiag ===== -if(MOONCAKE_UBDIAG_SOURCE_DIR AND EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") - FetchContent_Declare(ubdiag SOURCE_DIR ${MOONCAKE_UBDIAG_SOURCE_DIR}) -else() - FetchContent_Declare(ubdiag - GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} - GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG}) +set(_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE + "${ubdiag_BINARY_DIR}/mooncake-source-commit.txt") +set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR TRUE) +if(EXISTS "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}") + file(READ "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}" + _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT) + string(STRIP "${_MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT}" + _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT) + if(NOT _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT STREQUAL + MOONCAKE_UBDIAG_RESOLVED_COMMIT) + set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR FALSE) + endif() +elseif(EXISTS "${ubdiag_BINARY_DIR}") + file(GLOB _MOONCAKE_UBDIAG_EXISTING_BUILD_FILES + "${ubdiag_BINARY_DIR}/*") + if(_MOONCAKE_UBDIAG_EXISTING_BUILD_FILES) + set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR FALSE) + endif() +endif() +if(NOT _MOONCAKE_UBDIAG_REUSE_BINARY_DIR) + message(STATUS + "UbDiag: removing binary directory from a different or unverified source") + file(REMOVE_RECURSE "${ubdiag_BINARY_DIR}") endif() +file(MAKE_DIRECTORY "${ubdiag_BINARY_DIR}") +file(WRITE "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}" + "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}\n") set(UBDIAG_BUILD_SHARED ON CACHE BOOL "" FORCE) set(ENABLE_PERCENTILE ON CACHE BOOL "" FORCE) @@ -91,8 +197,7 @@ function(_mooncake_make_ubdiag_available) # function scope so Mooncake's own BUILD_EXAMPLES value is not changed. set(BUILD_TESTS OFF) set(BUILD_EXAMPLES OFF) - FetchContent_MakeAvailable(ubdiag) - set(ubdiag_SOURCE_DIR "${ubdiag_SOURCE_DIR}" PARENT_SCOPE) + add_subdirectory("${ubdiag_SOURCE_DIR}" "${ubdiag_BINARY_DIR}") endfunction() _mooncake_make_ubdiag_available() @@ -119,5 +224,9 @@ target_include_directories(ubdiag PRIVATE ${ubdiag_SOURCE_DIR}/src/cli) add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) -set(MOONCAKE_UBDIAG_ACTIVE_LAYER "vendored" CACHE STRING "" FORCE) -message(STATUS "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI)") +set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER + "${CMAKE_BINARY_DIR}") +_mooncake_write_ubdiag_rpm_manifest("vendored") +message(STATUS + "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI), " + "verified ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index e41b241d26..3b7d5f695d 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -46,10 +46,114 @@ echo "Cleaning previous RPM build..." rm -rf rpmbuild/ rm -rf ${OUTPUT_DIR}/ +fail_ubdiag_packaging() { + echo "Error: UbDiag RPM provenance check failed: $*" >&2 + return 1 +} + +load_ubdiag_rpm_manifest() { + local manifest=$1 + local key="" + local value="" + + if [ ! -f "${manifest}" ]; then + fail_ubdiag_packaging "manifest not found: ${manifest}" + return 1 + fi + + while IFS='=' read -r key value || [ -n "${key}" ]; do + value="${value%$'\r'}" + case "${key}" in + MOONCAKE_UBDIAG_LAYER|MOONCAKE_UBDIAG_GIT_REPOSITORY|\ + MOONCAKE_UBDIAG_GIT_TAG|MOONCAKE_UBDIAG_EXPECTED_COMMIT|\ + MOONCAKE_UBDIAG_RESOLVED_COMMIT|MOONCAKE_UBDIAG_SOURCE_DIR) + printf -v "${key}" '%s' "${value}" + ;; + "") + ;; + *) + fail_ubdiag_packaging \ + "unknown key '${key}' in ${manifest}" + return 1 + ;; + esac + done < "${manifest}" +} + +verify_ubdiag_source_provenance() { + local source_dir="" + local current_commit="" + local dirty="" + local required_tool="" + + for required_tool in git readelf readlink sha256sum; do + if ! command -v "${required_tool}" >/dev/null 2>&1; then + fail_ubdiag_packaging \ + "required tool is unavailable: ${required_tool}" + return 1 + fi + done + + case "${MOONCAKE_UBDIAG_LAYER}" in + mock|vendored) + ;; + *) + fail_ubdiag_packaging \ + "unsupported layer '${MOONCAKE_UBDIAG_LAYER:-unset}'" + return 1 + ;; + esac + + if [[ ! "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" =~ ^[0-9a-fA-F]{40}$ ]]; then + fail_ubdiag_packaging \ + "expected commit is not a full SHA: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" + return 1 + fi + if [ "${MOONCAKE_UBDIAG_EXPECTED_COMMIT,,}" != \ + "${MOONCAKE_UBDIAG_RESOLVED_COMMIT,,}" ]; then + fail_ubdiag_packaging \ + "configured commit ${MOONCAKE_UBDIAG_RESOLVED_COMMIT} does not match expected ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" + return 1 + fi + + source_dir="$(readlink -f "${MOONCAKE_UBDIAG_SOURCE_DIR}" 2>/dev/null || true)" + if [ -z "${source_dir}" ] || [ ! -f "${source_dir}/CMakeLists.txt" ]; then + fail_ubdiag_packaging \ + "verified source directory is unavailable: ${MOONCAKE_UBDIAG_SOURCE_DIR}" + return 1 + fi + + current_commit="$( + git -C "${source_dir}" rev-parse --verify HEAD 2>/dev/null || true + )" + if [ "${current_commit,,}" != "${MOONCAKE_UBDIAG_EXPECTED_COMMIT,,}" ]; then + fail_ubdiag_packaging \ + "source changed after CMake configure: expected ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}, found ${current_commit}" + return 1 + fi + dirty="$(git -C "${source_dir}" status --porcelain --untracked-files=all)" + if [ -n "${dirty}" ]; then + fail_ubdiag_packaging \ + "source worktree changed after CMake configure: ${source_dir}" + printf '%s\n' "${dirty}" >&2 + return 1 + fi + + MOONCAKE_UBDIAG_SOURCE_DIR="${source_dir}" + MOONCAKE_UBDIAG_RESOLVED_COMMIT="${current_commit,,}" +} + # Function to build RPM for a specific platform build_rpm_for_platform() { local PLATFORM=$1 local LIB_DIR="lib64" + local UBDIAG_RPM_FILES="" + local MOONCAKE_UBDIAG_LAYER="" + local MOONCAKE_UBDIAG_GIT_REPOSITORY="" + local MOONCAKE_UBDIAG_GIT_TAG="" + local MOONCAKE_UBDIAG_EXPECTED_COMMIT="" + local MOONCAKE_UBDIAG_RESOLVED_COMMIT="" + local MOONCAKE_UBDIAG_SOURCE_DIR="" echo "Building RPM for platform: ${PLATFORM}" @@ -68,7 +172,7 @@ build_rpm_for_platform() { mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM} # Create target directories in BUILDROOT - mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/{usr/{bin,${LIB_DIR},include},etc/mooncake} + mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/{usr/{bin,${LIB_DIR},include,share/doc/mooncake},etc/{mooncake,ubdiag}} # ------------------------------------------------------------------------- # Copy executables @@ -82,6 +186,11 @@ build_rpm_for_platform() { PLATFORM_BUILD_DIR="${BUILD_DIR}-${PLATFORM}" echo "Cross-compilation detected, looking in ${PLATFORM_BUILD_DIR}" fi + + local UBDIAG_RPM_MANIFEST="${PLATFORM_BUILD_DIR}/mooncake_ubdiag_rpm.env" + echo "Reading verified UbDiag RPM manifest: ${UBDIAG_RPM_MANIFEST}" + load_ubdiag_rpm_manifest "${UBDIAG_RPM_MANIFEST}" + verify_ubdiag_source_provenance # mooncake_master if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master ]; then @@ -170,6 +279,99 @@ build_rpm_for_platform() { else echo "Warning: store.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi + + # ------------------------------------------------------------------------- + # Copy the verified UbDiag runtime selected by Mooncake + # ------------------------------------------------------------------------- + local BUILDROOT="rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}" + if [ "${MOONCAKE_UBDIAG_LAYER}" = "vendored" ]; then + local ubdiag_binary_dir + local ubdiag_cli + local ubdiag_library_dir + local ubdiag_config + local ubdiag_library_real + local staged_library_real + local ubdiag_cli_sha256="" + local ubdiag_library_sha256="" + + ubdiag_binary_dir="$( + readlink -f "${PLATFORM_BUILD_DIR}/_deps/ubdiag-build" 2>/dev/null || + true + )" + ubdiag_cli="${ubdiag_binary_dir}/src/cli/ubdiag" + ubdiag_library_dir="${ubdiag_binary_dir}/src/sdk" + ubdiag_config="${MOONCAKE_UBDIAG_SOURCE_DIR}/config/ubdiag.conf.example" + + if [ -z "${ubdiag_binary_dir}" ] || + [ "$(tr -d '[:space:]' < "${ubdiag_binary_dir}/mooncake-source-commit.txt" 2>/dev/null || true)" != + "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" ]; then + fail_ubdiag_packaging \ + "current _deps/ubdiag-build has no matching source-commit marker" + return 1 + fi + if [ ! -x "${ubdiag_cli}" ] || + [ ! -f "${ubdiag_config}" ] || + ! compgen -G "${ubdiag_library_dir}/libubdiag.so*" >/dev/null || + ! readelf -d "${ubdiag_cli}" 2>/dev/null | + grep -q 'Shared library:.*libubdiag\.so'; then + fail_ubdiag_packaging \ + "Mooncake-built CLI, library, or config is missing/inconsistent" + return 1 + fi + ubdiag_library_real="$(readlink -f "${ubdiag_library_dir}/libubdiag.so")" + case "${ubdiag_library_real}" in + "${ubdiag_library_dir}"/*) + ;; + *) + fail_ubdiag_packaging "libubdiag.so escapes its build directory" + return 1 + ;; + esac + + cp "${ubdiag_cli}" "${BUILDROOT}/usr/bin/ubdiag" + chmod 755 "${BUILDROOT}/usr/bin/ubdiag" + cp -a "${ubdiag_library_dir}"/libubdiag.so* \ + "${BUILDROOT}/usr/${LIB_DIR}/" + cp "${ubdiag_config}" "${BUILDROOT}/etc/ubdiag/ubdiag.conf" + + cmp -s "${ubdiag_cli}" "${BUILDROOT}/usr/bin/ubdiag" || + { + fail_ubdiag_packaging "staged CLI differs from build output" + return 1 + } + staged_library_real="$( + readlink -f "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so" + )" + cmp -s "${ubdiag_library_real}" "${staged_library_real}" || + { + fail_ubdiag_packaging "staged library differs from build output" + return 1 + } + ubdiag_cli_sha256="$(sha256sum "${ubdiag_cli}" | awk '{print $1}')" + ubdiag_library_sha256="$(sha256sum "${ubdiag_library_real}" | awk '{print $1}')" + cat > "${BUILDROOT}/usr/share/doc/mooncake/ubdiag-provenance.txt" << EOF +layer=vendored +repository=${MOONCAKE_UBDIAG_GIT_REPOSITORY} +tag=${MOONCAKE_UBDIAG_GIT_TAG} +commit=${MOONCAKE_UBDIAG_RESOLVED_COMMIT} +cli_sha256=${ubdiag_cli_sha256} +library_file=$(basename "${ubdiag_library_real}") +library_sha256=${ubdiag_library_sha256} +EOF + UBDIAG_RPM_FILES=" +/usr/bin/ubdiag +/usr/${LIB_DIR}/libubdiag.so* +%config(noreplace) /etc/ubdiag/ubdiag.conf +/usr/share/doc/mooncake/ubdiag-provenance.txt" + echo "UbDiag RPM source verified: ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" + else + if compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" >/dev/null || + [ -e "${BUILDROOT}/usr/bin/ubdiag" ]; then + fail_ubdiag_packaging \ + "mock layer must not stage any UbDiag CLI or shared library" + return 1 + fi + fi # ------------------------------------------------------------------------- # Copy header files (only core headers for real_client and dummy_client) @@ -274,6 +476,32 @@ build_rpm_for_platform() { if [ -f mooncake-store/conf/master.json ]; then cp mooncake-store/conf/master.json rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi + + local staged_elf="" + local staged_ubdiag_dependency_count=0 + while IFS= read -r -d '' staged_elf; do + case "${staged_elf}" in + */usr/bin/ubdiag|*/usr/${LIB_DIR}/libubdiag.so*) + continue + ;; + esac + if readelf -d "${staged_elf}" 2>/dev/null | + grep -q 'Shared library:.*libubdiag\.so'; then + staged_ubdiag_dependency_count=$((staged_ubdiag_dependency_count + 1)) + fi + done < <(find "${BUILDROOT}" -type f -print0) + if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ] && + [ "${staged_ubdiag_dependency_count}" -ne 0 ]; then + fail_ubdiag_packaging \ + "mock RPM contains ${staged_ubdiag_dependency_count} ELF file(s) linked to libubdiag" + return 1 + fi + if [ "${MOONCAKE_UBDIAG_LAYER}" = "vendored" ] && + [ "${staged_ubdiag_dependency_count}" -eq 0 ]; then + fail_ubdiag_packaging \ + "vendored RPM has no ELF consumer linked to the packaged libubdiag" + return 1 + fi # ------------------------------------------------------------------------- # Create RPM spec file @@ -324,6 +552,7 @@ ${PACKAGE_DESCRIPTION} /usr/${LIB_DIR}/libetcd_wrapper.so /usr/${LIB_DIR}/libmooncake_engine.so /usr/${LIB_DIR}/libmooncake_store_python.so +${UBDIAG_RPM_FILES} /usr/include/mooncake/*.h /usr/include/mooncake/*.hpp /etc/mooncake/master.yaml @@ -398,4 +627,4 @@ echo "Created RPM files:" ls -la ${OUTPUT_DIR}/*.rpm 2>/dev/null || echo "No RPM files created" # Cleanup -rm -rf rpmbuild/ \ No newline at end of file +rm -rf rpmbuild/ From a52a4050dcc00731fdbe701819680e2de5147a60 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Sat, 25 Jul 2026 19:34:02 +0800 Subject: [PATCH 08/18] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3UbDiag=20RPM?= =?UTF-8?q?=E6=9D=A5=E6=BA=90=E6=A0=A1=E9=AA=8C=E4=B8=8E=E5=8F=AF=E9=80=89?= =?UTF-8?q?=E4=BA=A7=E7=89=A9=E6=89=93=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build_rpm.sh | 47 ++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index 3b7d5f695d..196db86fc3 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -10,10 +10,17 @@ set -x # Get build directory from environment variable or argument BUILD_DIR="${BUILD_DIR:-${1:-build}}" -BUILD_DIR_ABS="$(pwd)/${BUILD_DIR}" +if [[ "${BUILD_DIR}" = /* ]]; then + BUILD_DIR_ABS="${BUILD_DIR}" +else + BUILD_DIR_ABS="$(pwd)/${BUILD_DIR}" +fi # Get output directory from environment variable or argument OUTPUT_DIR="${OUTPUT_DIR:-${2:-rpm-output}}" +if [[ "${OUTPUT_DIR}" != /* ]]; then + OUTPUT_DIR="$(pwd)/${OUTPUT_DIR}" +fi # Detect current host architecture HOST_ARCH=$(uname -m) @@ -180,10 +187,10 @@ build_rpm_for_platform() { echo "Copying executables..." # Determine build subdirectory based on platform - local PLATFORM_BUILD_DIR="${BUILD_DIR}" + local PLATFORM_BUILD_DIR="${BUILD_DIR_ABS}" if [ "${PLATFORM}" != "${HOST_ARCH}" ]; then # Cross-compilation path - PLATFORM_BUILD_DIR="${BUILD_DIR}-${PLATFORM}" + PLATFORM_BUILD_DIR="${BUILD_DIR_ABS}-${PLATFORM}" echo "Cross-compilation detected, looking in ${PLATFORM_BUILD_DIR}" fi @@ -291,6 +298,7 @@ build_rpm_for_platform() { local ubdiag_config local ubdiag_library_real local staged_library_real + local build_source_commit local ubdiag_cli_sha256="" local ubdiag_library_sha256="" @@ -301,10 +309,14 @@ build_rpm_for_platform() { ubdiag_cli="${ubdiag_binary_dir}/src/cli/ubdiag" ubdiag_library_dir="${ubdiag_binary_dir}/src/sdk" ubdiag_config="${MOONCAKE_UBDIAG_SOURCE_DIR}/config/ubdiag.conf.example" + build_source_commit="$( + tr -d '[:space:]' \ + < "${ubdiag_binary_dir}/mooncake-source-commit.txt" \ + 2>/dev/null || true + )" if [ -z "${ubdiag_binary_dir}" ] || - [ "$(tr -d '[:space:]' < "${ubdiag_binary_dir}/mooncake-source-commit.txt" 2>/dev/null || true)" != - "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" ]; then + [ "${build_source_commit}" != "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" ]; then fail_ubdiag_packaging \ "current _deps/ubdiag-build has no matching source-commit marker" return 1 @@ -502,6 +514,21 @@ EOF "vendored RPM has no ELF consumer linked to the packaged libubdiag" return 1 fi + + local OPTIONAL_RPM_FILES="" + local optional_rpm_file="" + for optional_rpm_file in \ + /usr/bin/transfer_engine_bench \ + /usr/${LIB_DIR}/libmooncake_store.so \ + /usr/${LIB_DIR}/libtransfer_engine.so \ + /usr/${LIB_DIR}/libmooncake_common.so \ + /usr/${LIB_DIR}/libetcd_wrapper.so \ + /usr/${LIB_DIR}/libmooncake_engine.so \ + /usr/${LIB_DIR}/libmooncake_store_python.so; do + if [ -e "${BUILDROOT}${optional_rpm_file}" ]; then + OPTIONAL_RPM_FILES+="${optional_rpm_file}"$'\n' + fi + done # ------------------------------------------------------------------------- # Create RPM spec file @@ -544,14 +571,8 @@ ${PACKAGE_DESCRIPTION} /usr/bin/mooncake_master /usr/bin/mooncake_client /usr/bin/stress_cluster_bench -/usr/bin/transfer_engine_bench -/usr/${LIB_DIR}/libmooncake_store.so -/usr/${LIB_DIR}/libtransfer_engine.so -/usr/${LIB_DIR}/libmooncake_common.so /usr/${LIB_DIR}/libasio.so -/usr/${LIB_DIR}/libetcd_wrapper.so -/usr/${LIB_DIR}/libmooncake_engine.so -/usr/${LIB_DIR}/libmooncake_store_python.so +${OPTIONAL_RPM_FILES} ${UBDIAG_RPM_FILES} /usr/include/mooncake/*.h /usr/include/mooncake/*.hpp @@ -586,7 +607,7 @@ EOF # Build the RPM rpmbuild -bb \ --define "_topdir $(pwd)/rpmbuild" \ - --define "_rpmdir $(pwd)/${OUTPUT_DIR}" \ + --define "_rpmdir ${OUTPUT_DIR}" \ rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec # Move RPM to platform-specific directory From 05349574c46cad721cb6a205ecaf9b4e3d6d984e Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Mon, 27 Jul 2026 22:30:59 +0800 Subject: [PATCH 09/18] =?UTF-8?q?fix:=20=E6=9B=B4=E6=96=B0UbDiag=E7=B2=BE?= =?UTF-8?q?=E7=A1=AE=E7=89=88=E6=9C=AC=E5=B9=B6=E5=8C=85=E5=90=AB=E8=81=9A?= =?UTF-8?q?=E5=90=88=E5=99=A8=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 11 ++++++----- mooncake-common/FindUbDiag.cmake | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md index a18036756f..9fe49b4daa 100644 --- a/docs/ubdiag_integration_guide.md +++ b/docs/ubdiag_integration_guide.md @@ -32,10 +32,10 @@ cmake --build build -j CMake 配置阶段应输出(末尾同时打印已验证提交): ```text -UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified 705c6c37da45df2be4bc64c134dca0b7f30b2113 +UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f ``` -该模式使用 UbDiag `v0.5.1` 的同一份公共头文件,并通过 +该模式使用 UbDiag `0.6.0` 的同一份公共头文件,并通过 `UBDIAG_DISABLE` 将 PerfPoint 编译为空函数。Mooncake 无需启动 UbDiag, 也不需要安装 CLI 或动态库。可使用以下命令确认目标程序未链接 UbDiag: @@ -57,7 +57,7 @@ cmake --build build-ubdiag -j CMake 配置阶段应输出(末尾同时打印已验证提交): ```text -UbDiag: FetchContent 编译 v0.5.1(库+CLI), verified 705c6c37da45df2be4bc64c134dca0b7f30b2113 +UbDiag: FetchContent 编译 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f(库+CLI), verified 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f ``` 默认构建目录下的关键产物为: @@ -121,7 +121,8 @@ mkdir -p ./ubdiag-results UbDiag 洁净工作树,并通过 `MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: ```bash -git clone --branch v0.5.1 https://github.com/LinQuickDev/ubdiag.git /opt/src/ubdiag +git clone https://github.com/LinQuickDev/ubdiag.git /opt/src/ubdiag +git -C /opt/src/ubdiag checkout 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f cmake -S . -B build-ubdiag \ -DMOONCAKE_ENABLE_UBDIAG=ON \ -DMOONCAKE_UBDIAG_SOURCE_DIR=/opt/src/ubdiag @@ -139,7 +140,7 @@ git -C /opt/src/ubdiag rev-parse HEAD git -C /opt/src/ubdiag status --porcelain --untracked-files=all ``` -提交必须为 `705c6c37da45df2be4bc64c134dca0b7f30b2113`,工作树必须无修改和 +提交必须为 `8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f`,工作树必须无修改和 未跟踪文件。升级 UbDiag 版本时,必须同时更新 `MOONCAKE_UBDIAG_GIT_TAG` 和完整的 `MOONCAKE_UBDIAG_EXPECTED_COMMIT`,不能只更换标签。 diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 25fa8860f4..5cc5aec5ae 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -31,10 +31,10 @@ set(MOONCAKE_UBDIAG_GIT_REPOSITORY "https://github.com/LinQuickDev/ubdiag.git" CACHE STRING "ubdiag Git repository") set(MOONCAKE_UBDIAG_GIT_TAG - "v0.5.1" + "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" CACHE STRING "ubdiag 版本(tag/branch/commit)") set(MOONCAKE_UBDIAG_EXPECTED_COMMIT - "705c6c37da45df2be4bc64c134dca0b7f30b2113" + "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" CACHE STRING "Mooncake 允许使用的 ubdiag 精确提交 SHA") set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") From 039279418fefe1d138017975dac5122fbb2ed8dc Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Mon, 27 Jul 2026 23:06:29 +0800 Subject: [PATCH 10/18] =?UTF-8?q?fix:=20=E6=B8=85=E9=99=A4RPM=E5=86=85UbDi?= =?UTF-8?q?ag=E6=9E=84=E5=BB=BA=E8=B7=AF=E5=BE=84RPATH?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmake/RemoveRpath.cmake | 9 +++++++++ scripts/build_rpm.sh | 29 +++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 cmake/RemoveRpath.cmake diff --git a/cmake/RemoveRpath.cmake b/cmake/RemoveRpath.cmake new file mode 100644 index 0000000000..04f82c8d95 --- /dev/null +++ b/cmake/RemoveRpath.cmake @@ -0,0 +1,9 @@ +if(NOT DEFINED INPUT_FILE OR INPUT_FILE STREQUAL "") + message(FATAL_ERROR "INPUT_FILE is required") +endif() + +if(NOT EXISTS "${INPUT_FILE}") + message(FATAL_ERROR "ELF file does not exist: ${INPUT_FILE}") +endif() + +file(RPATH_REMOVE FILE "${INPUT_FILE}") diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index 196db86fc3..9604d2c699 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -8,6 +8,9 @@ set -e # Exit immediately if a command exits with a non-zero status set -x +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +MOONCAKE_SOURCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" + # Get build directory from environment variable or argument BUILD_DIR="${BUILD_DIR:-${1:-build}}" if [[ "${BUILD_DIR}" = /* ]]; then @@ -58,6 +61,22 @@ fail_ubdiag_packaging() { return 1 } +remove_staged_rpath() { + local staged_elf="$1" + + if readelf -d "${staged_elf}" 2>/dev/null | + grep -Eq '\((RPATH|RUNPATH)\)'; then + cmake -DINPUT_FILE="${staged_elf}" \ + -P "${MOONCAKE_SOURCE_DIR}/cmake/RemoveRpath.cmake" + fi + if readelf -d "${staged_elf}" 2>/dev/null | + grep -Eq '\((RPATH|RUNPATH)\)'; then + fail_ubdiag_packaging \ + "staged ELF still contains RPATH/RUNPATH: ${staged_elf}" + return 1 + fi +} + load_ubdiag_rpm_manifest() { local manifest=$1 local key="" @@ -359,8 +378,13 @@ build_rpm_for_platform() { fail_ubdiag_packaging "staged library differs from build output" return 1 } - ubdiag_cli_sha256="$(sha256sum "${ubdiag_cli}" | awk '{print $1}')" - ubdiag_library_sha256="$(sha256sum "${ubdiag_library_real}" | awk '{print $1}')" + remove_staged_rpath "${BUILDROOT}/usr/bin/ubdiag" + ubdiag_cli_sha256="$( + sha256sum "${BUILDROOT}/usr/bin/ubdiag" | awk '{print $1}' + )" + ubdiag_library_sha256="$( + sha256sum "${staged_library_real}" | awk '{print $1}' + )" cat > "${BUILDROOT}/usr/share/doc/mooncake/ubdiag-provenance.txt" << EOF layer=vendored repository=${MOONCAKE_UBDIAG_GIT_REPOSITORY} @@ -499,6 +523,7 @@ EOF esac if readelf -d "${staged_elf}" 2>/dev/null | grep -q 'Shared library:.*libubdiag\.so'; then + remove_staged_rpath "${staged_elf}" staged_ubdiag_dependency_count=$((staged_ubdiag_dependency_count + 1)) fi done < <(find "${BUILDROOT}" -type f -print0) From c09ee50e14ea37602081fc9b9d73e8bf72388a4d Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Mon, 27 Jul 2026 23:23:48 +0800 Subject: [PATCH 11/18] =?UTF-8?q?docs:=20=E5=AE=8C=E5=96=84UbDiag=E4=B8=A4?= =?UTF-8?q?=E5=B1=82=E5=88=86=E5=8F=91=E7=94=A8=E6=88=B7=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 93 ++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md index 9fe49b4daa..84c2a2ed83 100644 --- a/docs/ubdiag_integration_guide.md +++ b/docs/ubdiag_integration_guide.md @@ -1,8 +1,9 @@ -# Mooncake UbDiag 两层分发使用指南 +# Mooncake UbDiag 两层分发与单 RPM 使用指南 Mooncake 通过统一的 CMake 接口提供 UbDiag 两层分发能力。默认模式将 PerfPoint 编译为空实现;启用模式从同一份 UbDiag 源码同步构建 SDK 动态库 -与命令行工具,供 Mooncake 性能采集与分析使用。 +与命令行工具,并将 Mooncake、CLI、动态库和配置打入一个 RPM,供性能 +采集与分析使用。 ## 1. 模式选择 @@ -13,6 +14,10 @@ PerfPoint 编译为空实现;启用模式从同一份 UbDiag 源码同步构 模式由编译期选项决定,不能在运行时切换。建议为两种模式使用独立构建目录。 +> [!NOTE] +> L1 RPM 安装后可以不执行 `ubdiag start`,此时不会进行共享内存采集; +> 但该二进制仍链接真实 `libubdiag`,不能称为 Layer 0 编译期禁用模式。 + ## 2. 默认禁用模式 未指定 `MOONCAKE_ENABLE_UBDIAG` 时,Mooncake 默认使用 Layer 0: @@ -78,23 +83,57 @@ export LD_LIBRARY_PATH="$UBDIAG_BUILD/src/sdk${LD_LIBRARY_PATH:+:$LD_LIBRARY_PAT 不得混用系统中其他版本的 `ubdiag` CLI 或 `libubdiag.so`。CLI 与 SDK 必须来自同一源码版本和同一次构建,以保证共享内存布局及功能开关一致。 -## 4. 采集与分析 +## 4. 安装 L1 单 RPM + +完成 L1 构建后,可直接生成一个包含 Mooncake 和 UbDiag 的 RPM: + +```bash +bash scripts/build_rpm.sh build-ubdiag rpm-output "$(uname -m)" +sudo rpm -Uvh rpm-output/mooncake-*.rpm +``` + +安装后的关键文件如下: + +```text +/usr/bin/mooncake_master +/usr/bin/mooncake_client +/usr/bin/ubdiag +/usr/lib64/libubdiag.so +/usr/lib64/libubdiag.so.0 +/usr/lib64/libubdiag.so.0.6.0 +/etc/ubdiag/ubdiag.conf +/usr/share/doc/mooncake/ubdiag-provenance.txt +``` + +不需要再安装独立 UbDiag CLI 包。可以直接确认版本和来源: + +```bash +/usr/bin/ubdiag --version +cat /usr/share/doc/mooncake/ubdiag-provenance.txt +ldd /usr/bin/mooncake_master | grep libubdiag +``` + +版本输出应包含 `ubdiag version 0.6.0` 和构建身份 `8df2c284`; +provenance 中的完整提交应为 +`8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f`。 + +## 5. 采集与分析 启动 UbDiag 共享内存,并启用 PerfLog: ```bash -"$UBDIAG_CLI" start --perflog -"$UBDIAG_CLI" status +ubdiag start --perflog +ubdiag status ``` 随后按 Mooncake 原有方式启动服务和业务负载。负载运行期间可执行: ```bash -"$UBDIAG_CLI" show -"$UBDIAG_CLI" show --detail -"$UBDIAG_CLI" show --perflog -"$UBDIAG_CLI" watch --interval 1000 -"$UBDIAG_CLI" history -n 5 +ubdiag show +ubdiag show --detail +ubdiag show --perflog +ubdiag watch --interval 1000 +ubdiag history -n 5 ``` 其中 `show` 输出聚合统计及 P99/P999/P9999,`show --detail` 输出按核数据, @@ -104,18 +143,23 @@ export LD_LIBRARY_PATH="$UBDIAG_BUILD/src/sdk${LD_LIBRARY_PATH:+:$LD_LIBRARY_PAT ```bash mkdir -p ./ubdiag-results -"$UBDIAG_CLI" show --csv ./ubdiag-results -"$UBDIAG_CLI" show --detail --csv ./ubdiag-results -"$UBDIAG_CLI" history --csv ./ubdiag-results +ubdiag show --csv ./ubdiag-results +ubdiag show --detail --csv ./ubdiag-results +ubdiag show --perflog --csv ./ubdiag-results +ubdiag history --csv ./ubdiag-results ``` 分析结束后销毁共享内存: ```bash -"$UBDIAG_CLI" stop +ubdiag stop ``` -## 5. 离线源码 +源码构建但尚未安装 RPM 时,将以上 `ubdiag` 替换为 +`build-ubdiag/_deps/ubdiag-build/src/cli/ubdiag`,并确保 +`LD_LIBRARY_PATH` 首项为同一构建目录的 `src/sdk`。 + +## 6. 离线源码 构建环境无法访问 GitHub 时,预先准备精确版本且保留 `.git` 元数据的 UbDiag 洁净工作树,并通过 `MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: @@ -145,7 +189,7 @@ git -C /opt/src/ubdiag status --porcelain --untracked-files=all `MOONCAKE_UBDIAG_GIT_TAG` 和完整的 `MOONCAKE_UBDIAG_EXPECTED_COMMIT`,不能只更换标签。 -## 6. RPM 打包与来源保证 +## 7. RPM 打包与来源保证 CMake 每次配置都会在当前构建目录生成 `mooncake_ubdiag_rpm.env`。该清单记录当前层、UbDiag 源码目录、期望提交 @@ -171,6 +215,10 @@ CMake 清单指定的 FetchContent 源码和构建产物,并在出包前再次 `_deps/ubdiag-build` 内。 5. CLI 确实依赖同一构建目录生成的 `libubdiag.so`。 6. 复制到 RPM BUILDROOT 后逐文件比较,防止打包阶段替换产物。 +7. 删除 CLI 和 Mooncake 消费者中的构建目录 `RPATH/RUNPATH`,避免安装后 + 继续引用出包机器的 `_deps` 路径。 +8. 对完成 RPATH 清理后的最终 CLI 和真实动态库计算 SHA256,并写入 + provenance。 Layer 0 的 RPM 不包含 UbDiag CLI 或动态库,并检查待打包 ELF 不依赖 `libubdiag.so`。Layer 1 的 RPM 包含同一次构建生成的 CLI、动态库和配置, @@ -189,7 +237,7 @@ bash scripts/build_rpm.sh build rpm-output "$(uname -m)" 重新配置会刷新来源清单;打包脚本只按最新清单处理。反向切回 Layer 0 时, 即使构建目录残留旧的 `libubdiag.so`,也不会将其打入 RPM。 -## 7. 验收标准 +## 8. 验收标准 | 检查项 | Layer 0 | Layer 1 | |--------|---------|---------| @@ -202,3 +250,14 @@ bash scripts/build_rpm.sh build rpm-output "$(uname -m)" 若启用模式下 CLI 无数据,应依次确认共享内存已启动、Mooncake 使用的是 `build-ubdiag` 产物、运行时加载的是同目录 `libubdiag.so`,以及业务负载已 实际经过 Mooncake PerfPoint 打点路径。 + +## 9. 常见问题 + +| 现象 | 原因与处理 | +|------|------------| +| L1 RPM 未执行 `ubdiag start` | Mooncake 可以运行,但不产生 UbDiag 采集数据;这不是 Layer 0 Mock | +| `ubdiag show` 表格为空 | 先确认 `status` 为 running,再运行实际 Mooncake 负载 | +| CLI 与 Mooncake 数据布局不一致 | 检查 CLI、动态库和 provenance 是否来自同一 RPM | +| 配置时报提交不一致 | 删除陈旧 `_deps/ubdiag-src`,或提供匹配完整 SHA 的洁净本地源码 | +| 打包时报 binary marker 不一致 | 重新执行 CMake 配置和构建,不要复用其他版本的 UbDiag 子构建目录 | +| RPM 中出现构建目录 RPATH | 使用当前打包脚本重新出包;最终 ELF 不应包含 `_deps/ubdiag-build` | From 05927d6d0ab4cd5373e8c44d4f2e56f167d731b9 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 28 Jul 2026 11:32:02 +0800 Subject: [PATCH 12/18] =?UTF-8?q?fix:=20=E6=94=B6=E7=B4=A7UbDiag=E4=B8=A4?= =?UTF-8?q?=E5=B1=82=E9=85=8D=E7=BD=AE=E5=BC=82=E5=B8=B8=E9=97=A8=E7=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 8 ++++++-- mooncake-p2p-store/build.sh | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 5cc5aec5ae..7da1d098c9 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -112,8 +112,12 @@ function(_mooncake_write_ubdiag_rpm_manifest layer) endfunction() set(ubdiag_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-build") -if(MOONCAKE_UBDIAG_SOURCE_DIR AND - EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") +if(MOONCAKE_UBDIAG_SOURCE_DIR) + if(NOT EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + message(FATAL_ERROR + "MOONCAKE_UBDIAG_SOURCE_DIR does not contain CMakeLists.txt: " + "${MOONCAKE_UBDIAG_SOURCE_DIR}") + endif() set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") else() FetchContent_Populate(ubdiag diff --git a/mooncake-p2p-store/build.sh b/mooncake-p2p-store/build.sh index 9ba1a6151c..9363c3c639 100644 --- a/mooncake-p2p-store/build.sh +++ b/mooncake-p2p-store/build.sh @@ -48,7 +48,8 @@ case "$UBDIAG_LAYER" in echo "P2P Store: ubdiag DISABLE 模式,跳过 -lubdiag" ;; *) - echo "P2P Store: 未知 ubdiag layer: $UBDIAG_LAYER,跳过 -lubdiag" + echo "P2P Store: 未知 ubdiag layer: $UBDIAG_LAYER" >&2 + exit 1 ;; esac From 8a2304aecf85693a4ef18dd3f383f6159b6f6951 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 28 Jul 2026 11:45:07 +0800 Subject: [PATCH 13/18] =?UTF-8?q?style:=20=E6=B8=85=E7=90=86RPM=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E8=A1=8C=E5=B0=BE=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build_rpm.sh | 90 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index 9604d2c699..55a45374de 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -180,9 +180,9 @@ build_rpm_for_platform() { local MOONCAKE_UBDIAG_EXPECTED_COMMIT="" local MOONCAKE_UBDIAG_RESOLVED_COMMIT="" local MOONCAKE_UBDIAG_SOURCE_DIR="" - + echo "Building RPM for platform: ${PLATFORM}" - + # Determine lib directory based on platform if [ "${PLATFORM}" = "aarch64" ]; then LIB_DIR="lib64" # ARM64 also uses lib64 on most distros @@ -192,19 +192,19 @@ build_rpm_for_platform() { echo "Error: Unsupported platform ${PLATFORM}" return 1 fi - + # Create RPM build directory structure for this platform mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM} - + # Create target directories in BUILDROOT mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/{usr/{bin,${LIB_DIR},include,share/doc/mooncake},etc/{mooncake,ubdiag}} - + # ------------------------------------------------------------------------- # Copy executables # ------------------------------------------------------------------------- echo "Copying executables..." - + # Determine build subdirectory based on platform local PLATFORM_BUILD_DIR="${BUILD_DIR_ABS}" if [ "${PLATFORM}" != "${HOST_ARCH}" ]; then @@ -217,7 +217,7 @@ build_rpm_for_platform() { echo "Reading verified UbDiag RPM manifest: ${UBDIAG_RPM_MANIFEST}" load_ubdiag_rpm_manifest "${UBDIAG_RPM_MANIFEST}" verify_ubdiag_source_provenance - + # mooncake_master if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -225,7 +225,7 @@ build_rpm_for_platform() { else echo "Warning: mooncake_master not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # mooncake_client if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_client ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_client rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -233,7 +233,7 @@ build_rpm_for_platform() { else echo "Warning: mooncake_client not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # stress_cluster_bench if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/benchmarks/stress_cluster_bench ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/benchmarks/stress_cluster_bench rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -241,7 +241,7 @@ build_rpm_for_platform() { else echo "Warning: stress_cluster_bench not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # transfer_engine_bench if [ -f ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/example/transfer_engine_bench ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/example/transfer_engine_bench rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -249,40 +249,40 @@ build_rpm_for_platform() { else echo "Warning: transfer_engine_bench not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # ------------------------------------------------------------------------- # Copy libraries # ------------------------------------------------------------------------- echo "Copying shared libraries..." - + # libmooncake_store.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/libmooncake_store.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/libmooncake_store.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libmooncake_store.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libtransfer_engine.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/src/libtransfer_engine.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/src/libtransfer_engine.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libtransfer_engine.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libasio.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/libasio.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/libasio.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libasio.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libetcd_wrapper.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/etcd/libetcd_wrapper.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/etcd/libetcd_wrapper.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libetcd_wrapper.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libmooncake_common.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/libmooncake_common.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/libmooncake_common.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ @@ -291,14 +291,14 @@ build_rpm_for_platform() { else echo "Warning: libmooncake_common.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # engine.so (Python binding) if compgen -G "${PLATFORM_BUILD_DIR}/mooncake-integration/engine.*.so" >/dev/null; then cp ${PLATFORM_BUILD_DIR}/mooncake-integration/engine.*.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libmooncake_engine.so else echo "Warning: engine.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # store.so (Python binding) if compgen -G "${PLATFORM_BUILD_DIR}/mooncake-integration/store.*.so" >/dev/null; then cp ${PLATFORM_BUILD_DIR}/mooncake-integration/store.*.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libmooncake_store_python.so @@ -408,15 +408,15 @@ EOF return 1 fi fi - + # ------------------------------------------------------------------------- # Copy header files (only core headers for real_client and dummy_client) # ------------------------------------------------------------------------- echo "Copying core header files for real_client and dummy_client..." - + # Create include directories mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/include/mooncake - + # Core client headers (real_client and dummy_client dependencies) # These are the essential headers needed for client-side development CORE_HEADERS=( @@ -424,21 +424,21 @@ EOF "real_client.h" "dummy_client.h" "pyclient.h" - + # pyclient dependencies "client_service.h" "client_buffer.hpp" "mutex.h" "utils.h" "file_storage.h" - + # real_client dependencies "rpc_types.h" - + # dummy_client dependencies "shm_helper.h" "client_metric.h" - + # Common types and utilities "types.h" "segment.h" @@ -454,11 +454,11 @@ EOF "metadata_store.h" "mmap_arena.h" "pinned_buffer_pool.h" - + # C API headers "store_c.h" ) - + # Copy core store headers for header in "${CORE_HEADERS[@]}"; do if [ -f mooncake-store/include/${header} ]; then @@ -467,7 +467,7 @@ EOF echo "Warning: Core header ${header} not found" fi done - + # Transfer engine core headers (needed by real_client) TRANSFER_ENGINE_HEADERS=( "transfer_engine_c.h" @@ -479,7 +479,7 @@ EOF "multi_transport.h" "topology.h" ) - + # Copy transfer engine headers for header in "${TRANSFER_ENGINE_HEADERS[@]}"; do if [ -f mooncake-transfer-engine/include/${header} ]; then @@ -488,7 +488,7 @@ EOF echo "Warning: Transfer engine header ${header} not found" fi done - + # Note: Excluding the following directories as they are not needed for basic client usage: # - cachelib_memory_allocator/ (memory allocator internals) # - engram/ (engram store specific) @@ -498,17 +498,17 @@ EOF # - serialize/ (serialization utilities) # - spdk/ (SPDK integration) # - utils/s3_helper.h, zstd_util.h (specific utilities) - + # ------------------------------------------------------------------------- # Copy configuration files # ------------------------------------------------------------------------- echo "Copying configuration files..." - + # Master configuration if [ -f mooncake-store/conf/master.yaml ]; then cp mooncake-store/conf/master.yaml rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi - + if [ -f mooncake-store/conf/master.json ]; then cp mooncake-store/conf/master.json rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi @@ -554,12 +554,12 @@ EOF OPTIONAL_RPM_FILES+="${optional_rpm_file}"$'\n' fi done - + # ------------------------------------------------------------------------- # Create RPM spec file # ------------------------------------------------------------------------- echo "Creating RPM spec file for ${PLATFORM}..." - + cat > rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec << EOF Name: ${PACKAGE_NAME} Version: ${PACKAGE_VERSION} @@ -614,30 +614,30 @@ ${UBDIAG_RPM_FILES} * $(date +"%a %b %d %Y") KVCache.AI - ${PACKAGE_VERSION}-${PACKAGE_RELEASE} - Initial RPM package for ${PLATFORM} EOF - + # ------------------------------------------------------------------------- # Build RPM package # ------------------------------------------------------------------------- echo "Building RPM package for ${PLATFORM}..." - + # Ensure rpmbuild is available if ! command -v rpmbuild &>/dev/null; then echo "Error: rpmbuild not found. Please install rpm-build package." exit 1 fi - + # Create platform-specific output directory mkdir -p ${OUTPUT_DIR}/${PLATFORM} - + # Build the RPM rpmbuild -bb \ --define "_topdir $(pwd)/rpmbuild" \ --define "_rpmdir ${OUTPUT_DIR}" \ rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec - + # Move RPM to platform-specific directory mv ${OUTPUT_DIR}/${PLATFORM}/*.rpm ${OUTPUT_DIR}/ 2>/dev/null || true - + # Cleanup BUILDROOT for next platform rm -rf rpmbuild/BUILDROOT/ } @@ -647,20 +647,20 @@ EOF # ----------------------------------------------------------------------------- if [ "${TARGET_PLATFORM}" = "all" ]; then echo "Building RPM packages for all supported platforms..." - + # Build for x86_64 build_rpm_for_platform "x86_64" - + # Build for aarch64 (if cross-compilation is available or running on ARM) if [ "${HOST_ARCH}" = "aarch64" ] || [ -d "${BUILD_DIR}-aarch64" ]; then build_rpm_for_platform "aarch64" else echo "Warning: Skipping aarch64 build - no cross-compilation build directory found" fi - + elif [ "${TARGET_PLATFORM}" = "x86_64" ] || [ "${TARGET_PLATFORM}" = "aarch64" ]; then build_rpm_for_platform "${TARGET_PLATFORM}" - + else echo "Error: Unsupported platform ${TARGET_PLATFORM}" echo "Supported platforms: x86_64, aarch64, all" From ba2c6439f6d343b36df826c6fde1959a9bceca26 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 28 Jul 2026 23:31:41 +0800 Subject: [PATCH 14/18] =?UTF-8?q?feat:=20=E6=94=B9=E4=B8=BA=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=B3=BB=E7=BB=9FUbDiag=E5=AE=8C=E6=88=90=E4=B8=A4?= =?UTF-8?q?=E5=B1=82=E5=88=86=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 584 ++++++++++++++++++++---------- mooncake-p2p-store/CMakeLists.txt | 18 +- mooncake-p2p-store/build.sh | 19 +- mooncake-store/src/CMakeLists.txt | 2 +- scripts/build_rpm.sh | 429 ++++++++++++---------- 5 files changed, 650 insertions(+), 402 deletions(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 7da1d098c9..078833071d 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -1,236 +1,442 @@ -# FindUbDiag.cmake v2 — 基于 UBDIAG_DISABLE 的两层集成 +# FindUbDiag.cmake - two-layer UbDiag integration for Mooncake # -# Layer 0 (默认): FetchContent 拉源码 + 定义 UBDIAG_DISABLE → constexpr 空函数 -# Layer 1 (可选): FetchContent 拉源码 + 编译 ubdiag 库 + CLI +# Layer 0 (default): Fetch the pinned UbDiag source, expose its public headers, +# and propagate UBDIAG_DISABLE. PerfPoint calls compile to constexpr no-op +# functions. # -# Usage: -# include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) -# target_link_libraries(your_target PRIVATE UbDiag::ubdiag_lib) +# Layer 1: Consume a separately installed system UbDiag package. The package +# must provide a shared SDK, the ubdiag CLI, percentile support, and PerfLog. # -# Options: -# -DMOONCAKE_ENABLE_UBDIAG=ON 编译真实 ubdiag (库 + CLI) -# -DMOONCAKE_ENABLE_UBDIAG=OFF (默认) 使用 UBDIAG_DISABLE 空函数 -# -DMOONCAKE_UBDIAG_GIT_TAG= 指定 ubdiag 版本 -# -DMOONCAKE_UBDIAG_EXPECTED_COMMIT=<40-char SHA> 指定允许的精确提交 -# -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag 离线模式指定本地源码 +# Usage: include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) +# target_link_libraries(your_target PRIVATE UbDiag::ubdiag_lib) +# +# Options: -DMOONCAKE_ENABLE_UBDIAG=OFF Layer 0 (default) +# -DMOONCAKE_ENABLE_UBDIAG=ON Layer 1 +# +# Layer 0 source selection: -DMOONCAKE_UBDIAG_GIT_TAG= +# -DMOONCAKE_UBDIAG_EXPECTED_COMMIT=<40-character SHA> +# -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag +# +# Layer 1 package selection: -DCMAKE_PREFIX_PATH=/path/to/ubdiag/prefix +# -DUbDiag_DIR=/path/to/lib64/cmake/UbDiag if(TARGET UbDiag::ubdiag_lib) get_property(_MOONCAKE_UBDIAG_TARGET_OWNER GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER) if(NOT _MOONCAKE_UBDIAG_TARGET_OWNER STREQUAL "${CMAKE_BINARY_DIR}") - message(FATAL_ERROR - "UbDiag::ubdiag_lib already exists but was not created by Mooncake's " - "FetchContent integration. Remove any find_package(UbDiag), system " - "UbDiag target, or injected parent-project target before configuring.") + message( + FATAL_ERROR + "UbDiag::ubdiag_lib already exists but was not resolved by Mooncake. " + "Remove the injected target and let FindUbDiag.cmake select the active " + "Mooncake UbDiag layer.") endif() return() endif() -option(MOONCAKE_ENABLE_UBDIAG "编译 ubdiag 真实库(否则用 UBDIAG_DISABLE 空函数)" OFF) -set(MOONCAKE_UBDIAG_GIT_REPOSITORY - "https://github.com/LinQuickDev/ubdiag.git" - CACHE STRING "ubdiag Git repository") -set(MOONCAKE_UBDIAG_GIT_TAG - "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" - CACHE STRING "ubdiag 版本(tag/branch/commit)") -set(MOONCAKE_UBDIAG_EXPECTED_COMMIT - "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" - CACHE STRING "Mooncake 允许使用的 ubdiag 精确提交 SHA") -set(MOONCAKE_UBDIAG_SOURCE_DIR "" CACHE PATH "本地 ubdiag 源码目录(离线用,为空则 FetchContent)") - -include(FetchContent) - -function(_mooncake_verify_ubdiag_source source_dir) - get_filename_component(_source_dir "${source_dir}" REALPATH) - string(TOLOWER "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" _expected_commit) - string(LENGTH "${_expected_commit}" _expected_commit_length) - if(NOT _expected_commit_length EQUAL 40 OR - NOT _expected_commit MATCHES "^[0-9a-f]+$") - message(FATAL_ERROR - "MOONCAKE_UBDIAG_EXPECTED_COMMIT must be a full 40-character Git SHA, " - "got: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}") - endif() - - find_program(_MOONCAKE_UBDIAG_GIT_EXECUTABLE NAMES git) - if(NOT _MOONCAKE_UBDIAG_GIT_EXECUTABLE OR - NOT EXISTS "${_source_dir}/CMakeLists.txt") - message(FATAL_ERROR - "UbDiag source is incomplete or git is unavailable: ${_source_dir}") - endif() - - execute_process( - COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" - rev-parse --verify HEAD - RESULT_VARIABLE _git_result - OUTPUT_VARIABLE _resolved_commit - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(TOLOWER "${_resolved_commit}" _resolved_commit) - if(NOT _git_result EQUAL 0 OR - NOT _resolved_commit STREQUAL _expected_commit) - message(FATAL_ERROR - "UbDiag source commit mismatch.\n" - " expected: ${_expected_commit}\n" - " resolved: ${_resolved_commit}\n" - " source: ${_source_dir}\n" - "Remove the stale _deps/ubdiag-src directory or select the matching " - "MOONCAKE_UBDIAG_EXPECTED_COMMIT.") - endif() - - execute_process( - COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" - status --porcelain --untracked-files=all - RESULT_VARIABLE _git_result - OUTPUT_VARIABLE _git_status - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT _git_result EQUAL 0 OR NOT _git_status STREQUAL "") - message(FATAL_ERROR - "UbDiag source worktree is not clean, so its HEAD SHA does not fully " - "describe the code that would be built:\n${_git_status}") - endif() - - set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "${_source_dir}" - CACHE PATH "Verified UbDiag source selected by Mooncake" FORCE) - set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "${_resolved_commit}" - CACHE STRING "Verified UbDiag source commit selected by Mooncake" FORCE) - set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "${_source_dir}" PARENT_SCOPE) - set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "${_resolved_commit}" PARENT_SCOPE) -endfunction() +option(MOONCAKE_ENABLE_UBDIAG + "Use a system-installed UbDiag shared library and CLI" OFF) -function(_mooncake_write_ubdiag_rpm_manifest layer) - set(_manifest "${CMAKE_BINARY_DIR}/mooncake_ubdiag_rpm.env") +function(_mooncake_write_ubdiag_manifest layer) + set(_manifest "${CMAKE_BINARY_DIR}/mooncake_ubdiag.env") file(WRITE "${_manifest}" "MOONCAKE_UBDIAG_LAYER=${layer}\n") - file(APPEND "${_manifest}" + file( + APPEND "${_manifest}" "MOONCAKE_UBDIAG_GIT_REPOSITORY=${MOONCAKE_UBDIAG_GIT_REPOSITORY}\n" "MOONCAKE_UBDIAG_GIT_TAG=${MOONCAKE_UBDIAG_GIT_TAG}\n" "MOONCAKE_UBDIAG_EXPECTED_COMMIT=${MOONCAKE_UBDIAG_EXPECTED_COMMIT}\n" "MOONCAKE_UBDIAG_RESOLVED_COMMIT=${MOONCAKE_UBDIAG_RESOLVED_COMMIT}\n" - "MOONCAKE_UBDIAG_SOURCE_DIR=${MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR}\n") - set(MOONCAKE_UBDIAG_RPM_MANIFEST "${_manifest}" - CACHE FILEPATH "Verified UbDiag RPM packaging manifest" FORCE) - set(MOONCAKE_UBDIAG_ACTIVE_LAYER "${layer}" - CACHE STRING "Active UbDiag integration layer: mock or vendored" FORCE) + "MOONCAKE_UBDIAG_SOURCE_DIR=${MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR}\n" + "MOONCAKE_UBDIAG_PACKAGE_VERSION=${UbDiag_VERSION}\n" + "MOONCAKE_UBDIAG_PACKAGE_DIR=${UbDiag_DIR}\n" + "MOONCAKE_UBDIAG_SYSTEM_PREFIX=${MOONCAKE_UBDIAG_SYSTEM_PREFIX}\n" + "MOONCAKE_UBDIAG_SYSTEM_LIBRARY=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}\n" + "MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}\n" + "MOONCAKE_UBDIAG_SYSTEM_CLI=${MOONCAKE_UBDIAG_SYSTEM_CLI}\n" + "MOONCAKE_UBDIAG_SYSTEM_CLI_RPM=${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}\n" + "MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH=${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}\n" + "MOONCAKE_UBDIAG_SYSTEM_CONFIG=${MOONCAKE_UBDIAG_SYSTEM_CONFIG}\n") + set(MOONCAKE_UBDIAG_MANIFEST + "${_manifest}" + CACHE FILEPATH "Resolved Mooncake UbDiag integration manifest" FORCE) + set(MOONCAKE_UBDIAG_ACTIVE_LAYER + "${layer}" + CACHE STRING "Active UbDiag integration layer: mock or system" FORCE) endfunction() -set(ubdiag_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-build") -if(MOONCAKE_UBDIAG_SOURCE_DIR) - if(NOT EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") - message(FATAL_ERROR - "MOONCAKE_UBDIAG_SOURCE_DIR does not contain CMakeLists.txt: " - "${MOONCAKE_UBDIAG_SOURCE_DIR}") +if(NOT MOONCAKE_ENABLE_UBDIAG) + set(MOONCAKE_UBDIAG_GIT_REPOSITORY + "https://github.com/LinQuickDev/ubdiag.git" + CACHE STRING "UbDiag Git repository used by Layer 0") + set(MOONCAKE_UBDIAG_GIT_TAG + "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" + CACHE STRING "UbDiag ref used by Layer 0") + set(MOONCAKE_UBDIAG_EXPECTED_COMMIT + "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" + CACHE STRING "Allowed full UbDiag commit SHA used by Layer 0") + set(MOONCAKE_UBDIAG_SOURCE_DIR + "" + CACHE PATH "Local UbDiag source for offline Layer 0 configuration") + + include(FetchContent) + + function(_mooncake_verify_ubdiag_source source_dir) + get_filename_component(_source_dir "${source_dir}" REALPATH) + string(TOLOWER "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" _expected_commit) + string(LENGTH "${_expected_commit}" _expected_commit_length) + if(NOT _expected_commit_length EQUAL 40 OR NOT _expected_commit MATCHES + "^[0-9a-f]+$") + message( + FATAL_ERROR + "MOONCAKE_UBDIAG_EXPECTED_COMMIT must be a full 40-character Git " + "SHA, got: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}") + endif() + + find_program(_MOONCAKE_UBDIAG_GIT_EXECUTABLE NAMES git) + if(NOT _MOONCAKE_UBDIAG_GIT_EXECUTABLE OR NOT EXISTS + "${_source_dir}/CMakeLists.txt") + message( + FATAL_ERROR + "UbDiag source is incomplete or git is unavailable: ${_source_dir}") + endif() + + execute_process( + COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" rev-parse + --verify HEAD + RESULT_VARIABLE _git_result + OUTPUT_VARIABLE _resolved_commit + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(TOLOWER "${_resolved_commit}" _resolved_commit) + if(NOT _git_result EQUAL 0 OR NOT _resolved_commit STREQUAL + _expected_commit) + message( + FATAL_ERROR + "UbDiag source commit mismatch.\n" + " expected: ${_expected_commit}\n" + " resolved: ${_resolved_commit}\n" + " source: ${_source_dir}\n" + "Remove the stale _deps/ubdiag-src directory or select the matching " + "MOONCAKE_UBDIAG_EXPECTED_COMMIT.") + endif() + + execute_process( + COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" status + --porcelain --untracked-files=all + RESULT_VARIABLE _git_result + OUTPUT_VARIABLE _git_status + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT _git_result EQUAL 0 OR NOT _git_status STREQUAL "") + message( + FATAL_ERROR + "UbDiag source worktree is not clean, so its HEAD SHA does not fully " + "describe the headers that would be used:\n${_git_status}") + endif() + + set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR + "${_source_dir}" + CACHE PATH "Verified UbDiag source selected by Mooncake" FORCE) + set(MOONCAKE_UBDIAG_RESOLVED_COMMIT + "${_resolved_commit}" + CACHE STRING "Verified UbDiag source commit selected by Mooncake" FORCE) + set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR + "${_source_dir}" + PARENT_SCOPE) + set(MOONCAKE_UBDIAG_RESOLVED_COMMIT + "${_resolved_commit}" + PARENT_SCOPE) + endfunction() + + if(MOONCAKE_UBDIAG_SOURCE_DIR) + if(NOT EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") + message( + FATAL_ERROR + "MOONCAKE_UBDIAG_SOURCE_DIR does not contain CMakeLists.txt: " + "${MOONCAKE_UBDIAG_SOURCE_DIR}") + endif() + set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") + else() + FetchContent_Populate( + ubdiag + GIT_REPOSITORY "${MOONCAKE_UBDIAG_GIT_REPOSITORY}" + GIT_TAG "${MOONCAKE_UBDIAG_GIT_TAG}" + SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" + SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") endif() - set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") -else() - FetchContent_Populate(ubdiag - GIT_REPOSITORY ${MOONCAKE_UBDIAG_GIT_REPOSITORY} - GIT_TAG ${MOONCAKE_UBDIAG_GIT_TAG} - SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" - BINARY_DIR "${ubdiag_BINARY_DIR}" - SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") -endif() -_mooncake_verify_ubdiag_source("${ubdiag_SOURCE_DIR}") + _mooncake_verify_ubdiag_source("${ubdiag_SOURCE_DIR}") -# ===== Layer 0: UBDIAG_DISABLE 模式(默认) ===== -if(NOT MOONCAKE_ENABLE_UBDIAG) set(_MOONCAKE_UBDIAG_PERF_POINT_HEADER "${ubdiag_SOURCE_DIR}/include/ubdiag/perf_point.h") if(NOT EXISTS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}") - message(FATAL_ERROR - "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} is missing include/ubdiag/perf_point.h") + message(FATAL_ERROR "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} is missing " + "include/ubdiag/perf_point.h") endif() file(STRINGS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}" _MOONCAKE_UBDIAG_DISABLE_LINES REGEX "UBDIAG_DISABLE") if(NOT _MOONCAKE_UBDIAG_DISABLE_LINES) - message(FATAL_ERROR - "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} does not support UBDIAG_DISABLE. " - "Select an UbDiag release that contains the compile-time disabled PerfPoint implementation.") + message( + FATAL_ERROR "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} does not provide the " + "UBDIAG_DISABLE PerfPoint implementation required by Layer 0." + ) endif() - # Consumers inherit both the source include path and the compile-time switch. add_library(ubdiag_mock INTERFACE) - target_include_directories(ubdiag_mock INTERFACE ${ubdiag_SOURCE_DIR}/include) + target_include_directories(ubdiag_mock + INTERFACE "${ubdiag_SOURCE_DIR}/include") target_compile_definitions(ubdiag_mock INTERFACE UBDIAG_DISABLE) add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock) + set(MOONCAKE_UBDIAG_SYSTEM_PREFIX "") + set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY "") + set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM "") + set(MOONCAKE_UBDIAG_SYSTEM_CLI "") + set(MOONCAKE_UBDIAG_SYSTEM_CLI_RPM "") + set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH "") + set(MOONCAKE_UBDIAG_SYSTEM_CONFIG "") + set(MOONCAKE_UBDIAG_LIBRARY_DIR "") + set(UbDiag_VERSION "") + set(UbDiag_DIR "") set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER - "${CMAKE_BINARY_DIR}") - _mooncake_write_ubdiag_rpm_manifest("mock") - message(STATUS - "UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") + "${CMAKE_BINARY_DIR}") + _mooncake_write_ubdiag_manifest("mock") + message(STATUS "UbDiag: Layer 0 UBDIAG_DISABLE headers, verified " + "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") return() endif() -# ===== Layer 1: 编译真实 ubdiag ===== -set(_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE - "${ubdiag_BINARY_DIR}/mooncake-source-commit.txt") -set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR TRUE) -if(EXISTS "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}") - file(READ "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}" - _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT) - string(STRIP "${_MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT}" - _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT) - if(NOT _MOONCAKE_UBDIAG_PREVIOUS_BUILD_COMMIT STREQUAL - MOONCAKE_UBDIAG_RESOLVED_COMMIT) - set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR FALSE) - endif() -elseif(EXISTS "${ubdiag_BINARY_DIR}") - file(GLOB _MOONCAKE_UBDIAG_EXISTING_BUILD_FILES - "${ubdiag_BINARY_DIR}/*") - if(_MOONCAKE_UBDIAG_EXISTING_BUILD_FILES) - set(_MOONCAKE_UBDIAG_REUSE_BINARY_DIR FALSE) - endif() +# Layer 1 must be fully supplied by one system UbDiag RPM installation. +find_package(UbDiag CONFIG QUIET) +if(NOT UbDiag_FOUND) + message( + FATAL_ERROR + "MOONCAKE_ENABLE_UBDIAG=ON requires a system-installed UbDiag " + "shared SDK and CLI.\n" + "Install the UbDiag RPM separately (or build an UbDiag RPM with " + "UBDIAG_BUILD_SHARED=ON, ENABLE_PERCENTILE=ON, and ENABLE_PERFLOG=ON), " + "then install that RPM before configuring Mooncake.\n" + "Mooncake does not download or build the real UbDiag runtime in Layer 1. " + "Use CMAKE_PREFIX_PATH or UbDiag_DIR when it is installed under a " + "non-standard system prefix.") +endif() +if(NOT TARGET UbDiag::ubdiag_lib) + message( + FATAL_ERROR + "The system UbDiag package was found at ${UbDiag_DIR}, but it does not " + "export the required UbDiag::ubdiag_lib target. Reinstall the complete " + "UbDiag development RPM.") endif() -if(NOT _MOONCAKE_UBDIAG_REUSE_BINARY_DIR) - message(STATUS - "UbDiag: removing binary directory from a different or unverified source") - file(REMOVE_RECURSE "${ubdiag_BINARY_DIR}") + +get_target_property(_MOONCAKE_UBDIAG_IMPORTED UbDiag::ubdiag_lib IMPORTED) +get_target_property(_MOONCAKE_UBDIAG_TARGET_TYPE UbDiag::ubdiag_lib TYPE) +if(NOT _MOONCAKE_UBDIAG_IMPORTED OR NOT _MOONCAKE_UBDIAG_TARGET_TYPE STREQUAL + "SHARED_LIBRARY") + message( + FATAL_ERROR + "MOONCAKE_ENABLE_UBDIAG=ON requires the system shared SDK " + "libubdiag.so; ${UbDiag_DIR} exported target type " + "'${_MOONCAKE_UBDIAG_TARGET_TYPE}'. Rebuild and reinstall the UbDiag RPM " + "with UBDIAG_BUILD_SHARED=ON.") endif() -file(MAKE_DIRECTORY "${ubdiag_BINARY_DIR}") -file(WRITE "${_MOONCAKE_UBDIAG_BUILD_COMMIT_FILE}" - "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}\n") - -set(UBDIAG_BUILD_SHARED ON CACHE BOOL "" FORCE) -set(ENABLE_PERCENTILE ON CACHE BOOL "" FORCE) -set(ENABLE_PERFLOG ON CACHE BOOL "" FORCE) -set(ENABLE_OB_MEMORY OFF CACHE BOOL "" FORCE) -set(ENABLE_OB_CACHE OFF CACHE BOOL "" FORCE) -set(ENABLE_MEMPOINT OFF CACHE BOOL "" FORCE) -set(UBDIAG_ENABLE_CACHEPOINT OFF CACHE BOOL "" FORCE) - -function(_mooncake_make_ubdiag_available) - # UbDiag still exposes generic BUILD_* options. Keep the overrides inside a - # function scope so Mooncake's own BUILD_EXAMPLES value is not changed. - set(BUILD_TESTS OFF) - set(BUILD_EXAMPLES OFF) - add_subdirectory("${ubdiag_SOURCE_DIR}" "${ubdiag_BINARY_DIR}") + +function(_mooncake_get_imported_location target output_variable) + get_target_property(_imported_configs "${target}" IMPORTED_CONFIGURATIONS) + foreach(_config IN LISTS _imported_configs) + string(TOUPPER "${_config}" _config_upper) + get_target_property(_candidate "${target}" + "IMPORTED_LOCATION_${_config_upper}") + if(_candidate AND NOT _candidate MATCHES "-NOTFOUND$") + set("${output_variable}" + "${_candidate}" + PARENT_SCOPE) + return() + endif() + endforeach() + get_target_property(_candidate "${target}" IMPORTED_LOCATION) + if(_candidate AND NOT _candidate MATCHES "-NOTFOUND$") + set("${output_variable}" + "${_candidate}" + PARENT_SCOPE) + endif() endfunction() -_mooncake_make_ubdiag_available() -if(NOT TARGET ubdiag_lib OR NOT TARGET ubdiag) - message(FATAL_ERROR - "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} did not create both ubdiag_lib and CLI targets") +_mooncake_get_imported_location(UbDiag::ubdiag_lib + _MOONCAKE_UBDIAG_IMPORTED_LOCATION) +if(NOT _MOONCAKE_UBDIAG_IMPORTED_LOCATION + OR NOT EXISTS "${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}") + message( + FATAL_ERROR + "The system UbDiag target does not resolve to an installed shared " + "library: ${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}") +endif() +get_filename_component(MOONCAKE_UBDIAG_SYSTEM_LIBRARY + "${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}" REALPATH) +get_filename_component(MOONCAKE_UBDIAG_LIBRARY_DIR + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" DIRECTORY) +get_filename_component(_MOONCAKE_UBDIAG_LIBRARY_NAME + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" NAME) +if(NOT _MOONCAKE_UBDIAG_LIBRARY_NAME MATCHES "^libubdiag\\.so(\\..*)?$") + message( + FATAL_ERROR "The system UbDiag target resolved to an unexpected library: " + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}") endif() -# UbDiag master still uses CMAKE_SOURCE_DIR internally. When consumed by -# FetchContent that variable points at Mooncake, so add the real source paths -# to every UbDiag target without modifying the mirrored upstream sources. -foreach(_MOONCAKE_UBDIAG_LIB_TARGET - ubdiag_logger ubdiag_lib ubdiag_runtime_lib ubdiag_manager_lib - ubdiag_bpf_loader) - if(TARGET ${_MOONCAKE_UBDIAG_LIB_TARGET}) - target_include_directories(${_MOONCAKE_UBDIAG_LIB_TARGET} PUBLIC - $ - $) +get_target_property(_MOONCAKE_UBDIAG_COMPILE_DEFINITIONS UbDiag::ubdiag_lib + INTERFACE_COMPILE_DEFINITIONS) +foreach(_required_definition UBDIAG_ENABLE_PERCENTILE UBDIAG_ENABLE_PERFLOG) + list(FIND _MOONCAKE_UBDIAG_COMPILE_DEFINITIONS "${_required_definition}" + _definition_index) + if(_definition_index EQUAL -1) + message( + FATAL_ERROR + "The system UbDiag package does not advertise " + "${_required_definition}. Rebuild and reinstall the UbDiag RPM with " + "ENABLE_PERCENTILE=ON and ENABLE_PERFLOG=ON.") endif() endforeach() -target_include_directories(ubdiag PRIVATE - ${ubdiag_SOURCE_DIR}/include - ${ubdiag_SOURCE_DIR}/src - ${ubdiag_SOURCE_DIR}/src/cli) - -add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib) -set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER - "${CMAKE_BINARY_DIR}") -_mooncake_write_ubdiag_rpm_manifest("vendored") -message(STATUS - "UbDiag: FetchContent 编译 ${MOONCAKE_UBDIAG_GIT_TAG}(库+CLI), " - "verified ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") + +get_filename_component(_MOONCAKE_UBDIAG_LIBDIR_NAME + "${MOONCAKE_UBDIAG_LIBRARY_DIR}" NAME) +if(_MOONCAKE_UBDIAG_LIBDIR_NAME MATCHES "^lib(64)?$") + get_filename_component(MOONCAKE_UBDIAG_SYSTEM_PREFIX + "${MOONCAKE_UBDIAG_LIBRARY_DIR}" DIRECTORY) +else() + get_filename_component(_MOONCAKE_UBDIAG_CMAKE_DIR_PARENT "${UbDiag_DIR}" + DIRECTORY) + get_filename_component(_MOONCAKE_UBDIAG_PACKAGE_LIBDIR + "${_MOONCAKE_UBDIAG_CMAKE_DIR_PARENT}" DIRECTORY) + get_filename_component(MOONCAKE_UBDIAG_SYSTEM_PREFIX + "${_MOONCAKE_UBDIAG_PACKAGE_LIBDIR}" DIRECTORY) +endif() + +unset(_MOONCAKE_UBDIAG_CLI CACHE) +find_program( + _MOONCAKE_UBDIAG_CLI + NAMES ubdiag + PATHS "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin" + NO_DEFAULT_PATH) +if(NOT _MOONCAKE_UBDIAG_CLI) + message( + FATAL_ERROR + "The system UbDiag shared SDK was found at " + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}, but the matching ubdiag CLI was not " + "found at ${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin/ubdiag. Install the " + "complete UbDiag RPM before configuring Mooncake.") +endif() +get_filename_component(MOONCAKE_UBDIAG_SYSTEM_CLI "${_MOONCAKE_UBDIAG_CLI}" + REALPATH) + +find_program(_MOONCAKE_UBDIAG_RPM_EXECUTABLE NAMES rpm) +if(NOT _MOONCAKE_UBDIAG_RPM_EXECUTABLE) + message( + FATAL_ERROR + "MOONCAKE_ENABLE_UBDIAG=ON requires the rpm command to verify that the " + "system libubdiag.so and ubdiag CLI belong to matching UbDiag RPMs.") +endif() + +function(_mooncake_query_ubdiag_rpm file_path owner_output identity_output) + execute_process( + COMMAND "${_MOONCAKE_UBDIAG_RPM_EXECUTABLE}" -qf --qf + "%{NAME}|%{VERSION}-%{RELEASE}.%{ARCH}" "${file_path}" + RESULT_VARIABLE _rpm_result + OUTPUT_VARIABLE _rpm_record + ERROR_VARIABLE _rpm_error + OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) + if(NOT _rpm_result EQUAL 0 OR NOT _rpm_record MATCHES "^([^|]+)\\|(.+)$") + message( + FATAL_ERROR + "${file_path} is not owned by an installed RPM package. " + "Install the complete UbDiag RPM before configuring Mooncake.\n" + "rpm -qf: ${_rpm_error}") + endif() + set(_rpm_owner "${CMAKE_MATCH_1}") + set(_rpm_identity "${CMAKE_MATCH_2}") + string(TOLOWER "${_rpm_owner}" _rpm_owner_lower) + if(NOT _rpm_owner_lower MATCHES "ubdiag") + message( + FATAL_ERROR + "${file_path} is owned by '${_rpm_owner}', not an UbDiag RPM package.") + endif() + set("${owner_output}" + "${_rpm_owner}" + PARENT_SCOPE) + set("${identity_output}" + "${_rpm_identity}" + PARENT_SCOPE) +endfunction() + +_mooncake_query_ubdiag_rpm( + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM + _MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY) +_mooncake_query_ubdiag_rpm( + "${MOONCAKE_UBDIAG_SYSTEM_CLI}" MOONCAKE_UBDIAG_SYSTEM_CLI_RPM + _MOONCAKE_UBDIAG_CLI_RPM_IDENTITY) +if(NOT _MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY STREQUAL + _MOONCAKE_UBDIAG_CLI_RPM_IDENTITY) + message( + FATAL_ERROR + "The system libubdiag.so and ubdiag CLI come from different RPM " + "versions.\n" + " library: ${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM} " + "${_MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY}\n" + " CLI: ${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM} " + "${_MOONCAKE_UBDIAG_CLI_RPM_IDENTITY}\n" + "Reinstall one complete, matching UbDiag RPM set.") +endif() +set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH + "${_MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY}") + +unset(_MOONCAKE_UBDIAG_CONFIG CACHE) +set(_MOONCAKE_UBDIAG_CONFIG_PATHS "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/etc/ubdiag") +if(MOONCAKE_UBDIAG_SYSTEM_PREFIX STREQUAL "/usr") + list(APPEND _MOONCAKE_UBDIAG_CONFIG_PATHS "/etc/ubdiag") +endif() +find_file( + _MOONCAKE_UBDIAG_CONFIG + NAMES ubdiag.conf + PATHS ${_MOONCAKE_UBDIAG_CONFIG_PATHS} + NO_DEFAULT_PATH) +if(_MOONCAKE_UBDIAG_CONFIG) + get_filename_component(MOONCAKE_UBDIAG_SYSTEM_CONFIG + "${_MOONCAKE_UBDIAG_CONFIG}" REALPATH) +else() + set(MOONCAKE_UBDIAG_SYSTEM_CONFIG "") +endif() + +set(MOONCAKE_UBDIAG_SYSTEM_PREFIX + "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}" + CACHE PATH "System UbDiag installation prefix selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" + CACHE FILEPATH "System libubdiag.so selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}" + CACHE STRING + "RPM package owning the system libubdiag.so selected by Mooncake" + FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_CLI + "${MOONCAKE_UBDIAG_SYSTEM_CLI}" + CACHE FILEPATH "System ubdiag CLI selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_CLI_RPM + "${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}" + CACHE STRING + "RPM package owning the system ubdiag CLI selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH + "${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" + CACHE STRING + "Matching system UbDiag RPM version-release.arch selected by Mooncake" + FORCE) +set(MOONCAKE_UBDIAG_SYSTEM_CONFIG + "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" + CACHE FILEPATH "System UbDiag configuration selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_LIBRARY_DIR + "${MOONCAKE_UBDIAG_LIBRARY_DIR}" + CACHE PATH "System UbDiag library directory selected by Mooncake" FORCE) +set(MOONCAKE_UBDIAG_GIT_REPOSITORY "") +set(MOONCAKE_UBDIAG_GIT_TAG "") +set(MOONCAKE_UBDIAG_EXPECTED_COMMIT "") +set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "") +set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "") +set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER "${CMAKE_BINARY_DIR}") +_mooncake_write_ubdiag_manifest("system") +message( + STATUS "UbDiag: Layer 1 system RPM ${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}; " + "library=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}; " + "CLI=${MOONCAKE_UBDIAG_SYSTEM_CLI}") diff --git a/mooncake-p2p-store/CMakeLists.txt b/mooncake-p2p-store/CMakeLists.txt index 04b5fe706b..ee815b79b9 100644 --- a/mooncake-p2p-store/CMakeLists.txt +++ b/mooncake-p2p-store/CMakeLists.txt @@ -1,15 +1,11 @@ # Currently you have to manually execute makefile in the src subdirectory. add_custom_target(build_p2p_store DEPENDS transfer_engine) add_custom_command( - TARGET build_p2p_store - COMMAND bash build.sh - ${CMAKE_CURRENT_BINARY_DIR} - ${USE_ETCD} - ${USE_REDIS} - ${USE_HTTP} - ${USE_ETCD_LEGACY} - ${CMAKE_BINARY_DIR} - ${MOONCAKE_UBDIAG_ACTIVE_LAYER} - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) + TARGET build_p2p_store + COMMAND + bash build.sh ${CMAKE_CURRENT_BINARY_DIR} ${USE_ETCD} ${USE_REDIS} + ${USE_HTTP} ${USE_ETCD_LEGACY} ${CMAKE_BINARY_DIR} + "${MOONCAKE_UBDIAG_ACTIVE_LAYER}" "${MOONCAKE_UBDIAG_LIBRARY_DIR}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + VERBATIM) set_property(TARGET build_p2p_store PROPERTY EXCLUDE_FROM_ALL FALSE) diff --git a/mooncake-p2p-store/build.sh b/mooncake-p2p-store/build.sh index 9363c3c639..75354bbef6 100644 --- a/mooncake-p2p-store/build.sh +++ b/mooncake-p2p-store/build.sh @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -if [ "$#" -ne 7 ]; then - echo "Usage: $0 TARGET_PATH USE_ETCD USE_REDIS USE_HTTP USE_ETCD_LEGACY BUILD_DIR UBDIAG_LAYER" +if [ "$#" -ne 8 ]; then + echo "Usage: $0 TARGET_PATH USE_ETCD USE_REDIS USE_HTTP USE_ETCD_LEGACY BUILD_DIR UBDIAG_LAYER UBDIAG_LIB_DIR" exit 1 fi @@ -25,6 +25,7 @@ USE_HTTP=$4 USE_ETCD_LEGACY=$5 BUILD_DIR=$6 UBDIAG_LAYER=$7 +UBDIAG_LIB_DIR=$8 cd "src/p2pstore" if [ $? -ne 0 ]; then @@ -38,17 +39,21 @@ EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common" EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common/src" EXT_LDFLAGS+=" -ltransfer_engine -lbase -lasio -lstdc++ -lnuma -lglog -libverbs -lmlx5 -ljsoncpp -lmooncake_common -lm" -# ubdiag 链接: vendored 模式链接真实库, mock 模式跳过(空函数无库) +# UbDiag link contract: mock has no runtime library; system uses the +# separately installed library selected by FindUbDiag.cmake. case "$UBDIAG_LAYER" in - vendored) - UBDIAG_LIB_DIR="$BUILD_DIR/_deps/ubdiag-build/src/sdk" + system) + if [ -z "$UBDIAG_LIB_DIR" ] || [ ! -d "$UBDIAG_LIB_DIR" ]; then + echo "P2P Store: invalid system UbDiag library directory: $UBDIAG_LIB_DIR" >&2 + exit 1 + fi EXT_LDFLAGS+=" -L$UBDIAG_LIB_DIR -lubdiag" ;; mock) - echo "P2P Store: ubdiag DISABLE 模式,跳过 -lubdiag" + echo "P2P Store: UBDIAG_DISABLE mode, skipping -lubdiag" ;; *) - echo "P2P Store: 未知 ubdiag layer: $UBDIAG_LAYER" >&2 + echo "P2P Store: unknown UbDiag layer: $UBDIAG_LAYER" >&2 exit 1 ;; esac diff --git a/mooncake-store/src/CMakeLists.txt b/mooncake-store/src/CMakeLists.txt index 0f8d7db6b5..615c52dc15 100644 --- a/mooncake-store/src/CMakeLists.txt +++ b/mooncake-store/src/CMakeLists.txt @@ -250,7 +250,7 @@ target_link_libraries( ${EXTRA_LIBS} ${SPDK_STATIC_LIBS} asio_shared mooncake_common PRIVATE transfer_engine) -# UbDiag instrumentation (FetchContent + UBDIAG_DISABLE 两层集成) +# UbDiag instrumentation (compile-time mock or system package) include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) target_link_libraries(mooncake_store PRIVATE UbDiag::ubdiag_lib) target_include_directories(mooncake_store PRIVATE diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index 55a45374de..8d7233c8ae 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -5,7 +5,7 @@ # Example: ./scripts/build_rpm.sh build rpm-output aarch64 # Example: ./scripts/build_rpm.sh build rpm-output all (build both platforms) -set -e # Exit immediately if a command exits with a non-zero status +set -euo pipefail set -x SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -49,15 +49,15 @@ echo "Target platform: ${TARGET_PLATFORM}" echo "Host architecture: ${HOST_ARCH}" # Ensure LD_LIBRARY_PATH includes build directories -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${BUILD_DIR_ABS}/mooncake-common:/usr/local/lib +export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:${BUILD_DIR_ABS}/mooncake-common:/usr/local/lib" # Clean previous build echo "Cleaning previous RPM build..." rm -rf rpmbuild/ -rm -rf ${OUTPUT_DIR}/ +rm -rf "${OUTPUT_DIR}/" fail_ubdiag_packaging() { - echo "Error: UbDiag RPM provenance check failed: $*" >&2 + echo "Error: UbDiag RPM packaging check failed: $*" >&2 return 1 } @@ -77,8 +77,8 @@ remove_staged_rpath() { fi } -load_ubdiag_rpm_manifest() { - local manifest=$1 +load_ubdiag_manifest() { + local manifest="$1" local key="" local value="" @@ -92,7 +92,13 @@ load_ubdiag_rpm_manifest() { case "${key}" in MOONCAKE_UBDIAG_LAYER|MOONCAKE_UBDIAG_GIT_REPOSITORY|\ MOONCAKE_UBDIAG_GIT_TAG|MOONCAKE_UBDIAG_EXPECTED_COMMIT|\ - MOONCAKE_UBDIAG_RESOLVED_COMMIT|MOONCAKE_UBDIAG_SOURCE_DIR) + MOONCAKE_UBDIAG_RESOLVED_COMMIT|MOONCAKE_UBDIAG_SOURCE_DIR|\ + MOONCAKE_UBDIAG_PACKAGE_VERSION|MOONCAKE_UBDIAG_PACKAGE_DIR|\ + MOONCAKE_UBDIAG_SYSTEM_PREFIX|MOONCAKE_UBDIAG_SYSTEM_LIBRARY|\ + MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM|MOONCAKE_UBDIAG_SYSTEM_CLI|\ + MOONCAKE_UBDIAG_SYSTEM_CLI_RPM|\ + MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH|\ + MOONCAKE_UBDIAG_SYSTEM_CONFIG) printf -v "${key}" '%s' "${value}" ;; "") @@ -106,80 +112,102 @@ load_ubdiag_rpm_manifest() { done < "${manifest}" } -verify_ubdiag_source_provenance() { - local source_dir="" - local current_commit="" - local dirty="" - local required_tool="" +query_rpm_file_owner() { + local file_path="$1" + rpm -qf --qf '%{NAME}|%{VERSION}-%{RELEASE}.%{ARCH}' "${file_path}" +} + +verify_system_ubdiag_inputs() { + local library_record="" + local cli_record="" + local library_owner="" + local cli_owner="" + local library_identity="" + local cli_identity="" - for required_tool in git readelf readlink sha256sum; do + for required_tool in cmake readelf readlink rpm; do if ! command -v "${required_tool}" >/dev/null 2>&1; then fail_ubdiag_packaging \ "required tool is unavailable: ${required_tool}" return 1 fi done + if [ ! -f "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" ] || + [ ! -x "${MOONCAKE_UBDIAG_SYSTEM_CLI}" ]; then + fail_ubdiag_packaging \ + "configured system UbDiag library or CLI is unavailable" + return 1 + fi - case "${MOONCAKE_UBDIAG_LAYER}" in - mock|vendored) + MOONCAKE_UBDIAG_SYSTEM_LIBRARY="$( + readlink -f "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" + )" + MOONCAKE_UBDIAG_SYSTEM_CLI="$( + readlink -f "${MOONCAKE_UBDIAG_SYSTEM_CLI}" + )" + case "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" in + "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/lib/libubdiag.so*|\ + "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/lib64/libubdiag.so*) ;; *) fail_ubdiag_packaging \ - "unsupported layer '${MOONCAKE_UBDIAG_LAYER:-unset}'" + "libubdiag.so is outside the configured system prefix" + return 1 + ;; + esac + case "${MOONCAKE_UBDIAG_SYSTEM_CLI}" in + "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/bin/ubdiag) + ;; + *) + fail_ubdiag_packaging \ + "ubdiag CLI is outside the configured system prefix" return 1 ;; esac - if [[ ! "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" =~ ^[0-9a-fA-F]{40}$ ]]; then - fail_ubdiag_packaging \ - "expected commit is not a full SHA: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" - return 1 - fi - if [ "${MOONCAKE_UBDIAG_EXPECTED_COMMIT,,}" != \ - "${MOONCAKE_UBDIAG_RESOLVED_COMMIT,,}" ]; then - fail_ubdiag_packaging \ - "configured commit ${MOONCAKE_UBDIAG_RESOLVED_COMMIT} does not match expected ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" - return 1 - fi - - source_dir="$(readlink -f "${MOONCAKE_UBDIAG_SOURCE_DIR}" 2>/dev/null || true)" - if [ -z "${source_dir}" ] || [ ! -f "${source_dir}/CMakeLists.txt" ]; then - fail_ubdiag_packaging \ - "verified source directory is unavailable: ${MOONCAKE_UBDIAG_SOURCE_DIR}" - return 1 - fi - - current_commit="$( - git -C "${source_dir}" rev-parse --verify HEAD 2>/dev/null || true - )" - if [ "${current_commit,,}" != "${MOONCAKE_UBDIAG_EXPECTED_COMMIT,,}" ]; then + library_record="$(query_rpm_file_owner \ + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" + cli_record="$(query_rpm_file_owner "${MOONCAKE_UBDIAG_SYSTEM_CLI}")" + IFS='|' read -r library_owner library_identity <<< "${library_record}" + IFS='|' read -r cli_owner cli_identity <<< "${cli_record}" + if [[ "${library_owner,,}" != *ubdiag* ]] || + [[ "${cli_owner,,}" != *ubdiag* ]]; then fail_ubdiag_packaging \ - "source changed after CMake configure: expected ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}, found ${current_commit}" + "library or CLI is not owned by an UbDiag RPM" return 1 fi - dirty="$(git -C "${source_dir}" status --porcelain --untracked-files=all)" - if [ -n "${dirty}" ]; then + if [ "${library_identity}" != "${cli_identity}" ] || + [ "${library_identity}" != \ + "${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" ] || + [ "${library_owner}" != "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}" ] || + [ "${cli_owner}" != "${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}" ]; then fail_ubdiag_packaging \ - "source worktree changed after CMake configure: ${source_dir}" - printf '%s\n' "${dirty}" >&2 + "system UbDiag RPM changed after CMake configure: library=${library_record}, CLI=${cli_record}, configured=${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" return 1 fi - - MOONCAKE_UBDIAG_SOURCE_DIR="${source_dir}" - MOONCAKE_UBDIAG_RESOLVED_COMMIT="${current_commit,,}" } # Function to build RPM for a specific platform build_rpm_for_platform() { local PLATFORM=$1 local LIB_DIR="lib64" - local UBDIAG_RPM_FILES="" + local BUILDROOT="" + local UBDIAG_CONFIG_RPM_FILE="" local MOONCAKE_UBDIAG_LAYER="" local MOONCAKE_UBDIAG_GIT_REPOSITORY="" local MOONCAKE_UBDIAG_GIT_TAG="" local MOONCAKE_UBDIAG_EXPECTED_COMMIT="" local MOONCAKE_UBDIAG_RESOLVED_COMMIT="" local MOONCAKE_UBDIAG_SOURCE_DIR="" + local MOONCAKE_UBDIAG_PACKAGE_VERSION="" + local MOONCAKE_UBDIAG_PACKAGE_DIR="" + local MOONCAKE_UBDIAG_SYSTEM_PREFIX="" + local MOONCAKE_UBDIAG_SYSTEM_LIBRARY="" + local MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM="" + local MOONCAKE_UBDIAG_SYSTEM_CLI="" + local MOONCAKE_UBDIAG_SYSTEM_CLI_RPM="" + local MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH="" + local MOONCAKE_UBDIAG_SYSTEM_CONFIG="" echo "Building RPM for platform: ${PLATFORM}" @@ -195,10 +223,12 @@ build_rpm_for_platform() { # Create RPM build directory structure for this platform mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} - mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM} + BUILDROOT="rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}" + mkdir -p "${BUILDROOT}" # Create target directories in BUILDROOT - mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/{usr/{bin,${LIB_DIR},include,share/doc/mooncake},etc/{mooncake,ubdiag}} + mkdir -p "${BUILDROOT}/usr/bin" "${BUILDROOT}/usr/${LIB_DIR}" \ + "${BUILDROOT}/usr/include" "${BUILDROOT}/etc/mooncake" # ------------------------------------------------------------------------- # Copy executables @@ -213,10 +243,21 @@ build_rpm_for_platform() { echo "Cross-compilation detected, looking in ${PLATFORM_BUILD_DIR}" fi - local UBDIAG_RPM_MANIFEST="${PLATFORM_BUILD_DIR}/mooncake_ubdiag_rpm.env" - echo "Reading verified UbDiag RPM manifest: ${UBDIAG_RPM_MANIFEST}" - load_ubdiag_rpm_manifest "${UBDIAG_RPM_MANIFEST}" - verify_ubdiag_source_provenance + local UBDIAG_MANIFEST="${PLATFORM_BUILD_DIR}/mooncake_ubdiag.env" + echo "Reading Mooncake UbDiag manifest: ${UBDIAG_MANIFEST}" + load_ubdiag_manifest "${UBDIAG_MANIFEST}" + case "${MOONCAKE_UBDIAG_LAYER}" in + mock) + ;; + system) + verify_system_ubdiag_inputs + ;; + *) + fail_ubdiag_packaging \ + "unsupported layer '${MOONCAKE_UBDIAG_LAYER:-unset}'" + return 1 + ;; + esac # mooncake_master if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master ]; then @@ -307,106 +348,46 @@ build_rpm_for_platform() { fi # ------------------------------------------------------------------------- - # Copy the verified UbDiag runtime selected by Mooncake + # Stage the matching system UbDiag RPM payload for Layer 1 # ------------------------------------------------------------------------- - local BUILDROOT="rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}" - if [ "${MOONCAKE_UBDIAG_LAYER}" = "vendored" ]; then - local ubdiag_binary_dir - local ubdiag_cli - local ubdiag_library_dir - local ubdiag_config - local ubdiag_library_real - local staged_library_real - local build_source_commit - local ubdiag_cli_sha256="" - local ubdiag_library_sha256="" - - ubdiag_binary_dir="$( - readlink -f "${PLATFORM_BUILD_DIR}/_deps/ubdiag-build" 2>/dev/null || - true - )" - ubdiag_cli="${ubdiag_binary_dir}/src/cli/ubdiag" - ubdiag_library_dir="${ubdiag_binary_dir}/src/sdk" - ubdiag_config="${MOONCAKE_UBDIAG_SOURCE_DIR}/config/ubdiag.conf.example" - build_source_commit="$( - tr -d '[:space:]' \ - < "${ubdiag_binary_dir}/mooncake-source-commit.txt" \ - 2>/dev/null || true - )" - - if [ -z "${ubdiag_binary_dir}" ] || - [ "${build_source_commit}" != "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" ]; then - fail_ubdiag_packaging \ - "current _deps/ubdiag-build has no matching source-commit marker" - return 1 - fi - if [ ! -x "${ubdiag_cli}" ] || - [ ! -f "${ubdiag_config}" ] || - ! compgen -G "${ubdiag_library_dir}/libubdiag.so*" >/dev/null || - ! readelf -d "${ubdiag_cli}" 2>/dev/null | - grep -q 'Shared library:.*libubdiag\.so'; then - fail_ubdiag_packaging \ - "Mooncake-built CLI, library, or config is missing/inconsistent" - return 1 - fi - ubdiag_library_real="$(readlink -f "${ubdiag_library_dir}/libubdiag.so")" - case "${ubdiag_library_real}" in - "${ubdiag_library_dir}"/*) - ;; - *) - fail_ubdiag_packaging "libubdiag.so escapes its build directory" - return 1 - ;; - esac + if [ "${MOONCAKE_UBDIAG_LAYER}" = "system" ]; then + local ubdiag_library_dir="" + local ubdiag_candidate="" + local staged_library_count=0 - cp "${ubdiag_cli}" "${BUILDROOT}/usr/bin/ubdiag" + ubdiag_library_dir="$(dirname "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" + cp "${MOONCAKE_UBDIAG_SYSTEM_CLI}" "${BUILDROOT}/usr/bin/ubdiag" chmod 755 "${BUILDROOT}/usr/bin/ubdiag" - cp -a "${ubdiag_library_dir}"/libubdiag.so* \ - "${BUILDROOT}/usr/${LIB_DIR}/" - cp "${ubdiag_config}" "${BUILDROOT}/etc/ubdiag/ubdiag.conf" - cmp -s "${ubdiag_cli}" "${BUILDROOT}/usr/bin/ubdiag" || - { - fail_ubdiag_packaging "staged CLI differs from build output" - return 1 - } - staged_library_real="$( - readlink -f "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so" - )" - cmp -s "${ubdiag_library_real}" "${staged_library_real}" || - { - fail_ubdiag_packaging "staged library differs from build output" - return 1 - } - remove_staged_rpath "${BUILDROOT}/usr/bin/ubdiag" - ubdiag_cli_sha256="$( - sha256sum "${BUILDROOT}/usr/bin/ubdiag" | awk '{print $1}' - )" - ubdiag_library_sha256="$( - sha256sum "${staged_library_real}" | awk '{print $1}' - )" - cat > "${BUILDROOT}/usr/share/doc/mooncake/ubdiag-provenance.txt" << EOF -layer=vendored -repository=${MOONCAKE_UBDIAG_GIT_REPOSITORY} -tag=${MOONCAKE_UBDIAG_GIT_TAG} -commit=${MOONCAKE_UBDIAG_RESOLVED_COMMIT} -cli_sha256=${ubdiag_cli_sha256} -library_file=$(basename "${ubdiag_library_real}") -library_sha256=${ubdiag_library_sha256} -EOF - UBDIAG_RPM_FILES=" -/usr/bin/ubdiag -/usr/${LIB_DIR}/libubdiag.so* -%config(noreplace) /etc/ubdiag/ubdiag.conf -/usr/share/doc/mooncake/ubdiag-provenance.txt" - echo "UbDiag RPM source verified: ${MOONCAKE_UBDIAG_RESOLVED_COMMIT}" - else - if compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" >/dev/null || - [ -e "${BUILDROOT}/usr/bin/ubdiag" ]; then + while IFS= read -r -d '' ubdiag_candidate; do + if [ "$(readlink -f "${ubdiag_candidate}")" = \ + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" ]; then + cp -a "${ubdiag_candidate}" "${BUILDROOT}/usr/${LIB_DIR}/" + staged_library_count=$((staged_library_count + 1)) + fi + done < <( + find "${ubdiag_library_dir}" -maxdepth 1 \ + -name 'libubdiag.so*' -print0 + ) + if [ "${staged_library_count}" -eq 0 ] || + [ ! -f "${BUILDROOT}/usr/${LIB_DIR}/$(basename \ + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" ]; then fail_ubdiag_packaging \ - "mock layer must not stage any UbDiag CLI or shared library" + "failed to stage the selected system libubdiag.so chain" return 1 fi + + if [ -n "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" ]; then + if [ ! -f "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" ]; then + fail_ubdiag_packaging \ + "configured UbDiag config disappeared: ${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" + return 1 + fi + mkdir -p "${BUILDROOT}/etc/ubdiag" + cp "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" \ + "${BUILDROOT}/etc/ubdiag/ubdiag.conf" + UBDIAG_CONFIG_RPM_FILE="%config(noreplace) /etc/ubdiag/ubdiag.conf" + fi fi # ------------------------------------------------------------------------- @@ -513,9 +494,24 @@ EOF cp mooncake-store/conf/master.json rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi + # ------------------------------------------------------------------------- + # Validate the staged runtime before creating the RPM + # ------------------------------------------------------------------------- local staged_elf="" local staged_ubdiag_dependency_count=0 + for required_binary in mooncake_master mooncake_client; do + if [ ! -x "${BUILDROOT}/usr/bin/${required_binary}" ]; then + fail_ubdiag_packaging \ + "required Mooncake binary is missing: ${required_binary}" + return 1 + fi + done + while IFS= read -r -d '' staged_elf; do + if ! readelf -h "${staged_elf}" >/dev/null 2>&1; then + continue + fi + remove_staged_rpath "${staged_elf}" case "${staged_elf}" in */usr/bin/ubdiag|*/usr/${LIB_DIR}/libubdiag.so*) continue @@ -523,37 +519,33 @@ EOF esac if readelf -d "${staged_elf}" 2>/dev/null | grep -q 'Shared library:.*libubdiag\.so'; then - remove_staged_rpath "${staged_elf}" staged_ubdiag_dependency_count=$((staged_ubdiag_dependency_count + 1)) fi done < <(find "${BUILDROOT}" -type f -print0) - if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ] && - [ "${staged_ubdiag_dependency_count}" -ne 0 ]; then - fail_ubdiag_packaging \ - "mock RPM contains ${staged_ubdiag_dependency_count} ELF file(s) linked to libubdiag" - return 1 - fi - if [ "${MOONCAKE_UBDIAG_LAYER}" = "vendored" ] && - [ "${staged_ubdiag_dependency_count}" -eq 0 ]; then - fail_ubdiag_packaging \ - "vendored RPM has no ELF consumer linked to the packaged libubdiag" - return 1 - fi - local OPTIONAL_RPM_FILES="" - local optional_rpm_file="" - for optional_rpm_file in \ - /usr/bin/transfer_engine_bench \ - /usr/${LIB_DIR}/libmooncake_store.so \ - /usr/${LIB_DIR}/libtransfer_engine.so \ - /usr/${LIB_DIR}/libmooncake_common.so \ - /usr/${LIB_DIR}/libetcd_wrapper.so \ - /usr/${LIB_DIR}/libmooncake_engine.so \ - /usr/${LIB_DIR}/libmooncake_store_python.so; do - if [ -e "${BUILDROOT}${optional_rpm_file}" ]; then - OPTIONAL_RPM_FILES+="${optional_rpm_file}"$'\n' + if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ]; then + if [ "${staged_ubdiag_dependency_count}" -ne 0 ] || + [ -e "${BUILDROOT}/usr/bin/ubdiag" ] || + compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" \ + >/dev/null; then + fail_ubdiag_packaging \ + "mock RPM must not contain or depend on the UbDiag runtime" + return 1 fi - done + else + if [ "${staged_ubdiag_dependency_count}" -eq 0 ]; then + fail_ubdiag_packaging \ + "system RPM has no Mooncake ELF linked to libubdiag.so" + return 1 + fi + if [ ! -x "${BUILDROOT}/usr/bin/ubdiag" ] || + ! compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" \ + >/dev/null; then + fail_ubdiag_packaging \ + "system RPM is missing the UbDiag CLI or shared library" + return 1 + fi + fi # ------------------------------------------------------------------------- # Create RPM spec file @@ -586,29 +578,23 @@ Requires: libibverbs.so.1()(64bit) Recommends: libcudart.so.12()(64bit) Recommends: liburma.so.0()(64bit) -# Optional dependencies - not required but recommended -Requires(pre): /usr/sbin/ldconfig +# Refresh the dynamic linker cache after installation and removal. +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig %description ${PACKAGE_DESCRIPTION} %files -/usr/bin/mooncake_master -/usr/bin/mooncake_client -/usr/bin/stress_cluster_bench -/usr/${LIB_DIR}/libasio.so -${OPTIONAL_RPM_FILES} -${UBDIAG_RPM_FILES} -/usr/include/mooncake/*.h -/usr/include/mooncake/*.hpp -/etc/mooncake/master.yaml -/etc/mooncake/master.json - -%post -/sbin/ldconfig - -%postun -/sbin/ldconfig +/usr/bin/* +/usr/${LIB_DIR}/* +/usr/include/mooncake/* +%config(noreplace) /etc/mooncake/* +${UBDIAG_CONFIG_RPM_FILE} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig %changelog * $(date +"%a %b %d %Y") KVCache.AI - ${PACKAGE_VERSION}-${PACKAGE_RELEASE} @@ -627,7 +613,7 @@ EOF fi # Create platform-specific output directory - mkdir -p ${OUTPUT_DIR}/${PLATFORM} + mkdir -p "${OUTPUT_DIR}/${PLATFORM}" # Build the RPM rpmbuild -bb \ @@ -636,7 +622,62 @@ EOF rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec # Move RPM to platform-specific directory - mv ${OUTPUT_DIR}/${PLATFORM}/*.rpm ${OUTPUT_DIR}/ 2>/dev/null || true + mv "${OUTPUT_DIR}/${PLATFORM}"/*.rpm "${OUTPUT_DIR}/" 2>/dev/null || true + + local built_rpm="" + local rpm_candidate="" + for rpm_candidate in "${OUTPUT_DIR}"/*.rpm; do + [ -e "${rpm_candidate}" ] || continue + if [ "$(rpm -qp --qf '%{ARCH}' "${rpm_candidate}")" = \ + "${PLATFORM}" ]; then + built_rpm="${rpm_candidate}" + fi + done + if [ -z "${built_rpm}" ]; then + fail_ubdiag_packaging \ + "rpmbuild did not produce a ${PLATFORM} Mooncake RPM" + return 1 + fi + + local rpm_file_list="" + rpm_file_list="$(rpm -qlp "${built_rpm}")" + if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ]; then + if grep -Eq '^/usr/bin/ubdiag$|^/usr/lib64/libubdiag\.so' \ + <<< "${rpm_file_list}"; then + fail_ubdiag_packaging \ + "mock RPM unexpectedly contains the UbDiag runtime" + return 1 + fi + else + grep -qx '/usr/bin/ubdiag' <<< "${rpm_file_list}" || + { + fail_ubdiag_packaging \ + "system RPM does not contain /usr/bin/ubdiag" + return 1 + } + grep -Eq '^/usr/lib64/libubdiag\.so' <<< "${rpm_file_list}" || + { + fail_ubdiag_packaging \ + "system RPM does not contain libubdiag.so" + return 1 + } + fi + + # Install the payload into an isolated RPM root. This verifies that the + # generated package can be installed without mutating the build machine. + local install_root + install_root="$(pwd)/rpmbuild/INSTALLROOT-${PLATFORM}" + mkdir -p "${install_root}" + rpm --root "${install_root}" --initdb + rpm --root "${install_root}" -ivh --nodeps --noscripts "${built_rpm}" + test -x "${install_root}/usr/bin/mooncake_master" + test -x "${install_root}/usr/bin/mooncake_client" + if [ "${MOONCAKE_UBDIAG_LAYER}" = "system" ]; then + test -x "${install_root}/usr/bin/ubdiag" + compgen -G "${install_root}/usr/${LIB_DIR}/libubdiag.so*" \ + >/dev/null + fi + rm -rf "${install_root}" # Cleanup BUILDROOT for next platform rm -rf rpmbuild/BUILDROOT/ @@ -670,7 +711,7 @@ fi # List created RPM files echo "RPM packages built successfully!" echo "Created RPM files:" -ls -la ${OUTPUT_DIR}/*.rpm 2>/dev/null || echo "No RPM files created" +ls -la "${OUTPUT_DIR}"/*.rpm 2>/dev/null || echo "No RPM files created" # Cleanup rm -rf rpmbuild/ From 480fe3d480515ec108a79d4e6253842d7e9bf539 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Tue, 28 Jul 2026 23:31:46 +0800 Subject: [PATCH 15/18] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0UbDiag=E4=B8=A4?= =?UTF-8?q?=E5=B1=82=E9=9B=86=E6=88=90=E4=B8=8E=E5=8D=95RPM=E8=AF=B4?= =?UTF-8?q?=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 322 +++++++++++++------------------ 1 file changed, 139 insertions(+), 183 deletions(-) diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md index 84c2a2ed83..d55515e801 100644 --- a/docs/ubdiag_integration_guide.md +++ b/docs/ubdiag_integration_guide.md @@ -1,263 +1,219 @@ -# Mooncake UbDiag 两层分发与单 RPM 使用指南 +# Mooncake UbDiag 两层集成使用指南 -Mooncake 通过统一的 CMake 接口提供 UbDiag 两层分发能力。默认模式将 -PerfPoint 编译为空实现;启用模式从同一份 UbDiag 源码同步构建 SDK 动态库 -与命令行工具,并将 Mooncake、CLI、动态库和配置打入一个 RPM,供性能 -采集与分析使用。 +Mooncake 在配置阶段提供两个互斥的 UbDiag 编译层。构建完成后不能在运行时 +切换层级;如需切换,应重新配置并编译。 -## 1. 模式选择 +| 层 | 配置 | UbDiag 来源 | 生成结果 | +|---|---|---|---| +| Layer 0:Mock | `MOONCAKE_ENABLE_UBDIAG=OFF` | Mooncake 拉取固定源码头文件 | PerfPoint 为空实现,无 UbDiag 运行时依赖 | +| Layer 1:System | `MOONCAKE_ENABLE_UBDIAG=ON` | 用户预装的 UbDiag RPM | Mooncake 链接系统 `.so`,并可将同版本 CLI/`.so` 打入单一 RPM | -| 模式 | CMake 选项 | 适用场景 | 构建产物 | -|------|------------|----------|----------| -| Layer 0:禁用模式 | `MOONCAKE_ENABLE_UBDIAG=OFF`(默认) | 不需要性能采集,保持零运行时依赖 | 仅使用 UbDiag 头文件;不生成或链接 `libubdiag` | -| Layer 1:启用模式 | `MOONCAKE_ENABLE_UBDIAG=ON` | 使用 PerfPoint、分位数、PerfLog 和 CSV 分析 Mooncake | 同步生成 `libubdiag.so` 与 `ubdiag` CLI | +## 1. Layer 0:默认 Mock -模式由编译期选项决定,不能在运行时切换。建议为两种模式使用独立构建目录。 +### 1.1 配置与编译 -> [!NOTE] -> L1 RPM 安装后可以不执行 `ubdiag start`,此时不会进行共享内存采集; -> 但该二进制仍链接真实 `libubdiag`,不能称为 Layer 0 编译期禁用模式。 +```bash +cmake -S . -B build \ + -DMOONCAKE_ENABLE_UBDIAG=OFF +cmake --build build --parallel +``` -## 2. 默认禁用模式 +`MOONCAKE_ENABLE_UBDIAG` 默认值为 `OFF`,因此该参数可以省略。 -未指定 `MOONCAKE_ENABLE_UBDIAG` 时,Mooncake 默认使用 Layer 0: +Mooncake 使用 FetchContent 拉取固定提交的 UbDiag 源码,只消费公共头文件, +并通过统一目标 `UbDiag::ubdiag_lib` 传播: -```bash -cmake -S . -B build -cmake --build build -j +```text +include/ubdiag +UBDIAG_DISABLE ``` -也可以显式指定: +UbDiag 头文件中的 `UBDIAG_DISABLE` 分支将 PerfPoint 构造、`Start()`、 +`End()` 和 `Abandon()` 编译为空实现。因此: + +- Mooncake 打点源码保持不变; +- Mooncake ELF 不依赖 `libubdiag.so`; +- 不生成或打包 UbDiag CLI; +- 不创建 UbDiag SHM; +- 系统中已安装的 UbDiag 不参与该构建。 + +离线环境可以指定相同提交的洁净 UbDiag 工作树: ```bash -cmake -S . -B build -DMOONCAKE_ENABLE_UBDIAG=OFF -cmake --build build -j +cmake -S . -B build \ + -DMOONCAKE_ENABLE_UBDIAG=OFF \ + -DMOONCAKE_UBDIAG_SOURCE_DIR=/opt/src/ubdiag ``` -CMake 配置阶段应输出(末尾同时打印已验证提交): +## 2. Layer 1:系统 UbDiag + +### 2.1 前置条件 + +Layer 1 不下载或编译真实 UbDiag。配置 Mooncake 前,用户必须先安装完整 +UbDiag RPM。该安装必须同时提供: + +- `UbDiagConfig.cmake`; +- 导入目标 `UbDiag::ubdiag_lib`; +- 共享库 `libubdiag.so`; +- 同一安装前缀下的 `bin/ubdiag`; +- `UBDIAG_ENABLE_PERCENTILE`; +- `UBDIAG_ENABLE_PERFLOG`。 + +UbDiag RPM 构建时应至少启用: ```text -UbDiag: UBDIAG_DISABLE(空函数,零依赖), verified 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f +UBDIAG_BUILD_SHARED=ON +ENABLE_PERCENTILE=ON +ENABLE_PERFLOG=ON ``` -该模式使用 UbDiag `0.6.0` 的同一份公共头文件,并通过 -`UBDIAG_DISABLE` 将 PerfPoint 编译为空函数。Mooncake 无需启动 UbDiag, -也不需要安装 CLI 或动态库。可使用以下命令确认目标程序未链接 UbDiag: +Mooncake 不固定 L1 的 UbDiag 版本或源码 SHA。它通过 RPM 数据库分别查询 +真实 `libubdiag.so` 与 CLI 的所有者,并要求二者的 +`VERSION-RELEASE.ARCH` 完全一致。UbDiag RPM 自身的功能正确性由 UbDiag +发布方负责。 + +### 2.2 配置与编译 + +标准系统路径: ```bash -ldd | grep libubdiag +cmake -S . -B build-ubdiag \ + -DMOONCAKE_ENABLE_UBDIAG=ON +cmake --build build-ubdiag --parallel ``` -命令应无输出。 +自定义 RPM 安装前缀: -## 3. 启用 UbDiag +```bash +cmake -S . -B build-ubdiag \ + -DMOONCAKE_ENABLE_UBDIAG=ON \ + -DCMAKE_PREFIX_PATH=/opt/ubdiag +``` -需要采集 Mooncake PerfPoint 数据时,使用独立目录重新配置并构建: +也可以直接指定 CMake package: ```bash -cmake -S . -B build-ubdiag -DMOONCAKE_ENABLE_UBDIAG=ON -cmake --build build-ubdiag -j +cmake -S . -B build-ubdiag \ + -DMOONCAKE_ENABLE_UBDIAG=ON \ + -DUbDiag_DIR=/opt/ubdiag/lib64/cmake/UbDiag ``` -CMake 配置阶段应输出(末尾同时打印已验证提交): +### 2.3 配置门禁 -```text -UbDiag: FetchContent 编译 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f(库+CLI), verified 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f -``` +ON 模式依次检查: -默认构建目录下的关键产物为: +1. 找到 UbDiag CMake package; +2. package 导出导入型 `SHARED_LIBRARY` 目标; +3. 共享库解析为真实存在的 `libubdiag.so`; +4. target 传播 P99 与 PerfLog 能力宏; +5. 在同一安装前缀找到 `bin/ubdiag`; +6. `.so` 与 CLI 均由名称包含 `ubdiag` 的 RPM 拥有; +7. 两个 RPM 的 `VERSION-RELEASE.ARCH` 完全一致。 -```text -build-ubdiag/_deps/ubdiag-build/src/sdk/libubdiag.so -build-ubdiag/_deps/ubdiag-build/src/cli/ubdiag -``` +任一条件不满足都会停止配置。Mooncake 不会回退到源码构建,也不会使用 +`PATH` 中另一个前缀的 CLI。 -运行前应使用本次构建生成的 CLI 和动态库: +## 3. 构建 Mooncake RPM + +### 3.1 Mock RPM ```bash -export UBDIAG_BUILD="$PWD/build-ubdiag/_deps/ubdiag-build" -export UBDIAG_CLI="$UBDIAG_BUILD/src/cli/ubdiag" -export LD_LIBRARY_PATH="$UBDIAG_BUILD/src/sdk${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}" +bash scripts/build_rpm.sh build rpm-output "$(uname -m)" +rpm -qlp rpm-output/mooncake-*.rpm ``` -不得混用系统中其他版本的 `ubdiag` CLI 或 `libubdiag.so`。CLI 与 SDK -必须来自同一源码版本和同一次构建,以保证共享内存布局及功能开关一致。 +Mock RPM 包含 Mooncake 二进制,但不包含: + +```text +/usr/bin/ubdiag +/usr/lib64/libubdiag.so* +/etc/ubdiag/ubdiag.conf +``` -## 4. 安装 L1 单 RPM +打包脚本还会检查所有 Mooncake ELF 均不依赖 `libubdiag.so`。 -完成 L1 构建后,可直接生成一个包含 Mooncake 和 UbDiag 的 RPM: +### 3.2 System RPM ```bash bash scripts/build_rpm.sh build-ubdiag rpm-output "$(uname -m)" -sudo rpm -Uvh rpm-output/mooncake-*.rpm +rpm -qlp rpm-output/mooncake-*.rpm ``` -安装后的关键文件如下: +System RPM 包含: ```text /usr/bin/mooncake_master /usr/bin/mooncake_client /usr/bin/ubdiag -/usr/lib64/libubdiag.so -/usr/lib64/libubdiag.so.0 -/usr/lib64/libubdiag.so.0.6.0 -/etc/ubdiag/ubdiag.conf -/usr/share/doc/mooncake/ubdiag-provenance.txt +/usr/lib64/libubdiag.so* +/etc/ubdiag/ubdiag.conf # 系统包提供配置时 ``` -不需要再安装独立 UbDiag CLI 包。可以直接确认版本和来源: - -```bash -/usr/bin/ubdiag --version -cat /usr/share/doc/mooncake/ubdiag-provenance.txt -ldd /usr/bin/mooncake_master | grep libubdiag -``` +打包脚本读取 `build-ubdiag/mooncake_ubdiag.env`,不会重新搜索 `PATH` 或 +`LD_LIBRARY_PATH`。在复制前会再次查询 `.so` 与 CLI 的 RPM 归属;若系统 +UbDiag 在配置后被升级、替换或拆成不同版本,打包立即失败。 -版本输出应包含 `ubdiag version 0.6.0` 和构建身份 `8df2c284`; -provenance 中的完整提交应为 -`8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f`。 +生成 RPM 后,脚本会: -## 5. 采集与分析 +1. 检查 RPM 文件清单; +2. 检查 Mock/System 层与 ELF 依赖是否一致; +3. 清除构建目录 RPATH/RUNPATH; +4. 将 RPM 安装到隔离根目录,验证 payload 可以正常回装; +5. 不修改构建机当前已安装的软件。 -启动 UbDiag 共享内存,并启用 PerfLog: +## 4. 安装与运行 ```bash -ubdiag start --perflog +sudo rpm -Uvh rpm-output/mooncake-*.rpm +sudo ldconfig + +ubdiag --version +ubdiag start ubdiag status -``` -随后按 Mooncake 原有方式启动服务和业务负载。负载运行期间可执行: +# 启动 Mooncake master/client 并执行实际读写负载 -```bash ubdiag show ubdiag show --detail -ubdiag show --perflog -ubdiag watch --interval 1000 -ubdiag history -n 5 ``` -其中 `show` 输出聚合统计及 P99/P999/P9999,`show --detail` 输出按核数据, -`show --perflog` 输出最近的单次探针记录。`watch` 使用 `Ctrl+C` 结束。 - -将分析结果导出为 CSV: +PerfLog、P99 与 CSV 参数以所安装 UbDiag CLI 的帮助为准: ```bash -mkdir -p ./ubdiag-results -ubdiag show --csv ./ubdiag-results -ubdiag show --detail --csv ./ubdiag-results -ubdiag show --perflog --csv ./ubdiag-results -ubdiag history --csv ./ubdiag-results +ubdiag --help +ubdiag show --help ``` -分析结束后销毁共享内存: - -```bash -ubdiag stop -``` - -源码构建但尚未安装 RPM 时,将以上 `ubdiag` 替换为 -`build-ubdiag/_deps/ubdiag-build/src/cli/ubdiag`,并确保 -`LD_LIBRARY_PATH` 首项为同一构建目录的 `src/sdk`。 - -## 6. 离线源码 +## 5. 常见错误 -构建环境无法访问 GitHub 时,预先准备精确版本且保留 `.git` 元数据的 -UbDiag 洁净工作树,并通过 `MOONCAKE_UBDIAG_SOURCE_DIR` 指定绝对路径: +### `.so` 或 CLI 不受 RPM 管理 -```bash -git clone https://github.com/LinQuickDev/ubdiag.git /opt/src/ubdiag -git -C /opt/src/ubdiag checkout 8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f -cmake -S . -B build-ubdiag \ - -DMOONCAKE_ENABLE_UBDIAG=ON \ - -DMOONCAKE_UBDIAG_SOURCE_DIR=/opt/src/ubdiag -cmake --build build-ubdiag -j -``` - -`MOONCAKE_UBDIAG_SOURCE_DIR` 同样适用于默认禁用模式;将上述命令中的 -`MOONCAKE_ENABLE_UBDIAG` 改为 `OFF` 即可。两种模式均不会在已指定本地 -源码时访问 UbDiag 远端仓库。 +L1 面向系统 UbDiag RPM,不接受手工复制的散装文件。请安装完整 UbDiag +RPM 后重新配置 Mooncake。 -配置阶段会自动执行以下等价校验,不需要人工确认: +### `.so` 与 CLI 的 RPM 版本不同 -```bash -git -C /opt/src/ubdiag rev-parse HEAD -git -C /opt/src/ubdiag status --porcelain --untracked-files=all -``` +卸载冲突版本,并安装同一发布批次的 UbDiag RPM。Mooncake 比较 +`VERSION-RELEASE.ARCH`,不通过文件 SHA 判断。 -提交必须为 `8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f`,工作树必须无修改和 -未跟踪文件。升级 UbDiag 版本时,必须同时更新 -`MOONCAKE_UBDIAG_GIT_TAG` 和完整的 -`MOONCAKE_UBDIAG_EXPECTED_COMMIT`,不能只更换标签。 +### 找到静态库 -## 7. RPM 打包与来源保证 +重新构建 UbDiag RPM,并设置 `UBDIAG_BUILD_SHARED=ON`。 -CMake 每次配置都会在当前构建目录生成 -`mooncake_ubdiag_rpm.env`。该清单记录当前层、UbDiag 源码目录、期望提交 -和实际提交。CLI 与动态库路径固定从当前 Mooncake build 的 -`_deps/ubdiag-build` 推导,清单不能把它们重定向到其他目录。 +### 缺少 P99 或 PerfLog -完成构建后执行: +重新构建 UbDiag RPM,并设置: -```bash -bash scripts/build_rpm.sh build-ubdiag rpm-output "$(uname -m)" +```text +ENABLE_PERCENTILE=ON +ENABLE_PERFLOG=ON ``` -打包脚本不会搜索 `$PATH`、`LD_LIBRARY_PATH`、`/usr/bin`、`/usr/lib64` -或 `/usr/local` 中的 UbDiag,也不会使用 `find_package(UbDiag)`。它只接受 -CMake 清单指定的 FetchContent 源码和构建产物,并在出包前再次执行以下 -硬校验: - -1. 源码仓当前提交、配置时解析的提交和期望提交三者完全一致。 -2. 源码工作树保持洁净,避免同一 SHA 下混入本地修改。 -3. UbDiag 子构建目录的提交标记与当前源码一致;版本变化时只清理并重建 - 该子目录。 -4. CLI 和全部 `libubdiag.so*` 位于当前 Mooncake build 的 - `_deps/ubdiag-build` 内。 -5. CLI 确实依赖同一构建目录生成的 `libubdiag.so`。 -6. 复制到 RPM BUILDROOT 后逐文件比较,防止打包阶段替换产物。 -7. 删除 CLI 和 Mooncake 消费者中的构建目录 `RPATH/RUNPATH`,避免安装后 - 继续引用出包机器的 `_deps` 路径。 -8. 对完成 RPATH 清理后的最终 CLI 和真实动态库计算 SHA256,并写入 - provenance。 - -Layer 0 的 RPM 不包含 UbDiag CLI 或动态库,并检查待打包 ELF 不依赖 -`libubdiag.so`。Layer 1 的 RPM 包含同一次构建生成的 CLI、动态库和配置, -同时写入 `/usr/share/doc/mooncake/ubdiag-provenance.txt`,记录提交 SHA -以及 CLI、动态库 SHA256。 - -同一构建目录先配置 Layer 0、后续再切换到 Layer 1 时,必须重新执行 CMake -配置和构建,再执行 RPM 脚本: +### 从 Mock 切换到 System + +推荐使用新的构建目录,避免旧模式产物混入: ```bash -cmake -S . -B build -DMOONCAKE_ENABLE_UBDIAG=ON -cmake --build build -j -bash scripts/build_rpm.sh build rpm-output "$(uname -m)" +cmake -S . -B build-ubdiag \ + -DMOONCAKE_ENABLE_UBDIAG=ON ``` - -重新配置会刷新来源清单;打包脚本只按最新清单处理。反向切回 Layer 0 时, -即使构建目录残留旧的 `libubdiag.so`,也不会将其打入 RPM。 - -## 8. 验收标准 - -| 检查项 | Layer 0 | Layer 1 | -|--------|---------|---------| -| Mooncake 可正常编译和运行 | 必须 | 必须 | -| 目标程序链接 `libubdiag` | 否 | 是 | -| 生成 `ubdiag` CLI | 否 | 是 | -| `show` 返回 Mooncake PerfPoint 数据 | 不适用 | 必须 | -| P99/P999/P9999、PerfLog、CSV | 不适用 | 必须 | - -若启用模式下 CLI 无数据,应依次确认共享内存已启动、Mooncake 使用的是 -`build-ubdiag` 产物、运行时加载的是同目录 `libubdiag.so`,以及业务负载已 -实际经过 Mooncake PerfPoint 打点路径。 - -## 9. 常见问题 - -| 现象 | 原因与处理 | -|------|------------| -| L1 RPM 未执行 `ubdiag start` | Mooncake 可以运行,但不产生 UbDiag 采集数据;这不是 Layer 0 Mock | -| `ubdiag show` 表格为空 | 先确认 `status` 为 running,再运行实际 Mooncake 负载 | -| CLI 与 Mooncake 数据布局不一致 | 检查 CLI、动态库和 provenance 是否来自同一 RPM | -| 配置时报提交不一致 | 删除陈旧 `_deps/ubdiag-src`,或提供匹配完整 SHA 的洁净本地源码 | -| 打包时报 binary marker 不一致 | 重新执行 CMake 配置和构建,不要复用其他版本的 UbDiag 子构建目录 | -| RPM 中出现构建目录 RPATH | 使用当前打包脚本重新出包;最终 ELF 不应包含 `_deps/ubdiag-build` | From 362bbc87b4333d4dc2b6a097cf0c3bee5a1ee67e Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Thu, 30 Jul 2026 13:00:27 +0800 Subject: [PATCH 16/18] =?UTF-8?q?refactor:=20=E7=B2=BE=E7=AE=80UbDiag?= =?UTF-8?q?=E4=B8=A4=E5=B1=82=E9=9B=86=E6=88=90=E4=BF=9D=E6=8A=A4=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmake/RemoveRpath.cmake | 9 - mooncake-common/FindUbDiag.cmake | 443 ++++++------------------------ mooncake-p2p-store/build.sh | 21 +- mooncake-store/src/CMakeLists.txt | 2 +- scripts/build_rpm.sh | 418 +++++----------------------- 5 files changed, 161 insertions(+), 732 deletions(-) delete mode 100644 cmake/RemoveRpath.cmake diff --git a/cmake/RemoveRpath.cmake b/cmake/RemoveRpath.cmake deleted file mode 100644 index 04f82c8d95..0000000000 --- a/cmake/RemoveRpath.cmake +++ /dev/null @@ -1,9 +0,0 @@ -if(NOT DEFINED INPUT_FILE OR INPUT_FILE STREQUAL "") - message(FATAL_ERROR "INPUT_FILE is required") -endif() - -if(NOT EXISTS "${INPUT_FILE}") - message(FATAL_ERROR "ELF file does not exist: ${INPUT_FILE}") -endif() - -file(RPATH_REMOVE FILE "${INPUT_FILE}") diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index 078833071d..a99d6020cb 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -1,442 +1,175 @@ -# FindUbDiag.cmake - two-layer UbDiag integration for Mooncake +# Two-layer UbDiag integration for Mooncake. # -# Layer 0 (default): Fetch the pinned UbDiag source, expose its public headers, -# and propagate UBDIAG_DISABLE. PerfPoint calls compile to constexpr no-op -# functions. -# -# Layer 1: Consume a separately installed system UbDiag package. The package -# must provide a shared SDK, the ubdiag CLI, percentile support, and PerfLog. -# -# Usage: include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) -# target_link_libraries(your_target PRIVATE UbDiag::ubdiag_lib) -# -# Options: -DMOONCAKE_ENABLE_UBDIAG=OFF Layer 0 (default) -# -DMOONCAKE_ENABLE_UBDIAG=ON Layer 1 -# -# Layer 0 source selection: -DMOONCAKE_UBDIAG_GIT_TAG= -# -DMOONCAKE_UBDIAG_EXPECTED_COMMIT=<40-character SHA> -# -DMOONCAKE_UBDIAG_SOURCE_DIR=/path/to/ubdiag -# -# Layer 1 package selection: -DCMAKE_PREFIX_PATH=/path/to/ubdiag/prefix -# -DUbDiag_DIR=/path/to/lib64/cmake/UbDiag +# Layer 0 (default) uses the UbDiag public headers with UBDIAG_DISABLE. Layer 1 +# consumes a shared UbDiag SDK and CLI installed from system RPMs. -if(TARGET UbDiag::ubdiag_lib) - get_property(_MOONCAKE_UBDIAG_TARGET_OWNER GLOBAL - PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER) - if(NOT _MOONCAKE_UBDIAG_TARGET_OWNER STREQUAL "${CMAKE_BINARY_DIR}") - message( - FATAL_ERROR - "UbDiag::ubdiag_lib already exists but was not resolved by Mooncake. " - "Remove the injected target and let FindUbDiag.cmake select the active " - "Mooncake UbDiag layer.") - endif() - return() -endif() +include_guard(GLOBAL) option(MOONCAKE_ENABLE_UBDIAG - "Use a system-installed UbDiag shared library and CLI" OFF) + "Use the system-installed UbDiag shared library and CLI" OFF) -function(_mooncake_write_ubdiag_manifest layer) - set(_manifest "${CMAKE_BINARY_DIR}/mooncake_ubdiag.env") - file(WRITE "${_manifest}" "MOONCAKE_UBDIAG_LAYER=${layer}\n") +function(_mooncake_write_ubdiag_manifest layer library cli config) file( - APPEND "${_manifest}" - "MOONCAKE_UBDIAG_GIT_REPOSITORY=${MOONCAKE_UBDIAG_GIT_REPOSITORY}\n" - "MOONCAKE_UBDIAG_GIT_TAG=${MOONCAKE_UBDIAG_GIT_TAG}\n" - "MOONCAKE_UBDIAG_EXPECTED_COMMIT=${MOONCAKE_UBDIAG_EXPECTED_COMMIT}\n" - "MOONCAKE_UBDIAG_RESOLVED_COMMIT=${MOONCAKE_UBDIAG_RESOLVED_COMMIT}\n" - "MOONCAKE_UBDIAG_SOURCE_DIR=${MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR}\n" - "MOONCAKE_UBDIAG_PACKAGE_VERSION=${UbDiag_VERSION}\n" - "MOONCAKE_UBDIAG_PACKAGE_DIR=${UbDiag_DIR}\n" - "MOONCAKE_UBDIAG_SYSTEM_PREFIX=${MOONCAKE_UBDIAG_SYSTEM_PREFIX}\n" - "MOONCAKE_UBDIAG_SYSTEM_LIBRARY=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}\n" - "MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}\n" - "MOONCAKE_UBDIAG_SYSTEM_CLI=${MOONCAKE_UBDIAG_SYSTEM_CLI}\n" - "MOONCAKE_UBDIAG_SYSTEM_CLI_RPM=${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}\n" - "MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH=${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}\n" - "MOONCAKE_UBDIAG_SYSTEM_CONFIG=${MOONCAKE_UBDIAG_SYSTEM_CONFIG}\n") - set(MOONCAKE_UBDIAG_MANIFEST - "${_manifest}" - CACHE FILEPATH "Resolved Mooncake UbDiag integration manifest" FORCE) + WRITE "${CMAKE_BINARY_DIR}/mooncake_ubdiag.env" + "MOONCAKE_UBDIAG_LAYER=${layer}\n" + "MOONCAKE_UBDIAG_SYSTEM_LIBRARY=${library}\n" + "MOONCAKE_UBDIAG_SYSTEM_CLI=${cli}\n" + "MOONCAKE_UBDIAG_SYSTEM_CONFIG=${config}\n") set(MOONCAKE_UBDIAG_ACTIVE_LAYER "${layer}" - CACHE STRING "Active UbDiag integration layer: mock or system" FORCE) + CACHE INTERNAL "Active Mooncake UbDiag layer" FORCE) endfunction() if(NOT MOONCAKE_ENABLE_UBDIAG) set(MOONCAKE_UBDIAG_GIT_REPOSITORY "https://github.com/LinQuickDev/ubdiag.git" - CACHE STRING "UbDiag Git repository used by Layer 0") + CACHE STRING "UbDiag repository used by Layer 0") set(MOONCAKE_UBDIAG_GIT_TAG "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" - CACHE STRING "UbDiag ref used by Layer 0") - set(MOONCAKE_UBDIAG_EXPECTED_COMMIT - "8df2c2844d402e2e4dcd5ceab2424e8d36c5f99f" - CACHE STRING "Allowed full UbDiag commit SHA used by Layer 0") + CACHE STRING "UbDiag revision used by Layer 0") set(MOONCAKE_UBDIAG_SOURCE_DIR "" - CACHE PATH "Local UbDiag source for offline Layer 0 configuration") + CACHE PATH "Local UbDiag source directory for offline builds") include(FetchContent) - - function(_mooncake_verify_ubdiag_source source_dir) - get_filename_component(_source_dir "${source_dir}" REALPATH) - string(TOLOWER "${MOONCAKE_UBDIAG_EXPECTED_COMMIT}" _expected_commit) - string(LENGTH "${_expected_commit}" _expected_commit_length) - if(NOT _expected_commit_length EQUAL 40 OR NOT _expected_commit MATCHES - "^[0-9a-f]+$") - message( - FATAL_ERROR - "MOONCAKE_UBDIAG_EXPECTED_COMMIT must be a full 40-character Git " - "SHA, got: ${MOONCAKE_UBDIAG_EXPECTED_COMMIT}") - endif() - - find_program(_MOONCAKE_UBDIAG_GIT_EXECUTABLE NAMES git) - if(NOT _MOONCAKE_UBDIAG_GIT_EXECUTABLE OR NOT EXISTS - "${_source_dir}/CMakeLists.txt") - message( - FATAL_ERROR - "UbDiag source is incomplete or git is unavailable: ${_source_dir}") - endif() - - execute_process( - COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" rev-parse - --verify HEAD - RESULT_VARIABLE _git_result - OUTPUT_VARIABLE _resolved_commit - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(TOLOWER "${_resolved_commit}" _resolved_commit) - if(NOT _git_result EQUAL 0 OR NOT _resolved_commit STREQUAL - _expected_commit) - message( - FATAL_ERROR - "UbDiag source commit mismatch.\n" - " expected: ${_expected_commit}\n" - " resolved: ${_resolved_commit}\n" - " source: ${_source_dir}\n" - "Remove the stale _deps/ubdiag-src directory or select the matching " - "MOONCAKE_UBDIAG_EXPECTED_COMMIT.") - endif() - - execute_process( - COMMAND "${_MOONCAKE_UBDIAG_GIT_EXECUTABLE}" -C "${_source_dir}" status - --porcelain --untracked-files=all - RESULT_VARIABLE _git_result - OUTPUT_VARIABLE _git_status - OUTPUT_STRIP_TRAILING_WHITESPACE) - if(NOT _git_result EQUAL 0 OR NOT _git_status STREQUAL "") - message( - FATAL_ERROR - "UbDiag source worktree is not clean, so its HEAD SHA does not fully " - "describe the headers that would be used:\n${_git_status}") - endif() - - set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR - "${_source_dir}" - CACHE PATH "Verified UbDiag source selected by Mooncake" FORCE) - set(MOONCAKE_UBDIAG_RESOLVED_COMMIT - "${_resolved_commit}" - CACHE STRING "Verified UbDiag source commit selected by Mooncake" FORCE) - set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR - "${_source_dir}" - PARENT_SCOPE) - set(MOONCAKE_UBDIAG_RESOLVED_COMMIT - "${_resolved_commit}" - PARENT_SCOPE) - endfunction() - if(MOONCAKE_UBDIAG_SOURCE_DIR) - if(NOT EXISTS "${MOONCAKE_UBDIAG_SOURCE_DIR}/CMakeLists.txt") - message( - FATAL_ERROR - "MOONCAKE_UBDIAG_SOURCE_DIR does not contain CMakeLists.txt: " - "${MOONCAKE_UBDIAG_SOURCE_DIR}") - endif() set(ubdiag_SOURCE_DIR "${MOONCAKE_UBDIAG_SOURCE_DIR}") else() FetchContent_Populate( ubdiag GIT_REPOSITORY "${MOONCAKE_UBDIAG_GIT_REPOSITORY}" - GIT_TAG "${MOONCAKE_UBDIAG_GIT_TAG}" - SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-src" - SUBBUILD_DIR "${FETCHCONTENT_BASE_DIR}/ubdiag-subbuild") - endif() - _mooncake_verify_ubdiag_source("${ubdiag_SOURCE_DIR}") - - set(_MOONCAKE_UBDIAG_PERF_POINT_HEADER - "${ubdiag_SOURCE_DIR}/include/ubdiag/perf_point.h") - if(NOT EXISTS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}") - message(FATAL_ERROR "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} is missing " - "include/ubdiag/perf_point.h") - endif() - file(STRINGS "${_MOONCAKE_UBDIAG_PERF_POINT_HEADER}" - _MOONCAKE_UBDIAG_DISABLE_LINES REGEX "UBDIAG_DISABLE") - if(NOT _MOONCAKE_UBDIAG_DISABLE_LINES) - message( - FATAL_ERROR "UbDiag ${MOONCAKE_UBDIAG_GIT_TAG} does not provide the " - "UBDIAG_DISABLE PerfPoint implementation required by Layer 0." - ) + GIT_TAG "${MOONCAKE_UBDIAG_GIT_TAG}") endif() - add_library(ubdiag_mock INTERFACE) - target_include_directories(ubdiag_mock + add_library(mooncake_ubdiag_mock INTERFACE) + target_include_directories(mooncake_ubdiag_mock INTERFACE "${ubdiag_SOURCE_DIR}/include") - target_compile_definitions(ubdiag_mock INTERFACE UBDIAG_DISABLE) - add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock) + target_compile_definitions(mooncake_ubdiag_mock INTERFACE UBDIAG_DISABLE) + add_library(UbDiag::ubdiag_lib ALIAS mooncake_ubdiag_mock) - set(MOONCAKE_UBDIAG_SYSTEM_PREFIX "") - set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY "") - set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM "") - set(MOONCAKE_UBDIAG_SYSTEM_CLI "") - set(MOONCAKE_UBDIAG_SYSTEM_CLI_RPM "") - set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH "") - set(MOONCAKE_UBDIAG_SYSTEM_CONFIG "") - set(MOONCAKE_UBDIAG_LIBRARY_DIR "") - set(UbDiag_VERSION "") - set(UbDiag_DIR "") - set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER - "${CMAKE_BINARY_DIR}") - _mooncake_write_ubdiag_manifest("mock") - message(STATUS "UbDiag: Layer 0 UBDIAG_DISABLE headers, verified " - "${MOONCAKE_UBDIAG_RESOLVED_COMMIT}") + set(MOONCAKE_UBDIAG_LIBRARY_DIR + "" + CACHE INTERNAL "System UbDiag library directory" FORCE) + _mooncake_write_ubdiag_manifest("mock" "" "" "") + message(STATUS "UbDiag: Layer 0 UBDIAG_DISABLE headers") return() endif() -# Layer 1 must be fully supplied by one system UbDiag RPM installation. find_package(UbDiag CONFIG QUIET) -if(NOT UbDiag_FOUND) +if(NOT UbDiag_FOUND OR NOT TARGET UbDiag::ubdiag_lib) message( FATAL_ERROR - "MOONCAKE_ENABLE_UBDIAG=ON requires a system-installed UbDiag " - "shared SDK and CLI.\n" - "Install the UbDiag RPM separately (or build an UbDiag RPM with " - "UBDIAG_BUILD_SHARED=ON, ENABLE_PERCENTILE=ON, and ENABLE_PERFLOG=ON), " - "then install that RPM before configuring Mooncake.\n" - "Mooncake does not download or build the real UbDiag runtime in Layer 1. " - "Use CMAKE_PREFIX_PATH or UbDiag_DIR when it is installed under a " - "non-standard system prefix.") -endif() -if(NOT TARGET UbDiag::ubdiag_lib) - message( - FATAL_ERROR - "The system UbDiag package was found at ${UbDiag_DIR}, but it does not " - "export the required UbDiag::ubdiag_lib target. Reinstall the complete " - "UbDiag development RPM.") + "MOONCAKE_ENABLE_UBDIAG=ON requires the UbDiag runtime and development " + "RPMs. Install the RPMs that provide libubdiag.so, the ubdiag CLI, and " + "UbDiagConfig.cmake before configuring Mooncake.") endif() -get_target_property(_MOONCAKE_UBDIAG_IMPORTED UbDiag::ubdiag_lib IMPORTED) get_target_property(_MOONCAKE_UBDIAG_TARGET_TYPE UbDiag::ubdiag_lib TYPE) -if(NOT _MOONCAKE_UBDIAG_IMPORTED OR NOT _MOONCAKE_UBDIAG_TARGET_TYPE STREQUAL - "SHARED_LIBRARY") +if(NOT _MOONCAKE_UBDIAG_TARGET_TYPE STREQUAL "SHARED_LIBRARY") message( - FATAL_ERROR - "MOONCAKE_ENABLE_UBDIAG=ON requires the system shared SDK " - "libubdiag.so; ${UbDiag_DIR} exported target type " - "'${_MOONCAKE_UBDIAG_TARGET_TYPE}'. Rebuild and reinstall the UbDiag RPM " - "with UBDIAG_BUILD_SHARED=ON.") + FATAL_ERROR "MOONCAKE_ENABLE_UBDIAG=ON requires a shared libubdiag.so. " + "Reinstall UbDiag with UBDIAG_BUILD_SHARED=ON.") endif() function(_mooncake_get_imported_location target output_variable) - get_target_property(_imported_configs "${target}" IMPORTED_CONFIGURATIONS) - foreach(_config IN LISTS _imported_configs) + get_target_property(_configs "${target}" IMPORTED_CONFIGURATIONS) + foreach(_config IN LISTS _configs) string(TOUPPER "${_config}" _config_upper) - get_target_property(_candidate "${target}" + get_target_property(_location "${target}" "IMPORTED_LOCATION_${_config_upper}") - if(_candidate AND NOT _candidate MATCHES "-NOTFOUND$") + if(_location) set("${output_variable}" - "${_candidate}" + "${_location}" PARENT_SCOPE) return() endif() endforeach() - get_target_property(_candidate "${target}" IMPORTED_LOCATION) - if(_candidate AND NOT _candidate MATCHES "-NOTFOUND$") - set("${output_variable}" - "${_candidate}" - PARENT_SCOPE) - endif() + + get_target_property(_location "${target}" IMPORTED_LOCATION) + set("${output_variable}" + "${_location}" + PARENT_SCOPE) endfunction() _mooncake_get_imported_location(UbDiag::ubdiag_lib - _MOONCAKE_UBDIAG_IMPORTED_LOCATION) -if(NOT _MOONCAKE_UBDIAG_IMPORTED_LOCATION - OR NOT EXISTS "${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}") - message( - FATAL_ERROR - "The system UbDiag target does not resolve to an installed shared " - "library: ${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}") + MOONCAKE_UBDIAG_SYSTEM_LIBRARY) +if(NOT MOONCAKE_UBDIAG_SYSTEM_LIBRARY) + message(FATAL_ERROR "The installed UbDiag package does not expose its " + "shared-library location.") endif() get_filename_component(MOONCAKE_UBDIAG_SYSTEM_LIBRARY - "${_MOONCAKE_UBDIAG_IMPORTED_LOCATION}" REALPATH) + "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" REALPATH) get_filename_component(MOONCAKE_UBDIAG_LIBRARY_DIR "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" DIRECTORY) -get_filename_component(_MOONCAKE_UBDIAG_LIBRARY_NAME - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" NAME) -if(NOT _MOONCAKE_UBDIAG_LIBRARY_NAME MATCHES "^libubdiag\\.so(\\..*)?$") - message( - FATAL_ERROR "The system UbDiag target resolved to an unexpected library: " - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}") -endif() -get_target_property(_MOONCAKE_UBDIAG_COMPILE_DEFINITIONS UbDiag::ubdiag_lib +get_target_property(_MOONCAKE_UBDIAG_DEFINITIONS UbDiag::ubdiag_lib INTERFACE_COMPILE_DEFINITIONS) -foreach(_required_definition UBDIAG_ENABLE_PERCENTILE UBDIAG_ENABLE_PERFLOG) - list(FIND _MOONCAKE_UBDIAG_COMPILE_DEFINITIONS "${_required_definition}" - _definition_index) - if(_definition_index EQUAL -1) +foreach(_definition UBDIAG_ENABLE_PERCENTILE UBDIAG_ENABLE_PERFLOG) + if(NOT _definition IN_LIST _MOONCAKE_UBDIAG_DEFINITIONS) message( FATAL_ERROR - "The system UbDiag package does not advertise " - "${_required_definition}. Rebuild and reinstall the UbDiag RPM with " - "ENABLE_PERCENTILE=ON and ENABLE_PERFLOG=ON.") + "The installed UbDiag package does not provide ${_definition}. " + "Rebuild and reinstall the UbDiag RPM with percentile and PerfLog " + "enabled.") endif() endforeach() -get_filename_component(_MOONCAKE_UBDIAG_LIBDIR_NAME - "${MOONCAKE_UBDIAG_LIBRARY_DIR}" NAME) -if(_MOONCAKE_UBDIAG_LIBDIR_NAME MATCHES "^lib(64)?$") - get_filename_component(MOONCAKE_UBDIAG_SYSTEM_PREFIX - "${MOONCAKE_UBDIAG_LIBRARY_DIR}" DIRECTORY) -else() - get_filename_component(_MOONCAKE_UBDIAG_CMAKE_DIR_PARENT "${UbDiag_DIR}" - DIRECTORY) - get_filename_component(_MOONCAKE_UBDIAG_PACKAGE_LIBDIR - "${_MOONCAKE_UBDIAG_CMAKE_DIR_PARENT}" DIRECTORY) - get_filename_component(MOONCAKE_UBDIAG_SYSTEM_PREFIX - "${_MOONCAKE_UBDIAG_PACKAGE_LIBDIR}" DIRECTORY) -endif() - -unset(_MOONCAKE_UBDIAG_CLI CACHE) -find_program( - _MOONCAKE_UBDIAG_CLI - NAMES ubdiag - PATHS "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin" - NO_DEFAULT_PATH) -if(NOT _MOONCAKE_UBDIAG_CLI) +find_program(MOONCAKE_UBDIAG_SYSTEM_CLI NAMES ubdiag) +if(NOT MOONCAKE_UBDIAG_SYSTEM_CLI) message( - FATAL_ERROR - "The system UbDiag shared SDK was found at " - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}, but the matching ubdiag CLI was not " - "found at ${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin/ubdiag. Install the " - "complete UbDiag RPM before configuring Mooncake.") + FATAL_ERROR "The UbDiag SDK was found, but the ubdiag CLI is missing. " + "Install the matching UbDiag runtime RPM.") endif() -get_filename_component(MOONCAKE_UBDIAG_SYSTEM_CLI "${_MOONCAKE_UBDIAG_CLI}" - REALPATH) -find_program(_MOONCAKE_UBDIAG_RPM_EXECUTABLE NAMES rpm) -if(NOT _MOONCAKE_UBDIAG_RPM_EXECUTABLE) - message( - FATAL_ERROR - "MOONCAKE_ENABLE_UBDIAG=ON requires the rpm command to verify that the " - "system libubdiag.so and ubdiag CLI belong to matching UbDiag RPMs.") +find_program(_MOONCAKE_RPM_EXECUTABLE NAMES rpm) +if(NOT _MOONCAKE_RPM_EXECUTABLE) + message(FATAL_ERROR "The rpm command is required to compare the UbDiag " + "library and CLI versions.") endif() -function(_mooncake_query_ubdiag_rpm file_path owner_output identity_output) +function(_mooncake_get_rpm_identity file_path output_variable) execute_process( - COMMAND "${_MOONCAKE_UBDIAG_RPM_EXECUTABLE}" -qf --qf - "%{NAME}|%{VERSION}-%{RELEASE}.%{ARCH}" "${file_path}" - RESULT_VARIABLE _rpm_result - OUTPUT_VARIABLE _rpm_record - ERROR_VARIABLE _rpm_error + COMMAND "${_MOONCAKE_RPM_EXECUTABLE}" -qf --qf + "%{VERSION}-%{RELEASE}.%{ARCH}" "${file_path}" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _identity + ERROR_VARIABLE _error OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE) - if(NOT _rpm_result EQUAL 0 OR NOT _rpm_record MATCHES "^([^|]+)\\|(.+)$") - message( - FATAL_ERROR - "${file_path} is not owned by an installed RPM package. " - "Install the complete UbDiag RPM before configuring Mooncake.\n" - "rpm -qf: ${_rpm_error}") - endif() - set(_rpm_owner "${CMAKE_MATCH_1}") - set(_rpm_identity "${CMAKE_MATCH_2}") - string(TOLOWER "${_rpm_owner}" _rpm_owner_lower) - if(NOT _rpm_owner_lower MATCHES "ubdiag") - message( - FATAL_ERROR - "${file_path} is owned by '${_rpm_owner}', not an UbDiag RPM package.") + if(NOT _result EQUAL 0) + message(FATAL_ERROR "${file_path} is not provided by an installed RPM: " + "${_error}") endif() - set("${owner_output}" - "${_rpm_owner}" - PARENT_SCOPE) - set("${identity_output}" - "${_rpm_identity}" + set("${output_variable}" + "${_identity}" PARENT_SCOPE) endfunction() -_mooncake_query_ubdiag_rpm( - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM - _MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY) -_mooncake_query_ubdiag_rpm( - "${MOONCAKE_UBDIAG_SYSTEM_CLI}" MOONCAKE_UBDIAG_SYSTEM_CLI_RPM - _MOONCAKE_UBDIAG_CLI_RPM_IDENTITY) -if(NOT _MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY STREQUAL - _MOONCAKE_UBDIAG_CLI_RPM_IDENTITY) +_mooncake_get_rpm_identity("${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" + _MOONCAKE_UBDIAG_LIBRARY_IDENTITY) +_mooncake_get_rpm_identity("${MOONCAKE_UBDIAG_SYSTEM_CLI}" + _MOONCAKE_UBDIAG_CLI_IDENTITY) +if(NOT "${_MOONCAKE_UBDIAG_LIBRARY_IDENTITY}" STREQUAL + "${_MOONCAKE_UBDIAG_CLI_IDENTITY}") message( FATAL_ERROR - "The system libubdiag.so and ubdiag CLI come from different RPM " - "versions.\n" - " library: ${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM} " - "${_MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY}\n" - " CLI: ${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM} " - "${_MOONCAKE_UBDIAG_CLI_RPM_IDENTITY}\n" - "Reinstall one complete, matching UbDiag RPM set.") + "libubdiag.so and the ubdiag CLI come from different RPM versions: " + "${_MOONCAKE_UBDIAG_LIBRARY_IDENTITY} and " + "${_MOONCAKE_UBDIAG_CLI_IDENTITY}. Install one matching UbDiag RPM set.") endif() -set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH - "${_MOONCAKE_UBDIAG_LIBRARY_RPM_IDENTITY}") -unset(_MOONCAKE_UBDIAG_CONFIG CACHE) -set(_MOONCAKE_UBDIAG_CONFIG_PATHS "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}/etc/ubdiag") -if(MOONCAKE_UBDIAG_SYSTEM_PREFIX STREQUAL "/usr") - list(APPEND _MOONCAKE_UBDIAG_CONFIG_PATHS "/etc/ubdiag") -endif() -find_file( - _MOONCAKE_UBDIAG_CONFIG - NAMES ubdiag.conf - PATHS ${_MOONCAKE_UBDIAG_CONFIG_PATHS} - NO_DEFAULT_PATH) -if(_MOONCAKE_UBDIAG_CONFIG) - get_filename_component(MOONCAKE_UBDIAG_SYSTEM_CONFIG - "${_MOONCAKE_UBDIAG_CONFIG}" REALPATH) +if(EXISTS "/etc/ubdiag/ubdiag.conf") + set(MOONCAKE_UBDIAG_SYSTEM_CONFIG "/etc/ubdiag/ubdiag.conf") else() set(MOONCAKE_UBDIAG_SYSTEM_CONFIG "") endif() -set(MOONCAKE_UBDIAG_SYSTEM_PREFIX - "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}" - CACHE PATH "System UbDiag installation prefix selected by Mooncake" FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" - CACHE FILEPATH "System libubdiag.so selected by Mooncake" FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}" - CACHE STRING - "RPM package owning the system libubdiag.so selected by Mooncake" - FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_CLI - "${MOONCAKE_UBDIAG_SYSTEM_CLI}" - CACHE FILEPATH "System ubdiag CLI selected by Mooncake" FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_CLI_RPM - "${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}" - CACHE STRING - "RPM package owning the system ubdiag CLI selected by Mooncake" FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH - "${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" - CACHE STRING - "Matching system UbDiag RPM version-release.arch selected by Mooncake" - FORCE) -set(MOONCAKE_UBDIAG_SYSTEM_CONFIG - "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" - CACHE FILEPATH "System UbDiag configuration selected by Mooncake" FORCE) set(MOONCAKE_UBDIAG_LIBRARY_DIR "${MOONCAKE_UBDIAG_LIBRARY_DIR}" - CACHE PATH "System UbDiag library directory selected by Mooncake" FORCE) -set(MOONCAKE_UBDIAG_GIT_REPOSITORY "") -set(MOONCAKE_UBDIAG_GIT_TAG "") -set(MOONCAKE_UBDIAG_EXPECTED_COMMIT "") -set(MOONCAKE_UBDIAG_RESOLVED_COMMIT "") -set(MOONCAKE_UBDIAG_RESOLVED_SOURCE_DIR "") -set_property(GLOBAL PROPERTY MOONCAKE_UBDIAG_TARGET_OWNER "${CMAKE_BINARY_DIR}") -_mooncake_write_ubdiag_manifest("system") + CACHE INTERNAL "System UbDiag library directory" FORCE) +_mooncake_write_ubdiag_manifest( + "system" "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" "${MOONCAKE_UBDIAG_SYSTEM_CLI}" + "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}") message( - STATUS "UbDiag: Layer 1 system RPM ${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}; " + STATUS "UbDiag: Layer 1 system RPM ${_MOONCAKE_UBDIAG_LIBRARY_IDENTITY}; " "library=${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}; " "CLI=${MOONCAKE_UBDIAG_SYSTEM_CLI}") diff --git a/mooncake-p2p-store/build.sh b/mooncake-p2p-store/build.sh index 75354bbef6..081cf385cd 100644 --- a/mooncake-p2p-store/build.sh +++ b/mooncake-p2p-store/build.sh @@ -39,24 +39,9 @@ EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common" EXT_LDFLAGS+=" -L$BUILD_DIR/mooncake-common/src" EXT_LDFLAGS+=" -ltransfer_engine -lbase -lasio -lstdc++ -lnuma -lglog -libverbs -lmlx5 -ljsoncpp -lmooncake_common -lm" -# UbDiag link contract: mock has no runtime library; system uses the -# separately installed library selected by FindUbDiag.cmake. -case "$UBDIAG_LAYER" in - system) - if [ -z "$UBDIAG_LIB_DIR" ] || [ ! -d "$UBDIAG_LIB_DIR" ]; then - echo "P2P Store: invalid system UbDiag library directory: $UBDIAG_LIB_DIR" >&2 - exit 1 - fi - EXT_LDFLAGS+=" -L$UBDIAG_LIB_DIR -lubdiag" - ;; - mock) - echo "P2P Store: UBDIAG_DISABLE mode, skipping -lubdiag" - ;; - *) - echo "P2P Store: unknown UbDiag layer: $UBDIAG_LAYER" >&2 - exit 1 - ;; -esac +if [ "$UBDIAG_LAYER" = "system" ]; then + EXT_LDFLAGS+=" -L$UBDIAG_LIB_DIR -lubdiag" +fi if [ -d "/usr/local/cuda/lib64/stubs" ]; then EXT_LDFLAGS+=" -L/usr/local/cuda/lib64/stubs" diff --git a/mooncake-store/src/CMakeLists.txt b/mooncake-store/src/CMakeLists.txt index 615c52dc15..f541551d74 100644 --- a/mooncake-store/src/CMakeLists.txt +++ b/mooncake-store/src/CMakeLists.txt @@ -250,7 +250,7 @@ target_link_libraries( ${EXTRA_LIBS} ${SPDK_STATIC_LIBS} asio_shared mooncake_common PRIVATE transfer_engine) -# UbDiag instrumentation (compile-time mock or system package) +# UbDiag instrumentation include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake) target_link_libraries(mooncake_store PRIVATE UbDiag::ubdiag_lib) target_include_directories(mooncake_store PRIVATE diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh index 8d7233c8ae..85f05826ca 100755 --- a/scripts/build_rpm.sh +++ b/scripts/build_rpm.sh @@ -5,12 +5,9 @@ # Example: ./scripts/build_rpm.sh build rpm-output aarch64 # Example: ./scripts/build_rpm.sh build rpm-output all (build both platforms) -set -euo pipefail +set -e # Exit immediately if a command exits with a non-zero status set -x -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -MOONCAKE_SOURCE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" - # Get build directory from environment variable or argument BUILD_DIR="${BUILD_DIR:-${1:-build}}" if [[ "${BUILD_DIR}" = /* ]]; then @@ -49,143 +46,12 @@ echo "Target platform: ${TARGET_PLATFORM}" echo "Host architecture: ${HOST_ARCH}" # Ensure LD_LIBRARY_PATH includes build directories -export LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:${BUILD_DIR_ABS}/mooncake-common:/usr/local/lib" +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${BUILD_DIR_ABS}/mooncake-common:/usr/local/lib # Clean previous build echo "Cleaning previous RPM build..." rm -rf rpmbuild/ -rm -rf "${OUTPUT_DIR}/" - -fail_ubdiag_packaging() { - echo "Error: UbDiag RPM packaging check failed: $*" >&2 - return 1 -} - -remove_staged_rpath() { - local staged_elf="$1" - - if readelf -d "${staged_elf}" 2>/dev/null | - grep -Eq '\((RPATH|RUNPATH)\)'; then - cmake -DINPUT_FILE="${staged_elf}" \ - -P "${MOONCAKE_SOURCE_DIR}/cmake/RemoveRpath.cmake" - fi - if readelf -d "${staged_elf}" 2>/dev/null | - grep -Eq '\((RPATH|RUNPATH)\)'; then - fail_ubdiag_packaging \ - "staged ELF still contains RPATH/RUNPATH: ${staged_elf}" - return 1 - fi -} - -load_ubdiag_manifest() { - local manifest="$1" - local key="" - local value="" - - if [ ! -f "${manifest}" ]; then - fail_ubdiag_packaging "manifest not found: ${manifest}" - return 1 - fi - - while IFS='=' read -r key value || [ -n "${key}" ]; do - value="${value%$'\r'}" - case "${key}" in - MOONCAKE_UBDIAG_LAYER|MOONCAKE_UBDIAG_GIT_REPOSITORY|\ - MOONCAKE_UBDIAG_GIT_TAG|MOONCAKE_UBDIAG_EXPECTED_COMMIT|\ - MOONCAKE_UBDIAG_RESOLVED_COMMIT|MOONCAKE_UBDIAG_SOURCE_DIR|\ - MOONCAKE_UBDIAG_PACKAGE_VERSION|MOONCAKE_UBDIAG_PACKAGE_DIR|\ - MOONCAKE_UBDIAG_SYSTEM_PREFIX|MOONCAKE_UBDIAG_SYSTEM_LIBRARY|\ - MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM|MOONCAKE_UBDIAG_SYSTEM_CLI|\ - MOONCAKE_UBDIAG_SYSTEM_CLI_RPM|\ - MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH|\ - MOONCAKE_UBDIAG_SYSTEM_CONFIG) - printf -v "${key}" '%s' "${value}" - ;; - "") - ;; - *) - fail_ubdiag_packaging \ - "unknown key '${key}' in ${manifest}" - return 1 - ;; - esac - done < "${manifest}" -} - -query_rpm_file_owner() { - local file_path="$1" - rpm -qf --qf '%{NAME}|%{VERSION}-%{RELEASE}.%{ARCH}' "${file_path}" -} - -verify_system_ubdiag_inputs() { - local library_record="" - local cli_record="" - local library_owner="" - local cli_owner="" - local library_identity="" - local cli_identity="" - - for required_tool in cmake readelf readlink rpm; do - if ! command -v "${required_tool}" >/dev/null 2>&1; then - fail_ubdiag_packaging \ - "required tool is unavailable: ${required_tool}" - return 1 - fi - done - if [ ! -f "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" ] || - [ ! -x "${MOONCAKE_UBDIAG_SYSTEM_CLI}" ]; then - fail_ubdiag_packaging \ - "configured system UbDiag library or CLI is unavailable" - return 1 - fi - - MOONCAKE_UBDIAG_SYSTEM_LIBRARY="$( - readlink -f "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" - )" - MOONCAKE_UBDIAG_SYSTEM_CLI="$( - readlink -f "${MOONCAKE_UBDIAG_SYSTEM_CLI}" - )" - case "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" in - "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/lib/libubdiag.so*|\ - "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/lib64/libubdiag.so*) - ;; - *) - fail_ubdiag_packaging \ - "libubdiag.so is outside the configured system prefix" - return 1 - ;; - esac - case "${MOONCAKE_UBDIAG_SYSTEM_CLI}" in - "${MOONCAKE_UBDIAG_SYSTEM_PREFIX}"/bin/ubdiag) - ;; - *) - fail_ubdiag_packaging \ - "ubdiag CLI is outside the configured system prefix" - return 1 - ;; - esac - - library_record="$(query_rpm_file_owner \ - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" - cli_record="$(query_rpm_file_owner "${MOONCAKE_UBDIAG_SYSTEM_CLI}")" - IFS='|' read -r library_owner library_identity <<< "${library_record}" - IFS='|' read -r cli_owner cli_identity <<< "${cli_record}" - if [[ "${library_owner,,}" != *ubdiag* ]] || - [[ "${cli_owner,,}" != *ubdiag* ]]; then - fail_ubdiag_packaging \ - "library or CLI is not owned by an UbDiag RPM" - return 1 - fi - if [ "${library_identity}" != "${cli_identity}" ] || - [ "${library_identity}" != \ - "${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" ] || - [ "${library_owner}" != "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM}" ] || - [ "${cli_owner}" != "${MOONCAKE_UBDIAG_SYSTEM_CLI_RPM}" ]; then - fail_ubdiag_packaging \ - "system UbDiag RPM changed after CMake configure: library=${library_record}, CLI=${cli_record}, configured=${MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH}" - return 1 - fi -} +rm -rf ${OUTPUT_DIR}/ # Function to build RPM for a specific platform build_rpm_for_platform() { @@ -194,23 +60,12 @@ build_rpm_for_platform() { local BUILDROOT="" local UBDIAG_CONFIG_RPM_FILE="" local MOONCAKE_UBDIAG_LAYER="" - local MOONCAKE_UBDIAG_GIT_REPOSITORY="" - local MOONCAKE_UBDIAG_GIT_TAG="" - local MOONCAKE_UBDIAG_EXPECTED_COMMIT="" - local MOONCAKE_UBDIAG_RESOLVED_COMMIT="" - local MOONCAKE_UBDIAG_SOURCE_DIR="" - local MOONCAKE_UBDIAG_PACKAGE_VERSION="" - local MOONCAKE_UBDIAG_PACKAGE_DIR="" - local MOONCAKE_UBDIAG_SYSTEM_PREFIX="" local MOONCAKE_UBDIAG_SYSTEM_LIBRARY="" - local MOONCAKE_UBDIAG_SYSTEM_LIBRARY_RPM="" local MOONCAKE_UBDIAG_SYSTEM_CLI="" - local MOONCAKE_UBDIAG_SYSTEM_CLI_RPM="" - local MOONCAKE_UBDIAG_SYSTEM_RPM_EVR_ARCH="" local MOONCAKE_UBDIAG_SYSTEM_CONFIG="" - + echo "Building RPM for platform: ${PLATFORM}" - + # Determine lib directory based on platform if [ "${PLATFORM}" = "aarch64" ]; then LIB_DIR="lib64" # ARM64 also uses lib64 on most distros @@ -220,21 +75,20 @@ build_rpm_for_platform() { echo "Error: Unsupported platform ${PLATFORM}" return 1 fi - + # Create RPM build directory structure for this platform mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} BUILDROOT="rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}" mkdir -p "${BUILDROOT}" - + # Create target directories in BUILDROOT - mkdir -p "${BUILDROOT}/usr/bin" "${BUILDROOT}/usr/${LIB_DIR}" \ - "${BUILDROOT}/usr/include" "${BUILDROOT}/etc/mooncake" - + mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/{usr/{bin,${LIB_DIR},include},etc/mooncake} + # ------------------------------------------------------------------------- # Copy executables # ------------------------------------------------------------------------- echo "Copying executables..." - + # Determine build subdirectory based on platform local PLATFORM_BUILD_DIR="${BUILD_DIR_ABS}" if [ "${PLATFORM}" != "${HOST_ARCH}" ]; then @@ -243,22 +97,16 @@ build_rpm_for_platform() { echo "Cross-compilation detected, looking in ${PLATFORM_BUILD_DIR}" fi - local UBDIAG_MANIFEST="${PLATFORM_BUILD_DIR}/mooncake_ubdiag.env" - echo "Reading Mooncake UbDiag manifest: ${UBDIAG_MANIFEST}" - load_ubdiag_manifest "${UBDIAG_MANIFEST}" + source "${PLATFORM_BUILD_DIR}/mooncake_ubdiag.env" case "${MOONCAKE_UBDIAG_LAYER}" in - mock) - ;; - system) - verify_system_ubdiag_inputs + mock|system) ;; *) - fail_ubdiag_packaging \ - "unsupported layer '${MOONCAKE_UBDIAG_LAYER:-unset}'" + echo "Error: Unknown Mooncake UbDiag layer: ${MOONCAKE_UBDIAG_LAYER}" return 1 ;; esac - + # mooncake_master if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_master rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -266,7 +114,7 @@ build_rpm_for_platform() { else echo "Warning: mooncake_master not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # mooncake_client if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_client ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/mooncake_client rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -274,7 +122,7 @@ build_rpm_for_platform() { else echo "Warning: mooncake_client not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # stress_cluster_bench if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/benchmarks/stress_cluster_bench ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/benchmarks/stress_cluster_bench rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -282,7 +130,7 @@ build_rpm_for_platform() { else echo "Warning: stress_cluster_bench not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # transfer_engine_bench if [ -f ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/example/transfer_engine_bench ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/example/transfer_engine_bench rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ @@ -290,40 +138,40 @@ build_rpm_for_platform() { else echo "Warning: transfer_engine_bench not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # ------------------------------------------------------------------------- # Copy libraries # ------------------------------------------------------------------------- echo "Copying shared libraries..." - + # libmooncake_store.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-store/src/libmooncake_store.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-store/src/libmooncake_store.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libmooncake_store.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libtransfer_engine.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/src/libtransfer_engine.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-transfer-engine/src/libtransfer_engine.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libtransfer_engine.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libasio.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/libasio.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/libasio.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libasio.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libetcd_wrapper.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/etcd/libetcd_wrapper.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/etcd/libetcd_wrapper.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ else echo "Warning: libetcd_wrapper.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # libmooncake_common.so if [ -f ${PLATFORM_BUILD_DIR}/mooncake-common/libmooncake_common.so ]; then cp ${PLATFORM_BUILD_DIR}/mooncake-common/libmooncake_common.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/ @@ -332,14 +180,14 @@ build_rpm_for_platform() { else echo "Warning: libmooncake_common.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # engine.so (Python binding) if compgen -G "${PLATFORM_BUILD_DIR}/mooncake-integration/engine.*.so" >/dev/null; then cp ${PLATFORM_BUILD_DIR}/mooncake-integration/engine.*.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libmooncake_engine.so else echo "Warning: engine.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - + # store.so (Python binding) if compgen -G "${PLATFORM_BUILD_DIR}/mooncake-integration/store.*.so" >/dev/null; then cp ${PLATFORM_BUILD_DIR}/mooncake-integration/store.*.so rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libmooncake_store_python.so @@ -347,57 +195,35 @@ build_rpm_for_platform() { echo "Warning: store.so not found in ${PLATFORM_BUILD_DIR}, skipping..." fi - # ------------------------------------------------------------------------- - # Stage the matching system UbDiag RPM payload for Layer 1 - # ------------------------------------------------------------------------- if [ "${MOONCAKE_UBDIAG_LAYER}" = "system" ]; then - local ubdiag_library_dir="" - local ubdiag_candidate="" - local staged_library_count=0 + local ubdiag_library_dir + local ubdiag_library - ubdiag_library_dir="$(dirname "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" cp "${MOONCAKE_UBDIAG_SYSTEM_CLI}" "${BUILDROOT}/usr/bin/ubdiag" - chmod 755 "${BUILDROOT}/usr/bin/ubdiag" - - while IFS= read -r -d '' ubdiag_candidate; do - if [ "$(readlink -f "${ubdiag_candidate}")" = \ + ubdiag_library_dir="$(dirname "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" + for ubdiag_library in "${ubdiag_library_dir}"/libubdiag.so*; do + if [ "$(readlink -f "${ubdiag_library}")" = \ "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" ]; then - cp -a "${ubdiag_candidate}" "${BUILDROOT}/usr/${LIB_DIR}/" - staged_library_count=$((staged_library_count + 1)) + cp -a "${ubdiag_library}" "${BUILDROOT}/usr/${LIB_DIR}/" fi - done < <( - find "${ubdiag_library_dir}" -maxdepth 1 \ - -name 'libubdiag.so*' -print0 - ) - if [ "${staged_library_count}" -eq 0 ] || - [ ! -f "${BUILDROOT}/usr/${LIB_DIR}/$(basename \ - "${MOONCAKE_UBDIAG_SYSTEM_LIBRARY}")" ]; then - fail_ubdiag_packaging \ - "failed to stage the selected system libubdiag.so chain" - return 1 - fi + done if [ -n "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" ]; then - if [ ! -f "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" ]; then - fail_ubdiag_packaging \ - "configured UbDiag config disappeared: ${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" - return 1 - fi mkdir -p "${BUILDROOT}/etc/ubdiag" cp "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}" \ "${BUILDROOT}/etc/ubdiag/ubdiag.conf" UBDIAG_CONFIG_RPM_FILE="%config(noreplace) /etc/ubdiag/ubdiag.conf" fi fi - + # ------------------------------------------------------------------------- # Copy header files (only core headers for real_client and dummy_client) # ------------------------------------------------------------------------- echo "Copying core header files for real_client and dummy_client..." - + # Create include directories mkdir -p rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/include/mooncake - + # Core client headers (real_client and dummy_client dependencies) # These are the essential headers needed for client-side development CORE_HEADERS=( @@ -405,21 +231,21 @@ build_rpm_for_platform() { "real_client.h" "dummy_client.h" "pyclient.h" - + # pyclient dependencies "client_service.h" "client_buffer.hpp" "mutex.h" "utils.h" "file_storage.h" - + # real_client dependencies "rpc_types.h" - + # dummy_client dependencies "shm_helper.h" "client_metric.h" - + # Common types and utilities "types.h" "segment.h" @@ -435,11 +261,11 @@ build_rpm_for_platform() { "metadata_store.h" "mmap_arena.h" "pinned_buffer_pool.h" - + # C API headers "store_c.h" ) - + # Copy core store headers for header in "${CORE_HEADERS[@]}"; do if [ -f mooncake-store/include/${header} ]; then @@ -448,7 +274,7 @@ build_rpm_for_platform() { echo "Warning: Core header ${header} not found" fi done - + # Transfer engine core headers (needed by real_client) TRANSFER_ENGINE_HEADERS=( "transfer_engine_c.h" @@ -460,7 +286,7 @@ build_rpm_for_platform() { "multi_transport.h" "topology.h" ) - + # Copy transfer engine headers for header in "${TRANSFER_ENGINE_HEADERS[@]}"; do if [ -f mooncake-transfer-engine/include/${header} ]; then @@ -469,7 +295,7 @@ build_rpm_for_platform() { echo "Warning: Transfer engine header ${header} not found" fi done - + # Note: Excluding the following directories as they are not needed for basic client usage: # - cachelib_memory_allocator/ (memory allocator internals) # - engram/ (engram store specific) @@ -479,79 +305,26 @@ build_rpm_for_platform() { # - serialize/ (serialization utilities) # - spdk/ (SPDK integration) # - utils/s3_helper.h, zstd_util.h (specific utilities) - + # ------------------------------------------------------------------------- # Copy configuration files # ------------------------------------------------------------------------- echo "Copying configuration files..." - + # Master configuration if [ -f mooncake-store/conf/master.yaml ]; then cp mooncake-store/conf/master.yaml rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi - + if [ -f mooncake-store/conf/master.json ]; then cp mooncake-store/conf/master.json rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/mooncake/ fi - - # ------------------------------------------------------------------------- - # Validate the staged runtime before creating the RPM - # ------------------------------------------------------------------------- - local staged_elf="" - local staged_ubdiag_dependency_count=0 - for required_binary in mooncake_master mooncake_client; do - if [ ! -x "${BUILDROOT}/usr/bin/${required_binary}" ]; then - fail_ubdiag_packaging \ - "required Mooncake binary is missing: ${required_binary}" - return 1 - fi - done - - while IFS= read -r -d '' staged_elf; do - if ! readelf -h "${staged_elf}" >/dev/null 2>&1; then - continue - fi - remove_staged_rpath "${staged_elf}" - case "${staged_elf}" in - */usr/bin/ubdiag|*/usr/${LIB_DIR}/libubdiag.so*) - continue - ;; - esac - if readelf -d "${staged_elf}" 2>/dev/null | - grep -q 'Shared library:.*libubdiag\.so'; then - staged_ubdiag_dependency_count=$((staged_ubdiag_dependency_count + 1)) - fi - done < <(find "${BUILDROOT}" -type f -print0) - - if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ]; then - if [ "${staged_ubdiag_dependency_count}" -ne 0 ] || - [ -e "${BUILDROOT}/usr/bin/ubdiag" ] || - compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" \ - >/dev/null; then - fail_ubdiag_packaging \ - "mock RPM must not contain or depend on the UbDiag runtime" - return 1 - fi - else - if [ "${staged_ubdiag_dependency_count}" -eq 0 ]; then - fail_ubdiag_packaging \ - "system RPM has no Mooncake ELF linked to libubdiag.so" - return 1 - fi - if [ ! -x "${BUILDROOT}/usr/bin/ubdiag" ] || - ! compgen -G "${BUILDROOT}/usr/${LIB_DIR}/libubdiag.so*" \ - >/dev/null; then - fail_ubdiag_packaging \ - "system RPM is missing the UbDiag CLI or shared library" - return 1 - fi - fi - + # ------------------------------------------------------------------------- # Create RPM spec file # ------------------------------------------------------------------------- echo "Creating RPM spec file for ${PLATFORM}..." - + cat > rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec << EOF Name: ${PACKAGE_NAME} Version: ${PACKAGE_VERSION} @@ -578,9 +351,8 @@ Requires: libibverbs.so.1()(64bit) Recommends: libcudart.so.12()(64bit) Recommends: liburma.so.0()(64bit) -# Refresh the dynamic linker cache after installation and removal. -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig +# Optional dependencies - not required but recommended +Requires(pre): /usr/sbin/ldconfig %description ${PACKAGE_DESCRIPTION} @@ -592,93 +364,41 @@ ${PACKAGE_DESCRIPTION} %config(noreplace) /etc/mooncake/* ${UBDIAG_CONFIG_RPM_FILE} -%post -p /sbin/ldconfig +%post +/sbin/ldconfig -%postun -p /sbin/ldconfig +%postun +/sbin/ldconfig %changelog * $(date +"%a %b %d %Y") KVCache.AI - ${PACKAGE_VERSION}-${PACKAGE_RELEASE} - Initial RPM package for ${PLATFORM} EOF - + # ------------------------------------------------------------------------- # Build RPM package # ------------------------------------------------------------------------- echo "Building RPM package for ${PLATFORM}..." - + # Ensure rpmbuild is available if ! command -v rpmbuild &>/dev/null; then echo "Error: rpmbuild not found. Please install rpm-build package." exit 1 fi - + # Create platform-specific output directory - mkdir -p "${OUTPUT_DIR}/${PLATFORM}" - + mkdir -p ${OUTPUT_DIR}/${PLATFORM} + # Build the RPM rpmbuild -bb \ + --buildroot "$(pwd)/${BUILDROOT}" \ --define "_topdir $(pwd)/rpmbuild" \ --define "_rpmdir ${OUTPUT_DIR}" \ rpmbuild/SPECS/${PACKAGE_NAME}-${PLATFORM}.spec - + # Move RPM to platform-specific directory - mv "${OUTPUT_DIR}/${PLATFORM}"/*.rpm "${OUTPUT_DIR}/" 2>/dev/null || true - - local built_rpm="" - local rpm_candidate="" - for rpm_candidate in "${OUTPUT_DIR}"/*.rpm; do - [ -e "${rpm_candidate}" ] || continue - if [ "$(rpm -qp --qf '%{ARCH}' "${rpm_candidate}")" = \ - "${PLATFORM}" ]; then - built_rpm="${rpm_candidate}" - fi - done - if [ -z "${built_rpm}" ]; then - fail_ubdiag_packaging \ - "rpmbuild did not produce a ${PLATFORM} Mooncake RPM" - return 1 - fi - - local rpm_file_list="" - rpm_file_list="$(rpm -qlp "${built_rpm}")" - if [ "${MOONCAKE_UBDIAG_LAYER}" = "mock" ]; then - if grep -Eq '^/usr/bin/ubdiag$|^/usr/lib64/libubdiag\.so' \ - <<< "${rpm_file_list}"; then - fail_ubdiag_packaging \ - "mock RPM unexpectedly contains the UbDiag runtime" - return 1 - fi - else - grep -qx '/usr/bin/ubdiag' <<< "${rpm_file_list}" || - { - fail_ubdiag_packaging \ - "system RPM does not contain /usr/bin/ubdiag" - return 1 - } - grep -Eq '^/usr/lib64/libubdiag\.so' <<< "${rpm_file_list}" || - { - fail_ubdiag_packaging \ - "system RPM does not contain libubdiag.so" - return 1 - } - fi - - # Install the payload into an isolated RPM root. This verifies that the - # generated package can be installed without mutating the build machine. - local install_root - install_root="$(pwd)/rpmbuild/INSTALLROOT-${PLATFORM}" - mkdir -p "${install_root}" - rpm --root "${install_root}" --initdb - rpm --root "${install_root}" -ivh --nodeps --noscripts "${built_rpm}" - test -x "${install_root}/usr/bin/mooncake_master" - test -x "${install_root}/usr/bin/mooncake_client" - if [ "${MOONCAKE_UBDIAG_LAYER}" = "system" ]; then - test -x "${install_root}/usr/bin/ubdiag" - compgen -G "${install_root}/usr/${LIB_DIR}/libubdiag.so*" \ - >/dev/null - fi - rm -rf "${install_root}" - + mv ${OUTPUT_DIR}/${PLATFORM}/*.rpm ${OUTPUT_DIR}/ 2>/dev/null || true + # Cleanup BUILDROOT for next platform rm -rf rpmbuild/BUILDROOT/ } @@ -688,20 +408,20 @@ EOF # ----------------------------------------------------------------------------- if [ "${TARGET_PLATFORM}" = "all" ]; then echo "Building RPM packages for all supported platforms..." - + # Build for x86_64 build_rpm_for_platform "x86_64" - + # Build for aarch64 (if cross-compilation is available or running on ARM) if [ "${HOST_ARCH}" = "aarch64" ] || [ -d "${BUILD_DIR}-aarch64" ]; then build_rpm_for_platform "aarch64" else echo "Warning: Skipping aarch64 build - no cross-compilation build directory found" fi - + elif [ "${TARGET_PLATFORM}" = "x86_64" ] || [ "${TARGET_PLATFORM}" = "aarch64" ]; then build_rpm_for_platform "${TARGET_PLATFORM}" - + else echo "Error: Unsupported platform ${TARGET_PLATFORM}" echo "Supported platforms: x86_64, aarch64, all" @@ -711,7 +431,7 @@ fi # List created RPM files echo "RPM packages built successfully!" echo "Created RPM files:" -ls -la "${OUTPUT_DIR}"/*.rpm 2>/dev/null || echo "No RPM files created" +ls -la ${OUTPUT_DIR}/*.rpm 2>/dev/null || echo "No RPM files created" # Cleanup rm -rf rpmbuild/ From 99979204511f71a7917b28eda02f6027187f49d0 Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Thu, 30 Jul 2026 13:00:48 +0800 Subject: [PATCH 17/18] =?UTF-8?q?docs:=20=E7=B2=BE=E7=AE=80=E5=B9=B6?= =?UTF-8?q?=E4=BF=9D=E7=95=99UbDiag=E7=94=A8=E6=88=B7=E6=8C=87=E5=8D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/ubdiag_integration_guide.md | 90 ++++++++++++++------------------ 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/docs/ubdiag_integration_guide.md b/docs/ubdiag_integration_guide.md index d55515e801..2282331a5d 100644 --- a/docs/ubdiag_integration_guide.md +++ b/docs/ubdiag_integration_guide.md @@ -1,7 +1,6 @@ # Mooncake UbDiag 两层集成使用指南 -Mooncake 在配置阶段提供两个互斥的 UbDiag 编译层。构建完成后不能在运行时 -切换层级;如需切换,应重新配置并编译。 +Mooncake 在配置阶段提供两个互斥的 UbDiag 编译层。构建完成后不能在运行时切换层级;如需切换,应重新配置并编译。 | 层 | 配置 | UbDiag 来源 | 生成结果 | |---|---|---|---| @@ -20,16 +19,9 @@ cmake --build build --parallel `MOONCAKE_ENABLE_UBDIAG` 默认值为 `OFF`,因此该参数可以省略。 -Mooncake 使用 FetchContent 拉取固定提交的 UbDiag 源码,只消费公共头文件, -并通过统一目标 `UbDiag::ubdiag_lib` 传播: +Mooncake 使用 FetchContent 拉取固定修订的 UbDiag 源码,只消费 `include/ubdiag` 公共头文件,并通过统一目标 `UbDiag::ubdiag_lib` 传播 `UBDIAG_DISABLE`。 -```text -include/ubdiag -UBDIAG_DISABLE -``` - -UbDiag 头文件中的 `UBDIAG_DISABLE` 分支将 PerfPoint 构造、`Start()`、 -`End()` 和 `Abandon()` 编译为空实现。因此: +UbDiag 头文件中的 `UBDIAG_DISABLE` 分支将 PerfPoint 构造、`Start()`、`End()` 和 `Abandon()` 编译为空实现。因此: - Mooncake 打点源码保持不变; - Mooncake ELF 不依赖 `libubdiag.so`; @@ -37,7 +29,7 @@ UbDiag 头文件中的 `UBDIAG_DISABLE` 分支将 PerfPoint 构造、`Start()` - 不创建 UbDiag SHM; - 系统中已安装的 UbDiag 不参与该构建。 -离线环境可以指定相同提交的洁净 UbDiag 工作树: +离线环境可以指定已准备好的 UbDiag 源码目录: ```bash cmake -S . -B build \ @@ -49,13 +41,12 @@ cmake -S . -B build \ ### 2.1 前置条件 -Layer 1 不下载或编译真实 UbDiag。配置 Mooncake 前,用户必须先安装完整 -UbDiag RPM。该安装必须同时提供: +Layer 1 不下载或编译真实 UbDiag。配置 Mooncake 前,用户必须先安装完整的 UbDiag 运行时 RPM 和开发 RPM。安装结果必须同时提供: - `UbDiagConfig.cmake`; - 导入目标 `UbDiag::ubdiag_lib`; - 共享库 `libubdiag.so`; -- 同一安装前缀下的 `bin/ubdiag`; +- 可被系统找到的 `ubdiag` CLI; - `UBDIAG_ENABLE_PERCENTILE`; - `UBDIAG_ENABLE_PERFLOG`。 @@ -67,10 +58,7 @@ ENABLE_PERCENTILE=ON ENABLE_PERFLOG=ON ``` -Mooncake 不固定 L1 的 UbDiag 版本或源码 SHA。它通过 RPM 数据库分别查询 -真实 `libubdiag.so` 与 CLI 的所有者,并要求二者的 -`VERSION-RELEASE.ARCH` 完全一致。UbDiag RPM 自身的功能正确性由 UbDiag -发布方负责。 +Mooncake 不固定 Layer 1 的 UbDiag 版本或源码 SHA。它通过 RPM 数据库分别查询 `libubdiag.so` 与 CLI 的 `VERSION-RELEASE.ARCH`,并要求二者完全一致。UbDiag RPM 中其他功能的启用情况和功能正确性由 UbDiag 发布包负责。 ### 2.2 配置与编译 @@ -87,31 +75,31 @@ cmake --build build-ubdiag --parallel ```bash cmake -S . -B build-ubdiag \ -DMOONCAKE_ENABLE_UBDIAG=ON \ - -DCMAKE_PREFIX_PATH=/opt/ubdiag + -DCMAKE_PREFIX_PATH=/opt/ubdiag \ + -DCMAKE_PROGRAM_PATH=/opt/ubdiag/bin ``` -也可以直接指定 CMake package: +也可以直接指定 CMake package 和 CLI: ```bash cmake -S . -B build-ubdiag \ -DMOONCAKE_ENABLE_UBDIAG=ON \ - -DUbDiag_DIR=/opt/ubdiag/lib64/cmake/UbDiag + -DUbDiag_DIR=/opt/ubdiag/lib64/cmake/UbDiag \ + -DMOONCAKE_UBDIAG_SYSTEM_CLI=/opt/ubdiag/bin/ubdiag ``` -### 2.3 配置门禁 +### 2.3 配置检查 -ON 模式依次检查: +ON 模式依次确认: -1. 找到 UbDiag CMake package; -2. package 导出导入型 `SHARED_LIBRARY` 目标; -3. 共享库解析为真实存在的 `libubdiag.so`; -4. target 传播 P99 与 PerfLog 能力宏; -5. 在同一安装前缀找到 `bin/ubdiag`; -6. `.so` 与 CLI 均由名称包含 `ubdiag` 的 RPM 拥有; -7. 两个 RPM 的 `VERSION-RELEASE.ARCH` 完全一致。 +1. 找到 UbDiag CMake package 和 `UbDiag::ubdiag_lib`; +2. package 导出 `SHARED_LIBRARY` 目标; +3. target 传播 P99 与 PerfLog 能力宏; +4. 找到 `ubdiag` CLI; +5. `.so` 与 CLI 均由已安装的 RPM 提供; +6. 两者的 `VERSION-RELEASE.ARCH` 完全一致。 -任一条件不满足都会停止配置。Mooncake 不会回退到源码构建,也不会使用 -`PATH` 中另一个前缀的 CLI。 +任一条件不满足都会停止配置。Mooncake 不会回退到源码构建;应先修复或重新安装 UbDiag RPM,再重新配置 Mooncake。 ## 3. 构建 Mooncake RPM @@ -130,8 +118,6 @@ Mock RPM 包含 Mooncake 二进制,但不包含: /etc/ubdiag/ubdiag.conf ``` -打包脚本还会检查所有 Mooncake ELF 均不依赖 `libubdiag.so`。 - ### 3.2 System RPM ```bash @@ -146,22 +132,24 @@ System RPM 包含: /usr/bin/mooncake_client /usr/bin/ubdiag /usr/lib64/libubdiag.so* -/etc/ubdiag/ubdiag.conf # 系统包提供配置时 +/etc/ubdiag/ubdiag.conf # 系统安装提供该配置时 ``` -打包脚本读取 `build-ubdiag/mooncake_ubdiag.env`,不会重新搜索 `PATH` 或 -`LD_LIBRARY_PATH`。在复制前会再次查询 `.so` 与 CLI 的 RPM 归属;若系统 -UbDiag 在配置后被升级、替换或拆成不同版本,打包立即失败。 +打包脚本读取 `build-ubdiag/mooncake_ubdiag.env`,并复制 CMake 配置阶段已经选中的 CLI、共享库及其符号链接。CLI 与共享库的版本一致性在 CMake 配置阶段完成检查;如果构建机上的 UbDiag RPM 随后发生变化,应重新配置后再打包。 -生成 RPM 后,脚本会: +## 4. 安装与运行 -1. 检查 RPM 文件清单; -2. 检查 Mock/System 层与 ELF 依赖是否一致; -3. 清除构建目录 RPATH/RUNPATH; -4. 将 RPM 安装到隔离根目录,验证 payload 可以正常回装; -5. 不修改构建机当前已安装的软件。 +Mooncake RPM 使用标准系统路径安装 Mooncake 和 UbDiag 运行时: -## 4. 安装与运行 +```text +/usr/bin/mooncake_master +/usr/bin/mooncake_client +/usr/bin/ubdiag +/usr/lib64/libubdiag.so* +/etc/ubdiag/ubdiag.conf +``` + +安装和基础运行命令: ```bash sudo rpm -Uvh rpm-output/mooncake-*.rpm @@ -177,7 +165,7 @@ ubdiag show ubdiag show --detail ``` -PerfLog、P99 与 CSV 参数以所安装 UbDiag CLI 的帮助为准: +PerfLog、P99、历史数据和 CSV 参数以所安装 UbDiag CLI 的帮助为准: ```bash ubdiag --help @@ -188,13 +176,11 @@ ubdiag show --help ### `.so` 或 CLI 不受 RPM 管理 -L1 面向系统 UbDiag RPM,不接受手工复制的散装文件。请安装完整 UbDiag -RPM 后重新配置 Mooncake。 +Layer 1 面向系统 UbDiag RPM,不接受手工复制的散装文件。请安装完整的 UbDiag 运行时 RPM 和开发 RPM 后重新配置 Mooncake。 ### `.so` 与 CLI 的 RPM 版本不同 -卸载冲突版本,并安装同一发布批次的 UbDiag RPM。Mooncake 比较 -`VERSION-RELEASE.ARCH`,不通过文件 SHA 判断。 +卸载冲突版本,并安装同一发布批次的 UbDiag RPM。Mooncake 比较 `VERSION-RELEASE.ARCH`,不通过文件 SHA 判断。 ### 找到静态库 @@ -211,7 +197,7 @@ ENABLE_PERFLOG=ON ### 从 Mock 切换到 System -推荐使用新的构建目录,避免旧模式产物混入: +推荐使用新的构建目录: ```bash cmake -S . -B build-ubdiag \ From 64f45d2848bfaf5cb14a28192132df8d6594d5ec Mon Sep 17 00:00:00 2001 From: qinyufei63 Date: Thu, 30 Jul 2026 14:49:40 +0800 Subject: [PATCH 18/18] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E7=B3=BB?= =?UTF-8?q?=E7=BB=9FUbDiag=E7=9B=AE=E6=A0=87=E4=BD=9C=E7=94=A8=E5=9F=9F?= =?UTF-8?q?=E4=B8=8ECLI=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mooncake-common/FindUbDiag.cmake | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake index a99d6020cb..a70a306057 100644 --- a/mooncake-common/FindUbDiag.cmake +++ b/mooncake-common/FindUbDiag.cmake @@ -63,6 +63,7 @@ if(NOT UbDiag_FOUND OR NOT TARGET UbDiag::ubdiag_lib) "RPMs. Install the RPMs that provide libubdiag.so, the ubdiag CLI, and " "UbDiagConfig.cmake before configuring Mooncake.") endif() +set_property(TARGET UbDiag::ubdiag_lib PROPERTY IMPORTED_GLOBAL TRUE) get_target_property(_MOONCAKE_UBDIAG_TARGET_TYPE UbDiag::ubdiag_lib TYPE) if(NOT _MOONCAKE_UBDIAG_TARGET_TYPE STREQUAL "SHARED_LIBRARY") @@ -114,7 +115,15 @@ foreach(_definition UBDIAG_ENABLE_PERCENTILE UBDIAG_ENABLE_PERFLOG) endif() endforeach() -find_program(MOONCAKE_UBDIAG_SYSTEM_CLI NAMES ubdiag) +get_filename_component(_MOONCAKE_UBDIAG_SYSTEM_PREFIX + "${MOONCAKE_UBDIAG_LIBRARY_DIR}" DIRECTORY) +unset(MOONCAKE_UBDIAG_SYSTEM_CLI) +unset(MOONCAKE_UBDIAG_SYSTEM_CLI CACHE) +find_program( + MOONCAKE_UBDIAG_SYSTEM_CLI + NAMES ubdiag + PATHS "${_MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin" + NO_DEFAULT_PATH) if(NOT MOONCAKE_UBDIAG_SYSTEM_CLI) message( FATAL_ERROR "The UbDiag SDK was found, but the ubdiag CLI is missing. "