Skip to content

Commit

Permalink
Add multi-host support in systems.hpp
Browse files Browse the repository at this point in the history
This change introduces multi-host support to systems.hpp.
Previously no request handler in systems.hpp was capable of handling
the request for a multi-host system (this was indicated by the
BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM constant inside the
handler used to return a 404 resource not found). This change fixes all
occurances in systems.hpp and enables bmcweb to handle a request for
multi-host systems.

Testing: todo

Change-Id: I67c17c3dd7a354fa9a2ebbc56d4def7a7e788909
Signed-off-by: Oliver Brewka <[email protected]>
  • Loading branch information
Oliver Brewka committed Nov 30, 2024
1 parent 545871e commit cc26456
Show file tree
Hide file tree
Showing 3 changed files with 529 additions and 328 deletions.
90 changes: 90 additions & 0 deletions redfish-core/include/utils/systems_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "human_sort.hpp"
#include "str_utility.hpp"

#include <boost/url/format.hpp>

Expand Down Expand Up @@ -107,4 +108,93 @@ inline void getSystemCollectionMembers(
"/xyz/openbmc_project/inventory", 0, interfaces,
std::bind_front(handleSystemCollectionMembers, asyncResp));
}

inline void getManagedHostProperty(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName, const boost::system::error_code& ec,
const std::string& systemId, const std::string& serviceName,
std::function<void(const uint64_t computerSystemIndex)> callback)
{
// get HostIndex property associated with found system path
BMCWEB_LOG_DEBUG("in getManagedHostProperty..");
if (ec)
{
if (ec.value() == boost::system::errc::io_error)
{
BMCWEB_LOG_DEBUG("EIO - System not found");
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
systemName);
return;
}

BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
messages::internalError(asyncResp->res);
return;
}
if (systemId.empty() || serviceName.empty())
{
BMCWEB_LOG_WARNING("System not found");
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
systemName);
return;
}

sdbusplus::asio::getProperty<uint64_t>(
*crow::connections::systemBus, serviceName, systemId,
"xyz.openbmc_project.Inventory.Decorator.ManagedHost", "HostIndex",
[asyncResp, systemName, serviceName, callback = std::move(callback)](
const boost::system::error_code& ec2, const uint64_t hostIndex) {
if (ec2)
{
BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
systemName);
return;
}

callback(hostIndex);
});
}

inline void getComputerSystemIndex(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& systemName,
std::function<void(const uint64_t computerSystemIndex)>&& callback)
{
constexpr std::array<std::string_view, 1> interfaces{
"xyz.openbmc_project.Inventory.Decorator.ManagedHost"};
dbus::utility::getSubTree(
"/xyz/openbmc_project/inventory", 0, interfaces,
[asyncResp, systemName, callback = std::move(callback)](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
BMCWEB_LOG_DEBUG("in afterGetValidSystemPaths");
std::string systemId;
std::string serviceName;
if (ec)
{
getManagedHostProperty(asyncResp, systemName, ec, systemId,
serviceName, callback);
return;
}

for (const auto& [path, serviceMap] : subtree)
{
systemId = sdbusplus::message::object_path(path).filename();

if (systemId == systemName)
{
serviceName = serviceMap.begin()->first;
systemId = path;
break;
}
}
BMCWEB_LOG_DEBUG(
"found systemId: {}, serviceName: {} .. calling getManagedHostProperty",
systemId, serviceName);

getManagedHostProperty(asyncResp, systemName, ec, systemId,
serviceName, callback);
});
}
} // namespace redfish
31 changes: 21 additions & 10 deletions redfish-core/lib/redfish_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,27 @@ using UnitStruct =

template <typename CallbackFunc>
void getMainChassisId(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
CallbackFunc&& callback)
CallbackFunc&& callback, uint64_t computerSystemIndex = 0)
{
std::vector<std::string_view> interfaces;

if (computerSystemIndex == 0)
{
interfaces = {"xyz.openbmc_project.Inventory.Item.Board",
"xyz.openbmc_project.Inventory.Item.Chassis"};
}
else
{
interfaces = {"xyz.openbmc_project.Inventory.Item.Chassis"};
}

// Find managed chassis
constexpr std::array<std::string_view, 2> interfaces = {
"xyz.openbmc_project.Inventory.Item.Board",
"xyz.openbmc_project.Inventory.Item.Chassis"};
dbus::utility::getSubTree(
"/xyz/openbmc_project/inventory", 0, interfaces,
[callback = std::forward<CallbackFunc>(callback),
asyncResp](const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
[callback = std::forward<CallbackFunc>(callback), asyncResp,
computerSystemIndex](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
if (ec)
{
BMCWEB_LOG_ERROR("{}", ec);
Expand All @@ -82,15 +92,16 @@ void getMainChassisId(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
return;
}

std::size_t idPos = subtree[0].first.rfind('/');
std::size_t idx = static_cast<size_t>(computerSystemIndex);
std::size_t idPos = subtree[idx].first.rfind('/');
if (idPos == std::string::npos ||
(idPos + 1) >= subtree[0].first.size())
(idPos + 1) >= subtree[idx].first.size())
{
messages::internalError(asyncResp->res);
BMCWEB_LOG_DEBUG("Can't parse chassis ID!");
return;
}
std::string chassisId = subtree[0].first.substr(idPos + 1);
std::string chassisId = subtree[idx].first.substr(idPos + 1);
BMCWEB_LOG_DEBUG("chassisId = {}", chassisId);
callback(chassisId, asyncResp);
});
Expand Down
Loading

0 comments on commit cc26456

Please sign in to comment.