Skip to content

Commit aa450fc

Browse files
committed
Add multi-host support in systems.hpp
Add support for multi-host GET, POST and PATCH request handling under the /redfish/v1/Systems/{computerSystemId}/ redfish resource. The change implements the getComputerSystemIndex function which leverages the xyz.openbmc_project.ManagedHost interface to retrieve the index corresponding to the host the request was made for, when on a multi-host machine. On single-host the index always defaults to 0. It is not the perfect solution, but it is a starting point to introduce multi-host support to bmcweb, allowing for power control, via redfish and in general something we can build from. More efficient ways of doing things are already discussed, but will need more time to design properly. The implementation relies on the experimental-redfish-multi-computer-system meson flag to give bmcweb an indication, whether it is running on single- or multi-host and to drop unsupported redfish resources for the time being. All multi-host supported redfish URIs can be found in this listing: https://gerrit.openbmc.org/c/openbmc/bmcweb/+/76118 Tested: GET route has been tested with redfish service validator in qemu for the romulus and yosemite4 machine. Validator passed, no regression observed. POST route has been manually tested in web-ui on single-host hardware. All possible power controls worked as expected. For multi-host this was tested manually with curl in qemu. After requesting the expected changes have been observed on dbus. PATCH route has been requested via curl manually both on multi- and single-host for every property, that this patch implements. After each request the expected change has been observed on dbus. Change-Id: I67c17c3dd7a354fa9a2ebbc56d4def7a7e788909 Signed-off-by: Oliver Brewka <oliver.brewka@9elements.com>
1 parent 4a102cd commit aa450fc

File tree

3 files changed

+626
-327
lines changed

3 files changed

+626
-327
lines changed

redfish-core/include/utils/systems_utils.hpp

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "bmcweb_config.h"
44

55
#include "async_resp.hpp"
6+
#include "dbus_singleton.hpp"
67
#include "dbus_utility.hpp"
78
#include "error_messages.hpp"
89
#include "human_sort.hpp"
@@ -15,6 +16,7 @@
1516

1617
#include <algorithm>
1718
#include <array>
19+
#include <cstdint>
1820
#include <functional>
1921
#include <memory>
2022
#include <string>
@@ -115,4 +117,150 @@ inline void getSystemCollectionMembers(
115117
"/xyz/openbmc_project/inventory", 0, interfaces,
116118
std::bind_front(handleSystemCollectionMembers, asyncResp));
117119
}
120+
121+
inline void getManagedHostProperty(
122+
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
123+
const std::string& systemName, const std::string& systemPath,
124+
const std::string& serviceName,
125+
std::function<void(const uint64_t computerSystemIndex)> callback)
126+
{
127+
dbus::utility::getProperty<uint64_t>(
128+
*crow::connections::systemBus, serviceName, systemPath,
129+
"xyz.openbmc_project.Inventory.Decorator.ManagedHost", "HostIndex",
130+
[asyncResp, systemName, systemPath, serviceName,
131+
callback = std::move(callback)](const boost::system::error_code& ec,
132+
const uint64_t hostIndex) {
133+
if (ec)
134+
{
135+
BMCWEB_LOG_WARNING("DBUS response error {}", ec);
136+
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
137+
systemName);
138+
return;
139+
}
140+
BMCWEB_LOG_DEBUG("Got index {} for path {}", hostIndex, systemPath);
141+
callback(hostIndex);
142+
});
143+
}
144+
145+
inline void afterGetComputerSystemSubTree(
146+
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
147+
const std::string& systemName,
148+
std::function<void(const uint64_t computerSystemIndex)>& callback,
149+
const boost::system::error_code& ec,
150+
const dbus::utility::MapperGetSubTreeResponse& subtree)
151+
{
152+
sdbusplus::message::object_path systemPath;
153+
std::string serviceName;
154+
if (ec)
155+
{
156+
if (ec.value() == boost::system::errc::io_error)
157+
{
158+
BMCWEB_LOG_WARNING("EIO - System not found");
159+
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
160+
systemName);
161+
return;
162+
}
163+
164+
BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
165+
messages::internalError(asyncResp->res);
166+
return;
167+
}
168+
169+
const auto& found = std::ranges::find_if(
170+
subtree,
171+
[systemName](const std::pair<sdbusplus::message::object_path,
172+
dbus::utility::MapperServiceMap>& elem) {
173+
return elem.first.filename() == systemName;
174+
});
175+
176+
if (found == subtree.end())
177+
{
178+
BMCWEB_LOG_ERROR("Failed to match systemName: {}", systemName);
179+
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
180+
systemName);
181+
return;
182+
}
183+
184+
systemPath = found->first;
185+
serviceName = found->second.begin()->first;
186+
187+
getManagedHostProperty(asyncResp, systemName, systemPath, serviceName,
188+
std::move(callback));
189+
}
190+
191+
/**
192+
* @brief Retrieve the index associated with the requested system based on the
193+
* ManagedHost interface
194+
*
195+
* @param[i] asyncResp Async response object
196+
* @param[i] systemName The requested system
197+
* @param[i] callback Callback to call once the index has been found
198+
*
199+
* @return None
200+
*/
201+
inline void getComputerSystemIndex(
202+
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
203+
const std::string& systemName,
204+
std::function<void(const uint64_t computerSystemIndex)>&& callback)
205+
{
206+
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
207+
{
208+
constexpr std::array<std::string_view, 1> interfaces{
209+
"xyz.openbmc_project.Inventory.Decorator.ManagedHost"};
210+
dbus::utility::getSubTree(
211+
"/xyz/openbmc_project/inventory", 0, interfaces,
212+
std::bind_front(afterGetComputerSystemSubTree, asyncResp,
213+
systemName, std::move(callback)));
214+
}
215+
else
216+
{
217+
// on single-host, fallback to index 0
218+
BMCWEB_LOG_DEBUG(
219+
"Single-host detected, fallback to computerSystemIndex 0");
220+
callback(0);
221+
}
222+
}
223+
224+
inline sdbusplus::message::object_path getHostStateObjectPath(
225+
const uint64_t computerSystemIndex)
226+
{
227+
const sdbusplus::message::object_path hostStatePath(
228+
"/xyz/openbmc_project/state/host" +
229+
std::to_string(computerSystemIndex));
230+
231+
return hostStatePath;
232+
}
233+
234+
inline std::string getHostStateServiceName(const uint64_t computerSystemIndex)
235+
{
236+
std::string hostStateService = "xyz.openbmc_project.State.Host";
237+
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
238+
{
239+
hostStateService += std::to_string(computerSystemIndex);
240+
}
241+
242+
return hostStateService;
243+
}
244+
245+
inline sdbusplus::message::object_path getChassisStateObjectPath(
246+
const uint64_t computerSystemIndex)
247+
{
248+
const sdbusplus::message::object_path chassisStatePath(
249+
"/xyz/openbmc_project/state/chassis" +
250+
std::to_string(computerSystemIndex));
251+
252+
return chassisStatePath;
253+
}
254+
255+
inline std::string getChassisStateServiceName(
256+
const uint64_t computerSystemIndex)
257+
{
258+
std::string chassisStateService = "xyz.openbmc_project.State.Chassis";
259+
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
260+
{
261+
chassisStateService += std::to_string(computerSystemIndex);
262+
}
263+
264+
return chassisStateService;
265+
}
118266
} // namespace redfish

redfish-core/lib/processor.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,6 @@ inline void requestRoutesOperatingConfigCollection(App& app)
10861086
systemName);
10871087
return;
10881088
}
1089-
10901089
if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
10911090
{
10921091
messages::resourceNotFound(asyncResp->res, "ComputerSystem",
@@ -1254,7 +1253,6 @@ inline void requestRoutesProcessorCollection(App& app)
12541253
systemName);
12551254
return;
12561255
}
1257-
12581256
if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
12591257
{
12601258
messages::resourceNotFound(asyncResp->res, "ComputerSystem",

0 commit comments

Comments
 (0)