From 4e2943236d560a642b8c94858f60019b41e10b37 Mon Sep 17 00:00:00 2001 From: Matt Spinler Date: Thu, 2 Feb 2023 08:27:26 -0600 Subject: [PATCH] Check PowerSupply availability prop for State/Hlth This commit makes use of the Available property on the power supply D-Bus object when determining the power supply state and health in the PowerSupply response. The power supply monitor code from phosphor-power will set the property to false if it can determine that the power supply isn't able to provide power due to certain faults. If the PS isn't available, then the Health property will be set to Critical, and the State will be set to UnavailableOffline (assuming it shouldn't be Absent instead). This is necessary because on IBM systems the Functional property determines the fault LED state as well as the health value, and in certain cases the fault LED needs to stay off even though the PS health is not OK. A specific example of this is when the PS cord is unplugged: no fault LED is desired but it is desired for the Redfish output to show that there is an issue with the PS. If the Available property isn't present on D-Bus, it acts as if it had a value of true and behaves the same as it does today. Tested: Available = false: "Health": "Critical", "State": "UnavailableOffline" Available = true, Functional = false: "Health": "Critical", "State": "Enabled" PS missing: "Health": "Critical", "State": "Absent" Everything OK: "Health": "OK", "State": "Enabled" No Available property on D-Bus: "Health": "OK", "State": "Enabled" Change-Id: I1a3194bf3a6ca3936954b31439070dcc2f343411 Signed-off-by: Matt Spinler Signed-off-by: Myung Bae --- redfish-core/lib/power_supply.hpp | 45 ++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp index 2d3942b3a..208c7dfad 100644 --- a/redfish-core/lib/power_supply.hpp +++ b/redfish-core/lib/power_supply.hpp @@ -208,11 +208,12 @@ inline void getValidPowerSupplyPath( inline void getPowerSupplyState( const std::shared_ptr& asyncResp, - const std::string& service, const std::string& path) + const std::string& service, const std::string& path, bool available) { dbus::utility::getProperty( service, path, "xyz.openbmc_project.Inventory.Item", "Present", - [asyncResp](const boost::system::error_code& ec, const bool value) { + [asyncResp, + available](const boost::system::error_code& ec, const bool value) { if (ec) { if (ec.value() != EBADR) @@ -229,17 +230,23 @@ inline void getPowerSupplyState( asyncResp->res.jsonValue["Status"]["State"] = resource::State::Absent; } + else if (!available) + { + asyncResp->res.jsonValue["Status"]["State"] = + resource::State::UnavailableOffline; + } }); } inline void getPowerSupplyHealth( const std::shared_ptr& asyncResp, - const std::string& service, const std::string& path) + const std::string& service, const std::string& path, bool available) { dbus::utility::getProperty( service, path, "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional", - [asyncResp](const boost::system::error_code& ec, const bool value) { + [asyncResp, + available](const boost::system::error_code& ec, const bool value) { if (ec) { if (ec.value() != EBADR) @@ -251,7 +258,7 @@ inline void getPowerSupplyHealth( return; } - if (!value) + if (!value || !available) { asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::Critical; @@ -259,6 +266,31 @@ inline void getPowerSupplyHealth( }); } +inline void getPowerSupplyStateAndHealth( + const std::shared_ptr& asyncResp, + const std::string& service, const std::string& path) +{ + dbus::utility::getProperty( + service, path, "xyz.openbmc_project.State.Decorator.Availability", + "Available", + [asyncResp, service, + path](const boost::system::error_code& ec, const bool available) { + if (ec) + { + if (ec.value() != EBADR) + { + BMCWEB_LOG_ERROR("DBUS response error for Available {}", + ec.value()); + messages::internalError(asyncResp->res); + } + return; + } + + getPowerSupplyState(asyncResp, service, path, available); + getPowerSupplyHealth(asyncResp, service, path, available); + }); +} + inline void getPowerSupplyAsset( const std::shared_ptr& asyncResp, const std::string& service, const std::string& path) @@ -478,8 +510,7 @@ inline void doPowerSupplyGet( asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; - getPowerSupplyState(asyncResp, service, powerSupplyPath); - getPowerSupplyHealth(asyncResp, service, powerSupplyPath); + getPowerSupplyStateAndHealth(asyncResp, service, powerSupplyPath); getPowerSupplyAsset(asyncResp, service, powerSupplyPath); getPowerSupplyFirmwareVersion(asyncResp, service, powerSupplyPath); getPowerSupplyLocation(asyncResp, service, powerSupplyPath);