Skip to content
Open
13 changes: 13 additions & 0 deletions config/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,19 @@ else
work_dir = '/home/root'
endif

multi_comp = get_option('experimental-redfish-multi-computer-system')
if multi_comp.enabled()
if get_option('redfish-cpu-log').enabled()
error('redfish-cpu-log option not supported with experimental-redfish-multi-computer-system option')
endif
if get_option('redfish-dump-log').enabled()
error('redfish-dump-log option not supported with experimental-redfish-multi-computer-system option')
endif
if get_option('redfish-host-logger').enabled()
error('redfish-host-logger option not supported with experimental-redfish-multi-computer-system option')
endif
endif

configure_file(
input: 'bmcweb.service.in',
output: 'bmcweb.service',
Expand Down
2 changes: 2 additions & 0 deletions docs/Redfish.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ Fields common to all schemas
#### Sensor

- Implementation
- PeakReading
- PeakReadingTime
- Reading
- ReadingBasis
- ReadingRangeMax
Expand Down
1 change: 1 addition & 0 deletions include/dbus_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ using DbusVariantType = std::variant<
std::vector<uint16_t>,
sdbusplus::message::object_path,
std::tuple<uint64_t, std::vector<std::tuple<std::string, double, uint64_t>>>,
std::tuple<uint64_t, std::vector<std::tuple<std::string, std::string, double, uint64_t>>>,
std::vector<sdbusplus::message::object_path>,
std::vector<std::tuple<std::string, std::string>>,
std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
Expand Down
60 changes: 60 additions & 0 deletions redfish-core/include/utils/fan_utils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
#pragma once

#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "logging.hpp"

#include <asm-generic/errno.h>

#include <boost/system/error_code.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <array>
#include <functional>
#include <memory>
#include <string>
#include <string_view>

namespace redfish
{
constexpr std::array<std::string_view, 1> fanInterface = {
"xyz.openbmc_project.Inventory.Item.Fan"};

namespace fan_utils
{
inline void getFanPaths(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& validChassisPath,
const std::function<void(const dbus::utility::MapperGetSubTreePathsResponse&
fanPaths)>& callback)
{
sdbusplus::message::object_path endpointPath{validChassisPath};
endpointPath /= "cooled_by";

dbus::utility::getAssociatedSubTreePaths(
endpointPath,
sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
fanInterface,
[asyncResp, callback](
const boost::system::error_code& ec,
const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
if (ec)
{
if (ec.value() != EBADR)
{
BMCWEB_LOG_ERROR(
"DBUS response error for getAssociatedSubTreePaths {}",
ec.value());
messages::internalError(asyncResp->res);
}
return;
}
callback(subtreePaths);
});
}

} // namespace fan_utils
} // namespace redfish
10 changes: 9 additions & 1 deletion redfish-core/include/utils/redfish_aggregator_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ inline crow::Request createNewRequest(const crow::Request& localReq)
BMCWEB_LOG_ERROR("Failed to set body. Continuing");
}

for (const auto& field : req.fields())
// Preserve method and target (URI) from the original request
req.method(localReq.method());
if (!req.target(localReq.target()))
{
BMCWEB_LOG_ERROR("Failed to set target on aggregated request");
}

for (const auto& field : localReq.fields())
{
// Drop any incoming x-auth-token headers and keep Host and
// Content-Type. Set Accept.
Expand All @@ -34,6 +41,7 @@ inline crow::Request createNewRequest(const crow::Request& localReq)
req.addHeader(headerName, field.value());
}
}
// Set Accept header to application/json, application/octet-stream
req.addHeader(boost::beast::http::field::accept,
"application/json, application/octet-stream");
return req;
Expand Down
48 changes: 47 additions & 1 deletion redfish-core/include/utils/sensor_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,47 @@ inline sensor::ReadingType toReadingType(std::string_view sensorType)

} // namespace sensors

// represents metric Id, metadata, reading value and timestamp of single
// reading update in milliseconds
using Reading = std::tuple<std::string, std::string, double, uint64_t>;
// represents multiple independent readings
using Readings = std::vector<Reading>;
// represents a timestamp and multiple independent readings
using Statistics = std::tuple<uint64_t, Readings>;
// represents sensor's path, its metadata
using SensorPaths =
std::vector<std::tuple<sdbusplus::message::object_path, std::string>>;
// represents reading parameters for statistics readings
using ReadingParameters =
std::vector<std::tuple<SensorPaths, std::string, std::string, uint64_t>>;

inline void updateSensorStatistics(
nlohmann::json& sensorJson, const std::optional<Statistics>& statistics,
const std::optional<ReadingParameters>& readingParameters)
{
if (statistics.has_value() && readingParameters.has_value())
{
Readings metrics = std::get<1>(*statistics);
for (const auto& [sensorPaths, operationType, metricId, duration] :
*readingParameters)
{
if (operationType ==
"xyz.openbmc_project.Telemetry.Report.OperationType.Maximum")
{
if (metrics.size() == 1)
{
const auto& [id, metadata, value, timestamp] = metrics[0];
sensorJson["PeakReading"] = value;
if (timestamp != 0)
{
sensorJson["PeakReadingTime"] = timestamp;
}
}
}
}
}
}

/**
* @brief Returns the Redfish State value for the specified inventory item.
* @param inventoryItem D-Bus inventory item associated with a sensor.
Expand Down Expand Up @@ -519,11 +560,14 @@ inline void objectPropertiesToJson(
bool available = true;
std::optional<std::string> readingBasis;
std::optional<std::string> implementation;
std::optional<Statistics> statistics;
std::optional<ReadingParameters> readingParameters;

const bool success = sdbusplus::unpackPropertiesNoThrow(
dbus_utils::UnpackErrorPrinter(), propertiesDict, "Available",
checkAvailable, "ReadingBasis", readingBasis, "Implementation",
implementation);
implementation, "Readings", statistics, "ReadingParameters",
readingParameters);
if (!success)
{
messages::internalError();
Expand Down Expand Up @@ -583,6 +627,8 @@ inline void objectPropertiesToJson(
sensorJson["Implementation"] = implementationOpt;
}
}

updateSensorStatistics(sensorJson, statistics, readingParameters);
}
else if (sensorType == "temperature")
{
Expand Down
41 changes: 22 additions & 19 deletions redfish-core/include/utils/systems_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
namespace redfish
{

namespace systems_utils
{

inline void handleSystemCollectionMembers(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const boost::system::error_code& ec,
Expand Down Expand Up @@ -216,48 +219,49 @@ inline void getComputerSystemIndex(
inline sdbusplus::message::object_path getHostStateObjectPath(
const uint64_t computerSystemIndex)
{
const sdbusplus::message::object_path hostStatePath(
"/xyz/openbmc_project/state/host" +
std::to_string(computerSystemIndex));

return hostStatePath;
sdbusplus::message::object_path hostPath("/xyz/openbmc_project/state");
hostPath /= std::format("host{}", computerSystemIndex);
return hostPath;
}

inline std::string getHostStateServiceName(const uint64_t computerSystemIndex)
{
std::string hostStateService = "xyz.openbmc_project.State.Host";
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
hostStateService += std::to_string(computerSystemIndex);
return std::format("xyz.openbmc_project.State.Host{}",
computerSystemIndex);
}

return hostStateService;
return "xyz.openbmc_project.State.Host";
}

inline sdbusplus::message::object_path getChassisStateObjectPath(
const uint64_t computerSystemIndex)
{
const sdbusplus::message::object_path chassisStatePath(
"/xyz/openbmc_project/state/chassis" +
std::to_string(computerSystemIndex));

return chassisStatePath;
sdbusplus::message::object_path chassisPath("/xyz/openbmc_project/state");
chassisPath /= std::format("chassis{}", computerSystemIndex);
return chassisPath;
}

inline std::string getChassisStateServiceName(
const uint64_t computerSystemIndex)
{
std::string chassisStateService = "xyz.openbmc_project.State.Chassis";
if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
{
chassisStateService += std::to_string(computerSystemIndex);
return std::format("xyz.openbmc_project.State.Chassis{}",
computerSystemIndex);
}

return chassisStateService;
return "xyz.openbmc_project.State.Chassis";
}

namespace systems_utils
inline sdbusplus::message::object_path getControlObjectPath(
const uint64_t computerSystemIndex)
{
sdbusplus::message::object_path controlPath("/xyz/openbmc_project/control");
controlPath /= std::format("host{}", computerSystemIndex);
return controlPath;
}

inline void afterGetValidSystemsPath(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Expand Down Expand Up @@ -312,8 +316,6 @@ inline void getValidSystemsPath(
});
}

} // namespace systems_utils

/**
* @brief Match computerSystemIndex with index contained by an object path
* i.e 1 in /xyz/openbmc/project/control/host1/policy/TPMEnable
Expand Down Expand Up @@ -366,4 +368,5 @@ inline bool indexMatchingSubTreeMapObjectPath(

return false;
}
} // namespace systems_utils
} // namespace redfish
6 changes: 4 additions & 2 deletions redfish-core/lib/bios.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "utils/sw_utils.hpp"

#include <boost/beast/http/verb.hpp>
#include <boost/url/format.hpp>

#include <format>
#include <functional>
Expand Down Expand Up @@ -55,8 +56,9 @@ inline void handleBiosServiceGet(
asyncResp->res.jsonValue["Description"] = "BIOS Configuration Service";
asyncResp->res.jsonValue["Id"] = "BIOS";
asyncResp->res.jsonValue["Actions"]["#Bios.ResetBios"]["target"] =
std::format("/redfish/v1/Systems/{}/Bios/Actions/Bios.ResetBios",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
boost::urls::format(
"/redfish/v1/Systems/{}/Bios/Actions/Bios.ResetBios",
BMCWEB_REDFISH_SYSTEM_URI_NAME);

// Get the ActiveSoftwareImage and SoftwareImages
sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose, "",
Expand Down
4 changes: 2 additions & 2 deletions redfish-core/lib/chassis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,8 +457,8 @@ inline void handleDecoratorAssetProperties(

nlohmann::json::array_t computerSystems;
nlohmann::json::object_t system;
system["@odata.id"] =
std::format("/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
BMCWEB_REDFISH_SYSTEM_URI_NAME);
computerSystems.emplace_back(std::move(system));
asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
std::move(computerSystems);
Expand Down
Loading