Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ PATCHES_DIR := $(REPO_ROOT)/patches
SCRIPTS_DIR := $(REPO_ROOT)/scripts
BUILD_DIR := $(REPO_ROOT)/build
TARGET_DIR := $(REPO_ROOT)/$(SONIC_REDFISH_TARGET)
RMC_EVENTS_DIR := $(REPO_ROOT)/rmc-events
SERIES_FILE := $(PATCHES_DIR)/series
DEBIAN_DIR := $(BMCWEB_DIR)/debian

Expand All @@ -37,7 +38,7 @@ DOCKERFILE_BUILD := $(BUILD_DIR)/Dockerfile.build
MAIN_TARGET := $(BMCWEB_BINARY)
DERIVED_TARGETS := $(BRIDGE_BINARY)

.PHONY: all build clean reset setup-bmcweb copy-patches apply-patches build-bmcweb build-bridge build-bmcweb-native build-bridge-native build-in-docker help
.PHONY: all build clean reset setup-bmcweb copy-patches copy-rmc-events apply-patches build-bmcweb build-bridge build-bmcweb-native build-bridge-native build-in-docker help

# Default target - Build both components (via Docker)
all: build
Expand Down Expand Up @@ -96,7 +97,7 @@ build: $(DOCKERFILE_BUILD)
-v "$(REPO_ROOT):/workspace" \
-w /workspace \
-e SONIC_CONFIG_MAKE_JOBS=$(SONIC_CONFIG_MAKE_JOBS) \
$(DOCKER_BUILDER_IMAGE) \
$(DOCKER_BUILDER_IMAGE)\
bash -c "\
set -e; \
git config --global --add safe.directory /workspace; \
Expand Down Expand Up @@ -145,8 +146,22 @@ copy-patches: $(SERIES_FILE)
@# Note: Patches will create debian/ directory, so we only copy series file after patches are applied
@echo " Patches will be applied from $(PATCHES_DIR)"

# Copy rmc-events source files into bmcweb tree before patches are applied.
# The integration patch (0003) wires these files into the bmcweb build but
# does not contain the file contents -- they live in rmc-events/.
copy-rmc-events: setup-bmcweb
@echo "Copying rmc-events sources into bmcweb tree..."
@if [ -d "$(RMC_EVENTS_DIR)" ]; then \
cp -v $(RMC_EVENTS_DIR)/lib/*.hpp $(BMCWEB_DIR)/redfish-core/lib/ 2>/dev/null || true; \
cp -v $(RMC_EVENTS_DIR)/include/*.hpp $(BMCWEB_DIR)/redfish-core/include/ 2>/dev/null || true; \
cp -v $(RMC_EVENTS_DIR)/src/*.cpp $(BMCWEB_DIR)/redfish-core/src/ 2>/dev/null || true; \
echo " rmc-events files copied"; \
else \
echo " No rmc-events directory found, skipping"; \
fi

# Apply patches using series file
apply-patches: setup-bmcweb
apply-patches: setup-bmcweb copy-rmc-events
@echo "Applying patches from series file..."
@if [ ! -d "$(BMCWEB_DIR)" ]; then \
echo "Error: bmcweb directory not found"; \
Expand Down Expand Up @@ -280,6 +295,7 @@ build-bmcweb-native:
@mv $(REPO_ROOT)/bmcweb_*.changes $(TARGET_DIR)/ 2>/dev/null || true
@mv $(REPO_ROOT)/bmcweb_*.buildinfo $(TARGET_DIR)/ 2>/dev/null || true
@mv $(REPO_ROOT)/bmcweb_*.dsc $(TARGET_DIR)/ 2>/dev/null || true
@mv $(REPO_ROOT)/bmcweb_*.tar.gz $(TARGET_DIR)/ 2>/dev/null || true
@echo ""
@echo "========================================="
@echo "bmcweb build complete!"
Expand Down Expand Up @@ -357,9 +373,16 @@ clean:
@if [ -d "$(BMCWEB_DIR)" ]; then sudo chown -R $$(id -u):$$(id -g) $(BMCWEB_DIR) 2>/dev/null || true; fi
@sudo chown -R $$(id -u):$$(id -g) $(BRIDGE_DIR) 2>/dev/null || true

# Wipe bmcweb build state completely. With git, a hard reset + clean -fdx
# is exhaustive: reverts patched files and removes obj-*, debian/,
# subprojects/<wrapped-clones>, and anything else untracked or ignored.
# Clean host-owned files
@echo "Cleaning package artifacts..."
@rm -rf $(BMCWEB_DIR)/debian 2>/dev/null || true
@rm -rf $(BRIDGE_DIR)/build 2>/dev/null || true
@rm -f $(REPO_ROOT)/*.deb $(REPO_ROOT)/*.changes $(REPO_ROOT)/*.buildinfo $(REPO_ROOT)/*.dsc $(REPO_ROOT)/*.tar.gz 2>/dev/null || true
@echo " Removed package artifacts from root directory"

# Reset bmcweb source to clean state (so patches can be reapplied)
# git clean -fd also removes rmc-events copies (untracked files)
@echo "Resetting bmcweb source to clean state..."
@if [ -d "$(BMCWEB_DIR)/.git" ]; then \
echo "Resetting bmcweb source tree..."; \
cd $(BMCWEB_DIR) && git reset --hard HEAD && git clean -ffdx; \
Expand Down
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ The build system is designed for **Debian Trixie** and uses:

1. **Docker-based builds**: All compilation happens inside a `debian:trixie` container for consistency
2. **Debian packaging**: Uses `dpkg-buildpackage` to create `.deb` packages
3. **Meson subprojects**: Dependencies (sdbusplus, stdexec) are managed via `.wrap` files
3. **Meson subprojects**: sdbusplus is pre-built in the Docker image; other dependencies are managed via `.wrap` files
4. **Automatic dependencies**: Build targets automatically trigger required cleanup and setup steps
5. **Patch management**: Uses a `patches/series` file to define patch order

Expand All @@ -110,7 +110,7 @@ make all
- Apply patches from patches/series to bmcweb source

4. Build sonic-dbus-bridge
- Meson downloads dependencies (sdbusplus, stdexec) via .wrap files
- Uses pre-installed sdbusplus from Docker image
- dpkg-buildpackage creates .deb packages

5. Build bmcweb
Expand Down Expand Up @@ -166,18 +166,21 @@ To add a new patch:

## Dependency Management

Dependencies are managed via **Meson wrap files** (`.wrap`):
**sdbusplus** (OpenBMC D-Bus C++ bindings) is pre-built and installed in the Docker
image (`build/Dockerfile.build`). Both bmcweb and sonic-dbus-bridge find it via
pkg-config at build time. The pinned sdbusplus and stdexec commits are configured
as `ARG` directives in the Dockerfile.

Other dependencies are managed via **Meson wrap files** (`.wrap`):

### bmcweb dependencies:
- `bmcweb/subprojects/sdbusplus.wrap` - D-Bus C++ bindings
- `bmcweb/subprojects/stdexec.wrap` - C++23 executors
- `bmcweb/subprojects/sdbusplus.wrap` - D-Bus C++ bindings (fallback; prefers system package)
- Plus other dependencies defined in bmcweb upstream

### sonic-dbus-bridge dependencies:
- `sonic-dbus-bridge/subprojects/sdbusplus.wrap` - D-Bus C++ bindings
- `sonic-dbus-bridge/subprojects/stdexec.wrap` - C++23 executors
- `sonic-dbus-bridge/subprojects/sdbusplus.wrap` - D-Bus C++ bindings (fallback; prefers system package)

Meson automatically downloads and builds these dependencies during the build process.
Meson automatically downloads and builds subproject dependencies during the build process.

The Debian packages can be installed in SONiC images.

Expand Down
21 changes: 21 additions & 0 deletions build/Dockerfile.build
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ RUN apt-get update && apt-get install -y \
libboost-url-dev \
libboost-dev \
nlohmann-json3-dev \
libcap-dev \
dbus \
ninja-build \
cmake \
Expand All @@ -36,6 +37,26 @@ RUN apt-get update && apt-get install -y \
python3-inflection \
&& rm -rf /var/lib/apt/lists/*

# Pre-build and install sdbusplus as a system library.
# This avoids fetching NVIDIA/stdexec during the main build — stdexec is only
# needed to compile sdbusplus's async subsystem, and the installed pkg-config
# file does not expose it as a public dependency.
ARG SDBUSPLUS_COMMIT=a74f63b1903c8b00d9c134164eaa4ac8e925d0f5
ARG STDEXEC_COMMIT=91782e6cbfad5df74237bac139b5d61f6cf40313
RUN set -e \
&& git init /tmp/stdexec && cd /tmp/stdexec \
&& git remote add origin https://github.com/NVIDIA/stdexec.git \
&& git fetch --depth 1 origin ${STDEXEC_COMMIT} && git checkout FETCH_HEAD \
&& git init /tmp/sdbusplus && cd /tmp/sdbusplus \
&& git remote add origin https://github.com/openbmc/sdbusplus.git \
&& git fetch --depth 1 origin ${SDBUSPLUS_COMMIT} && git checkout FETCH_HEAD \
&& cp -r /tmp/stdexec /tmp/sdbusplus/subprojects/stdexec \
&& cd /tmp/sdbusplus \
&& meson setup build --prefix=/usr -Dtests=disabled -Dexamples=disabled \
&& ninja -C build \
&& ninja -C build install \
&& rm -rf /tmp/sdbusplus /tmp/stdexec

WORKDIR /workspace

CMD ["/bin/bash"]
124 changes: 124 additions & 0 deletions patches/0004-Integrate-rmc-events-leak-detection-into-bmcweb.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
Date: Mon, 07 Apr 2026 00:00:00 +0000
Subject: [PATCH] Integrate rmc-events leak detection into bmcweb

Wire rmc-events/ source files (copied into the bmcweb tree before this
patch is applied) into the bmcweb build:
- meson.build: add leak_detector_monitor.cpp to sources
- redfish.cpp: include leak_detection.hpp, register routes
- thermal_subsystem.hpp: add LeakDetection navigation link
- event_service.hpp: add "Environmental" and "LeakDetector" to
supported subscription filters
- event_service_manager.hpp: include and instantiate the
DbusLeakDetectorMonitor

No new file content in this patch -- the actual implementation lives
in the rmc-events/ directory and is copied by the build system.
---
meson.build | 1 +
redfish-core/include/event_service_manager.hpp | 8 ++++++++
redfish-core/lib/event_service.hpp | 8 ++++----
redfish-core/lib/thermal_subsystem.hpp | 4 ++++
redfish-core/src/redfish.cpp | 4 ++++
5 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/meson.build b/meson.build
index 00000001..00000002 100644
--- a/meson.build
+++ b/meson.build
@@ -383,6 +383,7 @@ srcfiles_bmcweb = files(
'redfish-core/src/event_log.cpp',
'redfish-core/src/filesystem_log_watcher.cpp',
'redfish-core/src/filter_expr_executor.cpp',
+ 'redfish-core/src/leak_detector_monitor.cpp',
'redfish-core/src/filter_expr_printer.cpp',
'redfish-core/src/heartbeat_messages.cpp',
'redfish-core/src/redfish.cpp',
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index 00000001..00000002 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -5,6 +5,7 @@

#include "dbus_log_watcher.hpp"
#include "error_messages.hpp"
+#include "leak_detector_monitor.hpp"
#include "event_logs_object_type.hpp"
#include "event_matches_filter.hpp"
#include "event_service_store.hpp"
@@ -57,6 +58,7 @@ class EventServiceManager
std::optional<DbusEventLogMonitor> dbusEventLogMonitor;
std::optional<DbusTelemetryMonitor> matchTelemetryMonitor;
std::optional<FilesystemLogWatcher> filesystemLogMonitor;
+ std::optional<DbusLeakDetectorMonitor> leakDetectorMonitor;
boost::container::flat_map<std::string, std::shared_ptr<Subscription>>
subscriptionsMap;

@@ -82,6 +84,11 @@ class EventServiceManager
{
// Load config from persist store.
initConfig();
+
+ // Always start the leak detector monitor so that D-Bus
+ // PropertiesChanged signals on leak sensors are forwarded
+ // as Redfish events to matching subscribers via sendEvent().
+ leakDetectorMonitor.emplace();
}

static EventServiceManager& getInstance()
diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp
index 00000001..00000002 100644
--- a/redfish-core/lib/event_service.hpp
+++ b/redfish-core/lib/event_service.hpp
@@ -49,11 +49,11 @@ namespace redfish

static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
eventFormatType, metricReportFormatType};
-static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
- "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
+static constexpr const std::array<const char*, 5> supportedRegPrefixes = {
+ "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent", "Environmental"};
static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
"TerminateAfterRetries", "SuspendRetries", "RetryForever"};

-static constexpr const std::array<const char*, 2> supportedResourceTypes = {
- "Task", "Heartbeat"};
+static constexpr const std::array<const char*, 3> supportedResourceTypes = {
+ "Task", "Heartbeat", "LeakDetector"};

diff --git a/redfish-core/lib/thermal_subsystem.hpp b/redfish-core/lib/thermal_subsystem.hpp
index 00000001..00000002 100644
--- a/redfish-core/lib/thermal_subsystem.hpp
+++ b/redfish-core/lib/thermal_subsystem.hpp
@@ -53,6 +53,11 @@ inline void doThermalSubsystemCollection(
asyncResp->res.jsonValue["ThermalMetrics"]["@odata.id"] =
boost::urls::format(
"/redfish/v1/Chassis/{}/ThermalSubsystem/ThermalMetrics",
chassisId);

+ asyncResp->res.jsonValue["LeakDetection"]["@odata.id"] =
+ boost::urls::format(
+ "/redfish/v1/Chassis/{}/ThermalSubsystem/LeakDetection",
+ chassisId);
+
asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
diff --git a/redfish-core/src/redfish.cpp b/redfish-core/src/redfish.cpp
index 00000001..00000002 100644
--- a/redfish-core/src/redfish.cpp
+++ b/redfish-core/src/redfish.cpp
@@ -20,6 +20,7 @@
#include "fabric_ports.hpp"
#include "fan.hpp"
#include "hypervisor_system.hpp"
+#include "leak_detection.hpp"
#include "log_services.hpp"
#include "manager_diagnostic_data.hpp"
#include "manager_logservices_dbus_eventlog.hpp"
@@ -100,4 +101,7 @@ requestRoutesThermalMetrics
requestRoutesThermalSubsystem(app);
requestRoutesFan(app);
+ requestRoutesLeakDetection(app);
+ requestRoutesLeakDetectorCollection(app);
+ requestRoutesLeakDetector(app);
}
requestRoutesManager(app);
34 changes: 34 additions & 0 deletions patches/0005-Add-libcap-dependency-for-static-libsystemd.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SONiC Team <sonic-dev@lists.sonic-net.org>
Date: Sun, 11 May 2026 00:00:00 +0000
Subject: [PATCH] Add libcap dependency for static libsystemd linking

When linking against libsystemd.a statically, the linker requires
libcap to resolve capability-related symbols (cap_set_flag, etc.)
used by systemd's capability-util.c.

This adds libcap as an explicit dependency to bmcweb_dependencies
to ensure proper linking in static build configurations.
---
meson.build | 3 +++
1 file changed, 3 insertions(+)

diff --git a/meson.build b/meson.build
index 00000000..11111111 100644
--- a/meson.build
+++ b/meson.build
@@ -289,7 +289,10 @@ libsystemd = dependency(
)

zlib = dependency('zlib')
-bmcweb_dependencies += [libsystemd, zlib]
+# libcap is needed when linking with static libsystemd.a
+cap = dependency('libcap', required: true)
+bmcweb_dependencies += [libsystemd, zlib, cap]
+

nlohmann_json_dep = dependency(
'nlohmann_json',
--
2.34.1

2 changes: 2 additions & 0 deletions patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@

0001-Integrating-bmcweb-with-SONiC-s-build-system.patch
0002-Add-Product-field-to-Redfish-service-root.patch
0004-Integrate-rmc-events-leak-detection-into-bmcweb.patch
0005-Add-libcap-dependency-for-static-libsystemd.patch

24 changes: 24 additions & 0 deletions rmc-events/include/leak_detector_monitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
///////////////////////////////////////
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2026 Nexthop AI
// Copyright (C) 2024 SONiC Project
// Author: Nexthop AI
// Author: SONiC Project
// License file: sonic-redfish/LICENSE
///////////////////////////////////////

#pragma once

#include <sdbusplus/bus/match.hpp>

namespace redfish
{

class DbusLeakDetectorMonitor
{
public:
DbusLeakDetectorMonitor();
sdbusplus::bus::match_t leakDetectorMonitor;
};

} // namespace redfish
Loading