diff --git a/.gitmodules b/.gitmodules
index acc910c38d..5a4998c24b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,3 +6,7 @@
path = extern/yalantinglibs
url = https://github.com/alibaba/yalantinglibs.git
branch = v0.5.7
+[submodule "extern/ubdiag"]
+ path = extern/ubdiag
+ url = https://atomgit.com/liusiyu60/ubdiag
+ branch = fix/shm-probe-fastpath
diff --git a/README.md b/README.md
index 925d9e3398..bb68537318 100644
--- a/README.md
+++ b/README.md
@@ -350,6 +350,23 @@ make -j
```
+
📊 UbDiag PerfPoint 集成
+
+Mooncake 通过 UbDiag SDK 支持 PerfPoint 性能打点,编译期自动通过三层分发(submodule / 系统包 / header-only mock)解析。使用前需先安装 ubdiag。
+
+**使用场景**:
+
+| 场景 | 操作 | 结果 |
+|---|---|---|
+| 需要打点 | `ubdiag start` → 启动 Mooncake | SHM 已存在,PerfPoint 正常打点 |
+| 不需要打点 | 直接启动 Mooncake | SDK 探测一次 SHM 不存在,后续全跳过,程序正常跑 |
+| 不需要打点但中途又想打点 | 重启 Mooncake(或程序内调 `Shutdown()` → `Init()`) | probeDone 标记归零,重新探测 SHM |
+
+> **注意**:Mooncake 启动后再执行 `ubdiag start`,已经在跑的 Mooncake 进程**不会自动感知**。必须重启进程,或在程序内调用 `PerfManager::Instance().Shutdown()` 后再 `Init(config)`。`ubdiag restart` 操作的是 SHM,不影响进程内部已缓存的探测结果。
+
+详见 [UbDiag 文档](https://atomgit.com/liusiyu60/ubdiag)。
+
+
🛣️ Incoming Milestones
- [x] First release of Mooncake and integrate with latest vLLM
diff --git a/extern/ubdiag b/extern/ubdiag
new file mode 160000
index 0000000000..7deea5f897
--- /dev/null
+++ b/extern/ubdiag
@@ -0,0 +1 @@
+Subproject commit 7deea5f89786784a2e2aa074d315a0a8e2561963
diff --git a/mooncake-common/FindUbDiag.cmake b/mooncake-common/FindUbDiag.cmake
new file mode 100644
index 0000000000..81f79231df
--- /dev/null
+++ b/mooncake-common/FindUbDiag.cmake
@@ -0,0 +1,239 @@
+# FindUbDiag.cmake Resolves UbDiag::ubdiag_lib with a three-layer fallback: 1.
+# Submodule (extern/ubdiag) — add_subdirectory if present 2. System package —
+# find_package(UbDiag QUIET) 3. Mock header — mooncake-common/ubdiag-mock/
+# (no-op PerfPoint)
+#
+# Usage: include(${CMAKE_SOURCE_DIR}/mooncake-common/FindUbDiag.cmake)
+# target_link_libraries(your_target PRIVATE UbDiag::ubdiag_lib)
+
+if(TARGET UbDiag::ubdiag_lib)
+ return()
+endif()
+
+option(MOONCAKE_UBDIAG_BUILD_CLI
+ "Enable UbDiag CLI integration for vendored or system UbDiag" ON)
+option(MOONCAKE_UBDIAG_L1_SHARED
+ "Build vendored UbDiag as libubdiag.so so Mooncake and the CLI use one SDK" ON)
+option(MOONCAKE_UBDIAG_ENABLE_PERCENTILE
+ "Enable vendored UbDiag P99/P999/P9999 percentile calculation for Mooncake PerfPoint" ON)
+option(MOONCAKE_UBDIAG_ENABLE_PERFLOG
+ "Enable vendored UbDiag PerfLog timestamp logging for Mooncake PerfPoint" ON)
+option(MOONCAKE_UBDIAG_PERFPOINT_ONLY
+ "Disable vendored UbDiag OB/MemPoint/CachePoint extensions; keep Mooncake PerfPoint/P99/PerfLog/CSV" ON)
+option(MOONCAKE_UBDIAG_DISABLE_SYSTEM
+ "Skip Layer 2 system-package lookup, used only for forced mock verification" OFF)
+
+function(_mooncake_ubdiag_write_rpm_manifest layer cli_path library_path config_path)
+ set(_manifest "${CMAKE_BINARY_DIR}/mooncake_ubdiag_rpm.env")
+ file(WRITE "${_manifest}" "MOONCAKE_UBDIAG_LAYER=${layer}\n")
+ file(APPEND "${_manifest}" "MOONCAKE_UBDIAG_CLI_PATH=${cli_path}\n")
+ file(APPEND "${_manifest}" "MOONCAKE_UBDIAG_LIBRARY_PATH=${library_path}\n")
+ file(APPEND "${_manifest}" "MOONCAKE_UBDIAG_CONFIG_PATH=${config_path}\n")
+ set(MOONCAKE_UBDIAG_RPM_MANIFEST "${_manifest}"
+ CACHE FILEPATH "UbDiag RPM packaging manifest generated by Mooncake" FORCE)
+ set(MOONCAKE_UBDIAG_ACTIVE_LAYER "${layer}"
+ CACHE STRING "Active UbDiag integration layer: submodule, system, or mock" FORCE)
+endfunction()
+
+function(_mooncake_ubdiag_get_imported_location target out_var)
+ set(_location_props IMPORTED_LOCATION IMPORTED_LOCATION_NOCONFIG)
+ get_target_property(_configs ${target} IMPORTED_CONFIGURATIONS)
+ if(NOT _configs OR _configs MATCHES "-NOTFOUND$")
+ set(_configs)
+ endif()
+ foreach(_config IN LISTS _configs)
+ string(TOUPPER "${_config}" _config_upper)
+ list(APPEND _location_props "IMPORTED_LOCATION_${_config_upper}")
+ endforeach()
+ list(APPEND _location_props
+ IMPORTED_LOCATION_RELEASE
+ IMPORTED_LOCATION_RELWITHDEBINFO
+ IMPORTED_LOCATION_MINSIZEREL
+ IMPORTED_LOCATION_DEBUG)
+
+ foreach(_prop IN LISTS _location_props)
+ get_target_property(_location ${target} ${_prop})
+ if(_location AND NOT _location MATCHES "-NOTFOUND$")
+ set(${out_var} "${_location}" PARENT_SCOPE)
+ return()
+ endif()
+ endforeach()
+
+ set(${out_var} "" PARENT_SCOPE)
+endfunction()
+
+# Layer 1: Submodule (same pattern as extern/pybind11). UbDiag's generic
+# BUILD_TESTS / BUILD_EXAMPLES default to ON and collide with Mooncake option
+# names, so temporarily narrow them only while adding the submodule.
+if(EXISTS "${CMAKE_SOURCE_DIR}/extern/ubdiag/CMakeLists.txt")
+ set(_MOONCAKE_UBDIAG_SAVED_BUILD_EXAMPLES "${BUILD_EXAMPLES}")
+ set(_MOONCAKE_UBDIAG_HAD_BUILD_EXAMPLES_CACHE FALSE)
+ if(DEFINED CACHE{BUILD_EXAMPLES})
+ set(_MOONCAKE_UBDIAG_HAD_BUILD_EXAMPLES_CACHE TRUE)
+ get_property(_MOONCAKE_UBDIAG_BUILD_EXAMPLES_HELP CACHE BUILD_EXAMPLES PROPERTY HELPSTRING)
+ endif()
+ set(_MOONCAKE_UBDIAG_SAVED_BUILD_TESTS "${BUILD_TESTS}")
+ set(_MOONCAKE_UBDIAG_HAD_BUILD_TESTS_CACHE FALSE)
+ if(DEFINED CACHE{BUILD_TESTS})
+ set(_MOONCAKE_UBDIAG_HAD_BUILD_TESTS_CACHE TRUE)
+ get_property(_MOONCAKE_UBDIAG_BUILD_TESTS_HELP CACHE BUILD_TESTS PROPERTY HELPSTRING)
+ endif()
+ set(BUILD_EXAMPLES OFF)
+ set(BUILD_EXAMPLES OFF CACHE BOOL "Disable UbDiag examples when vendored by Mooncake" FORCE)
+ set(BUILD_TESTS OFF)
+ set(BUILD_TESTS OFF CACHE BOOL "Disable UbDiag tests when vendored by Mooncake" FORCE)
+ if(MOONCAKE_UBDIAG_L1_SHARED)
+ set(UBDIAG_BUILD_SHARED ON CACHE BOOL "Build vendored UbDiag as a shared library" FORCE)
+ endif()
+ if(MOONCAKE_UBDIAG_ENABLE_PERCENTILE)
+ set(ENABLE_PERCENTILE ON CACHE BOOL "Enable vendored UbDiag percentile calculation" FORCE)
+ endif()
+ if(MOONCAKE_UBDIAG_ENABLE_PERFLOG)
+ set(ENABLE_PERFLOG ON CACHE BOOL "Enable vendored UbDiag PerfLog support" FORCE)
+ endif()
+ if(MOONCAKE_UBDIAG_PERFPOINT_ONLY)
+ set(ENABLE_OB_MEMORY OFF CACHE BOOL "Disable vendored UbDiag eBPF memory observation" FORCE)
+ set(ENABLE_OB_CACHE OFF CACHE BOOL "Disable vendored UbDiag cache observation" FORCE)
+ set(ENABLE_MEMPOINT OFF CACHE BOOL "Disable vendored UbDiag MemPoint observation" FORCE)
+ set(UBDIAG_ENABLE_CACHEPOINT OFF CACHE BOOL "Disable vendored UbDiag CachePoint observation" FORCE)
+ endif()
+
+ add_subdirectory(${CMAKE_SOURCE_DIR}/extern/ubdiag
+ ${CMAKE_BINARY_DIR}/extern/ubdiag_build EXCLUDE_FROM_ALL)
+
+ if(_MOONCAKE_UBDIAG_HAD_BUILD_EXAMPLES_CACHE)
+ set(BUILD_EXAMPLES "${_MOONCAKE_UBDIAG_SAVED_BUILD_EXAMPLES}"
+ CACHE BOOL "${_MOONCAKE_UBDIAG_BUILD_EXAMPLES_HELP}" FORCE)
+ else()
+ unset(BUILD_EXAMPLES CACHE)
+ endif()
+ set(BUILD_EXAMPLES "${_MOONCAKE_UBDIAG_SAVED_BUILD_EXAMPLES}")
+ if(_MOONCAKE_UBDIAG_HAD_BUILD_TESTS_CACHE)
+ set(BUILD_TESTS "${_MOONCAKE_UBDIAG_SAVED_BUILD_TESTS}"
+ CACHE BOOL "${_MOONCAKE_UBDIAG_BUILD_TESTS_HELP}" FORCE)
+ else()
+ unset(BUILD_TESTS CACHE)
+ endif()
+ set(BUILD_TESTS "${_MOONCAKE_UBDIAG_SAVED_BUILD_TESTS}")
+
+ if(TARGET ubdiag_lib)
+ set(_MOONCAKE_UBDIAG_SOURCE_DIR "${CMAKE_SOURCE_DIR}/extern/ubdiag")
+ # ubdiag's CMake uses CMAKE_SOURCE_DIR instead of CMAKE_CURRENT_SOURCE_DIR
+ # for its include paths. When consumed via add_subdirectory from Mooncake,
+ # CMAKE_SOURCE_DIR points to Mooncake's root, not ubdiag's. Fix it here.
+ target_include_directories(ubdiag_lib PUBLIC
+ $
+ $)
+
+ foreach(_MOONCAKE_UBDIAG_LIB_TARGET
+ ubdiag_logger ubdiag_manager_lib ubdiag_runtime_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
+ ${_MOONCAKE_UBDIAG_SOURCE_DIR}/include
+ ${_MOONCAKE_UBDIAG_SOURCE_DIR}/src
+ ${_MOONCAKE_UBDIAG_SOURCE_DIR}/src/cli)
+ if(MOONCAKE_UBDIAG_BUILD_CLI AND NOT TARGET mooncake_ubdiag_cli)
+ add_custom_target(mooncake_ubdiag_cli ALL DEPENDS ubdiag)
+ endif()
+ elseif(MOONCAKE_UBDIAG_BUILD_CLI)
+ message(WARNING "UbDiag: extern/ubdiag does not define the ubdiag CLI target")
+ endif()
+
+ add_library(UbDiag::ubdiag_lib ALIAS ubdiag_lib)
+ _mooncake_ubdiag_write_rpm_manifest(
+ "submodule"
+ "${CMAKE_BINARY_DIR}/extern/ubdiag_build/src/cli/ubdiag"
+ "${CMAKE_BINARY_DIR}/extern/ubdiag_build/src/sdk/libubdiag.so"
+ "${CMAKE_SOURCE_DIR}/extern/ubdiag/config/ubdiag.conf.example")
+ message(STATUS "UbDiag: using submodule (extern/ubdiag, CLI=${MOONCAKE_UBDIAG_BUILD_CLI})")
+ return()
+ endif()
+endif()
+
+# Layer 2: System package — only search standard system library paths
+# Using NO_DEFAULT_PATH + explicit PATHS to prevent cmake from recursively
+# searching CMAKE_SYSTEM_PREFIX_PATH subdirectories (e.g., UbDiag_bak, build artifacts)
+if(NOT MOONCAKE_UBDIAG_DISABLE_SYSTEM)
+ find_package(UbDiag QUIET
+ NO_DEFAULT_PATH
+ PATHS
+ /usr/lib64/cmake
+ /usr/local/lib64/cmake
+ /usr/lib/cmake
+ /usr/local/lib/cmake)
+ if(TARGET UbDiag::ubdiag_lib)
+ _mooncake_ubdiag_get_imported_location(UbDiag::ubdiag_lib _MOONCAKE_UBDIAG_SYSTEM_LIBRARY)
+
+ set(_MOONCAKE_UBDIAG_CLI_HINTS)
+ set(_MOONCAKE_UBDIAG_CONFIG_HINTS)
+ if(_MOONCAKE_UBDIAG_SYSTEM_LIBRARY)
+ get_filename_component(_MOONCAKE_UBDIAG_SYSTEM_LIB_DIR
+ "${_MOONCAKE_UBDIAG_SYSTEM_LIBRARY}" DIRECTORY)
+ get_filename_component(_MOONCAKE_UBDIAG_SYSTEM_PREFIX
+ "${_MOONCAKE_UBDIAG_SYSTEM_LIB_DIR}/.." ABSOLUTE)
+ list(APPEND _MOONCAKE_UBDIAG_CLI_HINTS
+ "${_MOONCAKE_UBDIAG_SYSTEM_PREFIX}/bin")
+ list(APPEND _MOONCAKE_UBDIAG_CONFIG_HINTS
+ "${_MOONCAKE_UBDIAG_SYSTEM_PREFIX}/etc/ubdiag")
+ endif()
+
+ find_program(MOONCAKE_UBDIAG_SYSTEM_CLI
+ NAMES ubdiag
+ HINTS ${_MOONCAKE_UBDIAG_CLI_HINTS}
+ PATHS /usr/bin /usr/local/bin
+ NO_DEFAULT_PATH)
+ if(MOONCAKE_UBDIAG_SYSTEM_CLI
+ AND NOT MOONCAKE_UBDIAG_SYSTEM_CLI MATCHES "-NOTFOUND$")
+ set(_MOONCAKE_UBDIAG_SYSTEM_CLI "${MOONCAKE_UBDIAG_SYSTEM_CLI}")
+ if(MOONCAKE_UBDIAG_BUILD_CLI AND NOT TARGET UbDiag::ubdiag_cli)
+ add_executable(UbDiag::ubdiag_cli IMPORTED GLOBAL)
+ set_target_properties(UbDiag::ubdiag_cli PROPERTIES
+ IMPORTED_LOCATION "${_MOONCAKE_UBDIAG_SYSTEM_CLI}")
+ endif()
+ if(MOONCAKE_UBDIAG_BUILD_CLI AND NOT TARGET mooncake_ubdiag_cli)
+ add_custom_target(mooncake_ubdiag_cli ALL
+ DEPENDS "${_MOONCAKE_UBDIAG_SYSTEM_CLI}")
+ endif()
+ else()
+ set(_MOONCAKE_UBDIAG_SYSTEM_CLI "")
+ if(MOONCAKE_UBDIAG_BUILD_CLI)
+ message(WARNING "UbDiag: system package found, but ubdiag CLI was not found under standard system paths")
+ endif()
+ endif()
+
+ find_file(MOONCAKE_UBDIAG_SYSTEM_CONFIG
+ NAMES ubdiag.conf
+ HINTS ${_MOONCAKE_UBDIAG_CONFIG_HINTS}
+ PATHS /etc/ubdiag /usr/local/etc/ubdiag
+ NO_DEFAULT_PATH)
+ if(MOONCAKE_UBDIAG_SYSTEM_CONFIG
+ AND NOT MOONCAKE_UBDIAG_SYSTEM_CONFIG MATCHES "-NOTFOUND$")
+ set(_MOONCAKE_UBDIAG_SYSTEM_CONFIG "${MOONCAKE_UBDIAG_SYSTEM_CONFIG}")
+ else()
+ set(_MOONCAKE_UBDIAG_SYSTEM_CONFIG "")
+ endif()
+
+ _mooncake_ubdiag_write_rpm_manifest(
+ "system"
+ "${_MOONCAKE_UBDIAG_SYSTEM_CLI}"
+ "${_MOONCAKE_UBDIAG_SYSTEM_LIBRARY}"
+ "${_MOONCAKE_UBDIAG_SYSTEM_CONFIG}")
+ message(STATUS "UbDiag: using system package (CLI=${_MOONCAKE_UBDIAG_SYSTEM_CLI})")
+ return()
+ endif()
+endif()
+
+# Layer 3: Mock fallback (no-op PerfPoint, guarantees compilation)
+add_library(ubdiag_mock INTERFACE)
+target_include_directories(
+ ubdiag_mock INTERFACE ${CMAKE_SOURCE_DIR}/mooncake-common/ubdiag-mock)
+add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock)
+_mooncake_ubdiag_write_rpm_manifest("mock" "" "" "")
+message(STATUS "UbDiag: using mock (no-op PerfPoint)")
diff --git a/mooncake-common/common.cmake b/mooncake-common/common.cmake
index d20b2ccdb2..a87cce5c86 100644
--- a/mooncake-common/common.cmake
+++ b/mooncake-common/common.cmake
@@ -1,7 +1,7 @@
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Wno-unused-parameter -fPIC")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -Wextra -Wno-unused-parameter -Wno-error=maybe-uninitialized -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -Wextra -Wno-unused-parameter -fPIC")
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
@@ -80,7 +80,6 @@ option(USE_EFA "option for using AWS EFA transport" OFF)
option(USE_UB "option for using UB protocol transport" OFF)
if (USE_UB)
- add_compile_definitions(USE_UB)
message(STATUS "ub transport is enabled")
include(${CMAKE_CURRENT_LIST_DIR}/FindUrma.cmake)
endif()
diff --git a/mooncake-common/ubdiag-mock/README.md b/mooncake-common/ubdiag-mock/README.md
new file mode 100644
index 0000000000..8e98b03e00
--- /dev/null
+++ b/mooncake-common/ubdiag-mock/README.md
@@ -0,0 +1,158 @@
+# UbDiag Mock — Mooncake 集成说明
+
+本目录是 Mooncake 项目的 UbDiag header-only mock,提供空操作的 PerfPoint,
+确保在未安装 UbDiag 的情况下 Mooncake 仍可正常编译。
+
+## 四种情况:用户拿到 Mooncake 后,每一步发生了什么
+
+### 情况 A:`git clone --recursive` — 完整 submodule 路径
+
+**Step 1 — git clone**:`--recursive` 触发 Git 读取 `.gitmodules`,自动拉取三个 submodule:
+```
+extern/pybind11/ ← 已拉取
+extern/yalantinglibs/ ← 已拉取
+extern/ubdiag/ ← 已拉取,commit f0a4a13(v0.4.0-56)
+```
+
+**Step 2 — cmake**:CMake 执行到 `FindUbDiag.cmake`,按顺序判断:
+```
+if(TARGET UbDiag::ubdiag_lib) → 否,第一次执行
+if(EXISTS "extern/ubdiag/CMakeLists.txt") → 是 → add_subdirectory(real ubdiag)
+```
+输出:`UbDiag: using submodule (extern/ubdiag)`,return。
+
+`EXCLUDE_FROM_ALL` 保证只编译 `ubdiag_lib` 自身,不编译它的 30+ 个单元测试和 examples。
+
+**Step 3 — make**:`real_client.cpp` 中 `#include "ubdiag/auto_perf.h"` 找到真实 UbDiag,`PerfPoint::Start()/End()` 走 SHM 写入,性能数据可被 `ubdiag watch` 实时采集。
+
+---
+
+### 情况 B:`git clone`(无 `--recursive`)— mock 回退路径
+
+**Step 1 — git clone**:只拉 Mooncake 自有代码。`extern/ubdiag/` 目录不存在。
+
+**Step 2 — cmake**:`FindUbDiag.cmake` 按顺序判断:
+```
+if(TARGET UbDiag::ubdiag_lib) → 否
+if(EXISTS "extern/ubdiag/CMakeLists.txt") → 否,目录不存在
+find_package(UbDiag QUIET) → 否,系统没装
+→ 走 Layer 3:创建 header-only INTERFACE library
+```
+```cmake
+add_library(ubdiag_mock INTERFACE) # 没有 .cpp,只暴露头文件路径
+add_library(UbDiag::ubdiag_lib ALIAS ubdiag_mock)
+```
+输出:`UbDiag: using mock (no-op PerfPoint)`。
+
+**Step 3 — make**:编译器展开 `PerfPoint::Start()` / `End()` 的两个空函数体:
+```cpp
+void Start() {} // 编译器 -O1 以上:零指令
+void End(int = 0) {} // 同上
+```
+93+ 处 `PerfPoint(...)` 调用全部优化为空操作。Mooncake 完整编译运行,无需 systemtap-sdt-dev、libbpf 等任何 UbDiag 依赖。
+
+---
+
+### 情况 C:已有 clone(无 submodule),后来补拉
+
+**Step 1 — git submodule update**:`extern/ubdiag/` 从不存在变为存在,Git 拉取 commit `f0a4a13`。
+
+```bash
+git submodule update --init --recursive
+```
+
+**Step 2 — 重新 cmake + make**:`FindUbDiag.cmake` 再次执行时 `EXISTS "extern/ubdiag/CMakeLists.txt"` 从 false 变成 true,Layer 1 命中。mock → submodule 切换自动完成,**不需要改任何 cmake 参数。**
+
+```bash
+cd build && cmake .. && make -j
+```
+
+---
+
+### 情况 D:CI 环境已系统预装 UbDiag
+
+**Step 1 — 系统预装**:运维已通过 RPM 或 `make install` 部署 `libubdiag.so` + `UbDiagConfig.cmake`。
+
+```bash
+cd ubdiag && bash build.sh -r && cd build && sudo make install
+```
+
+**Step 2 — cmake**:`FindUbDiag.cmake` 执行时 Layer 1 未命中(submodule 不存在),但 Layer 2 `find_package(UbDiag QUIET)` 成功发现系统 .so。输出 `UbDiag: using system package`。链接系统 .so,不编译 submodule。适用于 CI/CD 等已预装环境。
+
+## 用户操作指南
+
+作为 Mooncake 新用户,**你不需要做任何选择**。
+
+| 你的操作 | 结果 | 编译期日志 |
+|---|---|---|
+| `git clone --recursive` | 使用真实 UbDiag (submodule),性能诊断完整可用 | `UbDiag: using submodule` |
+| `git clone`(不拉 submodule) | 使用本目录 mock,性能探针静默失效,核心功能不受影响 | `UbDiag: using mock` |
+| `git clone` + `git submodule update --init` | 从 mock 切换到 submodule | `UbDiag: using submodule` |
+| 系统已预装 UbDiag | 链接系统 .so,不编译 submodule | `UbDiag: using system package` |
+
+以上路径全自动,由 `mooncake-common/FindUbDiag.cmake` 检测路径是否存在决定,**不需要传任何 cmake 参数或环境变量**。
+
+### 路径 1:全新 clone(推荐,一步到位)
+
+```bash
+git clone --recursive
+cd Mooncake && mkdir build && cd build
+cmake .. && make -j
+```
+
+`--recursive` 自动拉取三个 submodule(pybind11 / yalantinglibs / ubdiag),CMake 自动检测编译。
+
+### 路径 2:已有 clone,补拉 submodule
+
+```bash
+cd Mooncake
+git submodule update --init --recursive # 拉取 ubdiag 等 submodule
+cd build && cmake .. && make -j
+```
+
+### 路径 3:不拉 submodule,也能编译(完全不使用 UbDiag)
+
+普通 `git clone`(不带 `--recursive`、不执行 `submodule update`)直接 cmake 编译即可,不需要做任何额外操作。
+CMake 自动回退至本目录的 header-only mock,编译期输出 `UbDiag: using mock`:
+- 所有 `PerfPoint` 调用编译为空操作,零运行时开销
+- 不依赖任何 UbDiag 的 .so 或头文件,不需要安装 systemtap-sdt-dev、libbpf 等依赖
+- Mooncake 核心功能完整运行,仅性能探针失效
+
+### 路径 4(可选):系统预装 UbDiag
+
+```bash
+cd ubdiag && bash build.sh -r && cd build && sudo make install
+cd Mooncake && mkdir build && cd build
+cmake .. && make -j
+```
+
+CMake 通过 `find_package(UbDiag)` 自动发现系统已安装的库。适用于 CI/CD 等已预装环境。
+
+## 三层优先级
+
+```
+submodule (extern/ubdiag) > system package (find_package QUIET) > mock fallback (本目录)
+```
+
+每个 `include(FindUbDiag.cmake)` 开头有 `if(TARGET ...) return()`,多次 include 幂等。
+
+## 文件说明
+
+| 文件 | 用途 |
+|---|---|
+| `ubdiag/auto_perf.h` | Header-only mock,提供空操作 PerfPoint 和 PerfKey/PerfLevel 定义 |
+
+## PerfLevel 对齐
+
+本 mock 的 PerfLevel 枚举值与真实 UbDiag v0.4.0 保持一致:
+
+```cpp
+#include
+
+enum class PerfLevel : uint8_t {
+ SUB_SYSTEM = 1,
+ KEY_MODULE = 2,
+ MODULE = 3,
+ DEBUG = 4,
+};
+```
diff --git a/mooncake-common/ubdiag-mock/ubdiag/auto_perf.h b/mooncake-common/ubdiag-mock/ubdiag/auto_perf.h
new file mode 100644
index 0000000000..9a3f883729
--- /dev/null
+++ b/mooncake-common/ubdiag-mock/ubdiag/auto_perf.h
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: Apache-2.0
+// Copyright 2024-present Mooncake contributors
+//
+// Header-only mock for UbDiag. Provides no-op PerfPoint and PerfKey
+// definitions so the codebase compiles without the UbDiag library.
+// All perf instrumentation becomes a no-op.
+//
+// Differences from the real extern/ubdiag/include/ubdiag/auto_perf.h:
+// - PerfKey values are all 0 (mock doesn't need unique slot indices).
+// - No auto-init static initializer (mock has no SHM, no PerfManager).
+// - PerfLevel / PerfPoint are no-ops (no SHM writes).
+
+#pragma once
+
+#include
+#include
+
+// Process the perf-key definition file to populate the PerfKey enum.
+// UBDIAG_PERF_DEF_FILE must be defined by the includer before this header.
+enum class PerfKey : int {
+// All keys map to 0 — mock PerfPoint ignores the key entirely.
+#define PERF_KEY_DEF(name, file, label) name = 0,
+#include UBDIAG_PERF_DEF_FILE
+#undef PERF_KEY_DEF
+};
+
+namespace UbDiag {
+
+enum class PerfLevel : uint8_t {
+ SUB_SYSTEM = 1,
+ KEY_MODULE = 2,
+ MODULE = 3,
+ DEBUG = 4,
+};
+
+class PerfPoint {
+ public:
+ explicit PerfPoint(uint32_t slotIndex, PerfLevel level) {
+ (void)slotIndex;
+ (void)level;
+ }
+
+ // Template constructor: accepts any enum type (zero-overhead in real
+ // UbDiag). Mock forwards to the no-op core constructor.
+ template >>
+ explicit PerfPoint(E key, PerfLevel level = PerfLevel::SUB_SYSTEM)
+ : PerfPoint(static_cast(key), level) {}
+
+ ~PerfPoint() {}
+
+ void Start() {}
+ void End(int /*rc*/ = 0) {}
+ void Abandon() {}
+};
+
+} // namespace UbDiag
diff --git a/mooncake-integration/CMakeLists.txt b/mooncake-integration/CMakeLists.txt
index 6ee283eda7..a805fda8de 100644
--- a/mooncake-integration/CMakeLists.txt
+++ b/mooncake-integration/CMakeLists.txt
@@ -101,7 +101,7 @@ if(WITH_STORE)
store/store_py.cpp 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..03efd1884a 100644
--- a/mooncake-p2p-store/CMakeLists.txt
+++ b/mooncake-p2p-store/CMakeLists.txt
@@ -2,7 +2,15 @@
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}
+ 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 24f3346dc3..b3dc1269fe 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,26 @@ 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 -ljsoncpp -lmooncake_common"
+EXT_LDFLAGS+=" -ltransfer_engine"
+
+case "$UBDIAG_LAYER" in
+ submodule)
+ UBDIAG_LIB_DIR="$BUILD_DIR/extern/ubdiag_build/src/sdk"
+ EXT_LDFLAGS+=" -L$UBDIAG_LIB_DIR -lubdiag"
+ ;;
+ system)
+ EXT_LDFLAGS+=" -lubdiag"
+ ;;
+ mock)
+ echo "P2P Store: using UbDiag mock; skipping -lubdiag"
+ ;;
+ *)
+ echo "Error: Unknown UbDiag layer: $UBDIAG_LAYER"
+ exit 1
+ ;;
+esac
+
+EXT_LDFLAGS+=" -lbase -lasio -lstdc++ -lnuma -lglog -libverbs -ljsoncpp -lmooncake_common"
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 cad2e73a63..fc8293abd9 100644
--- a/mooncake-store/src/CMakeLists.txt
+++ b/mooncake-store/src/CMakeLists.txt
@@ -247,8 +247,8 @@ target_link_libraries(
${EXTRA_LIBS} ${SPDK_STATIC_LIBS} asio_shared mooncake_common
PRIVATE transfer_engine)
-# UbDiag instrumentation
-find_package(UbDiag REQUIRED)
+# UbDiag instrumentation (resolved by FindUbDiag.cmake: submodule > system > mock)
+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-store/src/master.cpp b/mooncake-store/src/master.cpp
index 0a552f8334..d0f80f78e2 100644
--- a/mooncake-store/src/master.cpp
+++ b/mooncake-store/src/master.cpp
@@ -963,7 +963,7 @@ int main(int argc, char* argv[]) {
gflags::SetVersionString(mooncake::MOONCAKE_DISPLAY_VERSION);
gflags::ParseCommandLineFlags(&argc, &argv, true);
- if (!FLAGS_log_dir.empty()) {
+ if (!FLAGS_log_dir.empty() && !google::IsGoogleLoggingInitialized()) {
google::InitGoogleLogging(argv[0]);
}
mooncake::logging::ApplyMooncakeLogEnableToGlog();
diff --git a/mooncake-store/src/real_client_main.cpp b/mooncake-store/src/real_client_main.cpp
index e1f6d257ef..220cbfbb41 100644
--- a/mooncake-store/src/real_client_main.cpp
+++ b/mooncake-store/src/real_client_main.cpp
@@ -98,7 +98,7 @@ int main(int argc, char *argv[]) {
mooncake::ResourceTracker::getInstance();
gflags::ParseCommandLineFlags(&argc, &argv, true);
- if (!FLAGS_log_dir.empty()) {
+ if (!FLAGS_log_dir.empty() && !google::IsGoogleLoggingInitialized()) {
google::InitGoogleLogging(argv[0]);
}
mooncake::logging::ApplyMooncakeLogEnableToGlog();
diff --git a/mooncake-transfer-engine/src/CMakeLists.txt b/mooncake-transfer-engine/src/CMakeLists.txt
index ce95cf612d..a64d0bbc3d 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)
@@ -148,6 +148,9 @@ if(USE_EFA)
target_link_libraries(transfer_engine PUBLIC fabric efa_transport)
endif()
if(USE_UB)
+ target_compile_definitions(transfer_engine PUBLIC USE_UB)
message(STATUS "Enabled USE_UB protocol support")
target_link_libraries(transfer_engine PUBLIC ub_transport)
+ target_compile_definitions(transfer_engine PUBLIC USE_UB)
+ target_compile_definitions(ub_transport PRIVATE USE_UB)
endif()
diff --git a/mooncake-transfer-engine/src/config.cpp b/mooncake-transfer-engine/src/config.cpp
index b4e4252285..6e252a6855 100644
--- a/mooncake-transfer-engine/src/config.cpp
+++ b/mooncake-transfer-engine/src/config.cpp
@@ -274,9 +274,13 @@ void loadGlobalConfig(GlobalConfig& config) {
const char* log_dir_path = std::getenv("MC_LOG_DIR");
if (log_dir_path) {
- if (!google::IsGoogleLoggingInitialized()) {
- google::InitGoogleLogging("mooncake-transfer-engine");
- }
+ // NOTE: Do NOT call InitGoogleLogging() here. This function may
+ // execute during static initialization (e.g. via ub_context.cpp's
+ // file-scope globalConfig() call). If we init glog here and main()
+ // inits it again, we get a fatal "You called InitGoogleLogging()
+ // twice!" abort. Instead, just forward the desired log directory
+ // to glog's flags; the actual InitGoogleLogging() call belongs in
+ // each binary's main() (master / client / bench).
if (opendir(log_dir_path) == NULL) {
LOG(WARNING)
<< "Path [" << log_dir_path
diff --git a/scripts/build_rpm.sh b/scripts/build_rpm.sh
index e41b241d26..08dd397637 100755
--- a/scripts/build_rpm.sh
+++ b/scripts/build_rpm.sh
@@ -10,10 +10,19 @@ 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_ABS="${OUTPUT_DIR}"
+else
+ OUTPUT_DIR_ABS="$(pwd)/${OUTPUT_DIR}"
+fi
# Detect current host architecture
HOST_ARCH=$(uname -m)
@@ -44,12 +53,13 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${BUILD_DIR_ABS}/mooncake-common:/usr/lo
# Clean previous build
echo "Cleaning previous RPM build..."
rm -rf rpmbuild/
-rm -rf ${OUTPUT_DIR}/
+rm -rf ${OUTPUT_DIR_ABS}/
# Function to build RPM for a specific platform
build_rpm_for_platform() {
local PLATFORM=$1
local LIB_DIR="lib64"
+ local UBDIAG_RPM_FILES=""
echo "Building RPM for platform: ${PLATFORM}"
@@ -68,7 +78,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},etc/{mooncake,ubdiag}}
# -------------------------------------------------------------------------
# Copy executables
@@ -170,6 +180,109 @@ build_rpm_for_platform() {
else
echo "Warning: store.so not found in ${PLATFORM_BUILD_DIR}, skipping..."
fi
+
+ # UbDiag runtime artifacts. L1 packages the vendored build output. L2 packages
+ # the customer-provided system UbDiag selected by FindUbDiag.cmake. The CLI
+ # and libubdiag must come from the same layer so feature flags and shared
+ # memory layout stay in sync. Do not package UbDiag headers or CMake package
+ # metadata here: Layer 2 must remain a customer-provided system package.
+ local UBDIAG_BUILD_DIR="${PLATFORM_BUILD_DIR}/extern/ubdiag_build"
+ local UBDIAG_RPM_MANIFEST="${PLATFORM_BUILD_DIR}/mooncake_ubdiag_rpm.env"
+ local MOONCAKE_UBDIAG_LAYER=""
+ local MOONCAKE_UBDIAG_CLI_PATH=""
+ local MOONCAKE_UBDIAG_LIBRARY_PATH=""
+ local MOONCAKE_UBDIAG_CONFIG_PATH=""
+
+ if [ -f "${UBDIAG_RPM_MANIFEST}" ]; then
+ echo "Reading UbDiag RPM manifest: ${UBDIAG_RPM_MANIFEST}"
+ . "${UBDIAG_RPM_MANIFEST}"
+ fi
+
+ if { [ -z "${MOONCAKE_UBDIAG_LAYER}" ] || [ "${MOONCAKE_UBDIAG_LAYER}" = "submodule" ]; } && [ -d "${UBDIAG_BUILD_DIR}" ]; then
+ echo "Copying vendored UbDiag CLI and SDK runtime library..."
+
+ if [ -f "${UBDIAG_BUILD_DIR}/src/cli/ubdiag" ]; then
+ cp "${UBDIAG_BUILD_DIR}/src/cli/ubdiag" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/
+ chmod 755 rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ubdiag
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+/usr/bin/ubdiag"
+ else
+ echo "Error: vendored UbDiag build found, but ${UBDIAG_BUILD_DIR}/src/cli/ubdiag is missing"
+ return 1
+ fi
+
+ if compgen -G "${UBDIAG_BUILD_DIR}/src/sdk/libubdiag.so*" >/dev/null; then
+ for ubdiag_lib in "${UBDIAG_BUILD_DIR}"/src/sdk/libubdiag.so*; do
+ cp "${ubdiag_lib}" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/
+ done
+ chmod 755 rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libubdiag.so* 2>/dev/null || true
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+/usr/${LIB_DIR}/libubdiag.so*"
+ elif [ -f "${UBDIAG_BUILD_DIR}/src/sdk/libubdiag.a" ]; then
+ cp "${UBDIAG_BUILD_DIR}/src/sdk/libubdiag.a" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+/usr/${LIB_DIR}/libubdiag.a"
+ else
+ echo "Error: vendored UbDiag build found, but libubdiag was not built under ${UBDIAG_BUILD_DIR}/src/sdk"
+ return 1
+ fi
+
+ if [ -f extern/ubdiag/config/ubdiag.conf.example ]; then
+ cp extern/ubdiag/config/ubdiag.conf.example rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/ubdiag/ubdiag.conf
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+%config(noreplace) /etc/ubdiag/ubdiag.conf"
+ else
+ echo "Warning: extern/ubdiag/config/ubdiag.conf.example not found, skipping UbDiag config..."
+ fi
+ elif [ "${MOONCAKE_UBDIAG_LAYER}" = "system" ]; then
+ echo "Copying system UbDiag CLI and SDK runtime library selected by Layer 2..."
+
+ if [ -z "${MOONCAKE_UBDIAG_CLI_PATH}" ] || [ ! -f "${MOONCAKE_UBDIAG_CLI_PATH}" ]; then
+ echo "Error: Layer 2 selected system UbDiag, but ubdiag CLI was not found"
+ echo " Expected CLI path from manifest: ${MOONCAKE_UBDIAG_CLI_PATH}"
+ return 1
+ fi
+
+ cp "${MOONCAKE_UBDIAG_CLI_PATH}" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ubdiag
+ chmod 755 rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/bin/ubdiag
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+/usr/bin/ubdiag"
+
+ local UBDIAG_SYSTEM_LIB_DIR=""
+ if [ -n "${MOONCAKE_UBDIAG_LIBRARY_PATH}" ] && [ -e "${MOONCAKE_UBDIAG_LIBRARY_PATH}" ]; then
+ UBDIAG_SYSTEM_LIB_DIR="$(dirname "${MOONCAKE_UBDIAG_LIBRARY_PATH}")"
+ fi
+ if [ -z "${UBDIAG_SYSTEM_LIB_DIR}" ] || ! compgen -G "${UBDIAG_SYSTEM_LIB_DIR}/libubdiag.so*" >/dev/null; then
+ for ubdiag_lib_dir in /usr/lib64 /usr/local/lib64 /usr/lib /usr/local/lib; do
+ if compgen -G "${ubdiag_lib_dir}/libubdiag.so*" >/dev/null; then
+ UBDIAG_SYSTEM_LIB_DIR="${ubdiag_lib_dir}"
+ break
+ fi
+ done
+ fi
+ if [ -z "${UBDIAG_SYSTEM_LIB_DIR}" ] || ! compgen -G "${UBDIAG_SYSTEM_LIB_DIR}/libubdiag.so*" >/dev/null; then
+ echo "Error: Layer 2 selected system UbDiag, but libubdiag.so* was not found"
+ echo " Expected library path from manifest: ${MOONCAKE_UBDIAG_LIBRARY_PATH}"
+ return 1
+ fi
+
+ for ubdiag_lib in "${UBDIAG_SYSTEM_LIB_DIR}"/libubdiag.so*; do
+ cp -P "${ubdiag_lib}" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/
+ done
+ chmod 755 rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/usr/${LIB_DIR}/libubdiag.so* 2>/dev/null || true
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+/usr/${LIB_DIR}/libubdiag.so*"
+
+ if [ -n "${MOONCAKE_UBDIAG_CONFIG_PATH}" ] && [ -f "${MOONCAKE_UBDIAG_CONFIG_PATH}" ]; then
+ cp "${MOONCAKE_UBDIAG_CONFIG_PATH}" rpmbuild/BUILDROOT/${PACKAGE_NAME}-${PACKAGE_VERSION}-${PACKAGE_RELEASE}.${PLATFORM}/etc/ubdiag/ubdiag.conf
+ UBDIAG_RPM_FILES="${UBDIAG_RPM_FILES}
+%config(noreplace) /etc/ubdiag/ubdiag.conf"
+ else
+ echo "Warning: Layer 2 system UbDiag config not found, skipping UbDiag config..."
+ fi
+ else
+ echo "UbDiag layer is '${MOONCAKE_UBDIAG_LAYER:-unknown}', skipping UbDiag CLI packaging..."
+ fi
# -------------------------------------------------------------------------
# Copy header files (only core headers for real_client and dummy_client)
@@ -324,6 +437,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
@@ -352,16 +466,16 @@ EOF
fi
# Create platform-specific output directory
- mkdir -p ${OUTPUT_DIR}/${PLATFORM}
+ mkdir -p ${OUTPUT_DIR_ABS}/${PLATFORM}
# Build the RPM
rpmbuild -bb \
--define "_topdir $(pwd)/rpmbuild" \
- --define "_rpmdir $(pwd)/${OUTPUT_DIR}" \
+ --define "_rpmdir ${OUTPUT_DIR_ABS}" \
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_ABS}/${PLATFORM}/*.rpm ${OUTPUT_DIR_ABS}/ 2>/dev/null || true
# Cleanup BUILDROOT for next platform
rm -rf rpmbuild/BUILDROOT/
@@ -395,7 +509,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_ABS}/*.rpm 2>/dev/null || echo "No RPM files created"
# Cleanup
-rm -rf rpmbuild/
\ No newline at end of file
+rm -rf rpmbuild/