platform-mc / libpldmresponder: Add bypass-terminus-discovery feature and fix event handler NACKs
This commit introduces a new platform configuration toggle to optimize
PLDM behavior for lightweight topologies (like crash dump listeners) and
resolves a critical variable shadowing bug inside the event responder stack.
1. Add `bypass-terminus-discovery` Meson toggle
For platforms that only need minimal event routing without massive DBus
footprints , this feature flag allows bypassing
the traditional heavy discovery phase:
- Skips PDR Polling: Short-circuits `getPDRs()` inside the platform
manager to suppress heavy I2C cross-traffic for unused sensors and effecters.
- Prevents Phantom Chassis Creation: Instantly aborts `createInventoryPath()`
in the terminus mapping, preventing bmcweb from blindly exposing the
bare terminus (e.g., `MCTP_0`) as a Redfish Chassis object.
2. Fix Completion Code shadowing in `platformEventMessage`
A variable shadowing bug (`auto rc = handler(...)`) within the active
event handler iteration loop previously resulted in failing handlers
falling through. This caused the BMC to illegally return `PLDM_SUCCESS`
(0x00) over the wire, even when handlers actively rejected a polled event.
The return code variable has been extracted to the outer scope so that any
handler failure now immediately breaks the loop and returns the proper NACK.
Tested:
https://paste.googleplex.com/6678851397222400
With the change we dont see any new entry under Chassis redfish
endpoint and crash dump feature is working fine as well.
Google-Bug-Id: 556580550
Change-Id: I1fcd2cce9fa268054028f3a868abb70863fba7d4
Signed-off-by: Vikram Gara <vikramgara@google.com>
diff --git a/libpldmresponder/platform.cpp b/libpldmresponder/platform.cpp
index b414704..c2f450f 100644
--- a/libpldmresponder/platform.cpp
+++ b/libpldmresponder/platform.cpp
@@ -855,19 +855,21 @@
try
{
const auto& handlers = eventHandlers.at(eventClass);
+ int handlerRc = PLDM_SUCCESS;
bool oneFailedHandler = false;
for (const auto& handler : handlers)
{
- auto rc =
+ handlerRc =
handler(request, payloadLength, formatVersion, tid, offset);
- if (rc != PLDM_SUCCESS)
+ if (handlerRc != PLDM_SUCCESS)
{
oneFailedHandler = true;
+ break;
}
}
if (oneFailedHandler)
{
- return CmdHandler::ccOnlyResponse(request, rc);
+ return CmdHandler::ccOnlyResponse(request, handlerRc);
}
}
catch (const std::out_of_range& e)
diff --git a/meson.build b/meson.build
index 53f24dd..e02ccb9 100644
--- a/meson.build
+++ b/meson.build
@@ -52,6 +52,9 @@
if get_option('sensor-polling').allowed()
conf_data.set('SENSOR_POLLING', 1)
endif
+if get_option('bypass-terminus-discovery').allowed()
+ conf_data.set('BYPASS_TERMINUS_DISCOVERY', 1)
+endif
if get_option('libpldmresponder').allowed()
conf_data.set_quoted('BIOS_JSONS_DIR', join_paths(package_datadir, 'bios'))
diff --git a/meson.options b/meson.options
index d7c8772..74cdb00 100644
--- a/meson.options
+++ b/meson.options
@@ -259,3 +259,10 @@
value: 'enabled',
description: 'Enable numeric sensor polling in platform-mc',
)
+
+option(
+ 'bypass-terminus-discovery',
+ type: 'feature',
+ value: 'disabled',
+ description: 'Bypass PDR fetching and chassis DBus creation for terminii',
+)
diff --git a/platform-mc/platform_manager.cpp b/platform-mc/platform_manager.cpp
index 548cb1a..a980741 100644
--- a/platform-mc/platform_manager.cpp
+++ b/platform-mc/platform_manager.cpp
@@ -56,6 +56,7 @@
}
}
+#ifndef BYPASS_TERMINUS_DISCOVERY
if (terminus->doesSupportCommand(PLDM_PLATFORM, PLDM_GET_PDR))
{
auto rc = co_await getPDRs(terminus);
@@ -69,6 +70,7 @@
terminus->parseTerminusPDRs();
}
+#endif
/**
* Need terminus name from PDRs before updating Inventory object with
diff --git a/platform-mc/sensor_manager.cpp b/platform-mc/sensor_manager.cpp
index 7a44a5a..31a8581 100644
--- a/platform-mc/sensor_manager.cpp
+++ b/platform-mc/sensor_manager.cpp
@@ -155,7 +155,7 @@
rcOpt = PLDM_SUCCESS;
}
}),
- exec::default_task_context<void>(exec::inline_scheduler{}));
+ exec::default_task_context<void>(stdexec::inline_scheduler{}));
}
exec::task<int> SensorManager::doSensorPollingTask(pldm_tid_t tid)
diff --git a/platform-mc/terminus.cpp b/platform-mc/terminus.cpp
index fdaacf4..2a25092 100644
--- a/platform-mc/terminus.cpp
+++ b/platform-mc/terminus.cpp
@@ -89,6 +89,13 @@
bool Terminus::createInventoryPath(std::string tName)
{
+#ifdef BYPASS_TERMINUS_DISCOVERY
+ // HACK: Immediately return false to prevent pldmd from exposing the
+ // terminus under /xyz/openbmc_project/inventory/system/board/ which bubbles
+ // up as a Redfish Chassis object (e.g., MCTP_0).
+ return false;
+#endif
+
if (tName.empty())
{
return false;
diff --git a/platform-mc/terminus_manager.cpp b/platform-mc/terminus_manager.cpp
index 5270da8..a111a54 100644
--- a/platform-mc/terminus_manager.cpp
+++ b/platform-mc/terminus_manager.cpp
@@ -170,7 +170,7 @@
auto& [scope, rcOpt] = discoverMctpTerminusTaskHandle.emplace();
scope.spawn(discoverMctpTerminusTask() |
stdexec::then([&](int rc) { rcOpt.emplace(rc); }),
- exec::default_task_context<void>(exec::inline_scheduler{}));
+ exec::default_task_context<void>(stdexec::inline_scheduler{}));
}
TerminiMapper::iterator TerminusManager::findTerminusPtr(
diff --git a/requester/test/handler_test.cpp b/requester/test/handler_test.cpp
index caa4663..a3c06e5 100644
--- a/requester/test/handler_test.cpp
+++ b/requester/test/handler_test.cpp
@@ -197,7 +197,7 @@
EXPECT_EQ(validResponse, true);
}),
- exec::default_task_context<void>(exec::inline_scheduler{}));
+ exec::default_task_context<void>(stdexec::inline_scheduler{}));
pldm::Response mockResponse(sizeof(pldm_msg_hdr) + sizeof(uint8_t), 0);
auto mockResponsePtr =
@@ -231,7 +231,7 @@
EXPECT_TRUE(false); // unreachable
}) | stdexec::upon_stopped([&] { stopped = true; }),
- exec::default_task_context<void>(exec::inline_scheduler{}));
+ exec::default_task_context<void>(stdexec::inline_scheduler{}));
scope.request_stop();
@@ -285,7 +285,7 @@
EXPECT_EQ(expectedTid, respTid);
}),
- exec::default_task_context<void>(exec::inline_scheduler{}));
+ exec::default_task_context<void>(stdexec::inline_scheduler{}));
pldm::Response mockResponse(sizeof(pldm_msg_hdr) + PLDM_GET_TID_RESP_BYTES,
0);