diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces')
10 files changed, 1241 insertions, 144 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0006-Add-fix-for-broken-feature-Pending-Attributes.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0006-Add-fix-for-broken-feature-Pending-Attributes.patch new file mode 100644 index 000000000..0e4fc4903 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/biosconfig/0006-Add-fix-for-broken-feature-Pending-Attributes.patch @@ -0,0 +1,919 @@ +From 9814f83f36afafffa55bd19481654c064840e73d Mon Sep 17 00:00:00 2001 +From: Arun Lal K M <arun.lal@intel.com> +Date: Mon, 16 Aug 2021 17:49:11 +0000 +Subject: [PATCH] Add fix for broken feature 'Pending Attributes'. + +Fix is added for the following: +1) GET to 'redfish/v1/Systems/system/Bios'. +2) PATCH to 'redfish/v1/Systems/system/Bios/Settings'. +3) GET to 'redfish/v1/Systems/system/Bios/Settings'. +4) Fix for incremental duplicate values in BiosAttributeRegistry. + +Tested: +By giving PATCH to 'redfish/v1/Systems/system/Bios/Settings' +PATCH command raw data: +{ + "data":{ + "AmpPrefetchEnable": "0x1", + "Ce2LmLoggingEn": "0x1", + "DfxEadrDebugLogs": "0x2", + "PsfUrEnable": "0x1", + "ATS": "0x0" + } +} + +Response: +{ + "@Message.ExtendedInfo": [ + { + "@odata.type": "#Message.v1_1_1.Message", + "Message": "Successfully Completed Request", + "MessageArgs": [], + "MessageId": "Base.1.8.1.Success", + "MessageSeverity": "OK", + "Resolution": "None" + } + ] +} + +By giving GET to 'redfish/v1/Systems/system/Bios' +Response: +{ + "@Redfish.Settings": { + "@odata.type": "#Settings.v1_3_0.Settings", + "SettingsObject": { + "@odata.id": + "/redfish/v1/Systems/system/Bios/Settings" + } + }, + "@odata.id": "/redfish/v1/Systems/system/Bios", + "@odata.type": "#Bios.v1_1_0.Bios", + "Actions": { + "#Bios.ChangePassword": { + "target": + "/redfish/v1/Systems/system/Bios/Actions/Bios.ChangePassword" + }, + "#Bios.ResetBios": { + "target": + "/redfish/v1/Systems/system/Bios/Actions/Bios.ResetBios" + } + }, + "AttributeRegistry": "BiosAttributeRegistry", + "Attributes": { + "AEPErrorInjEn": "0x00", + "ARIEnable": "0x01", + "ARIForward": "0x00", + ... + ... + ... + "txEqCalibration": "0x01", + "volMemMode": "0x00", + "wrVrefCenter": "0x01" + }, + "Description": "BIOS Configuration Service", + "Id": "BIOS", + "Links": { + "ActiveSoftwareImage": { + "@odata.id": + "/redfish/v1/UpdateService/FirmwareInventory/bios_active" + }, + "SoftwareImages": [ + { + "@odata.id": + "/redfish/v1/UpdateService/FirmwareInventory/bios_active" + } + ], + "SoftwareImages@odata.count": 1 + }, + "Name": "BIOS Configuration" +} + +By giving GET to 'redfish/v1/Systems/system/Bios/Settings' +Response: +{ + "@odata.id": "/redfish/v1/Systems/system/Bios/Settings", + "@odata.type": "#Bios.v1_1_0.Bios", + "AttributeRegistry": "BiosAttributeRegistry", + "Attributes": { + "ATS": "0x0", + "AmpPrefetchEnable": "0x1", + "Ce2LmLoggingEn": "0x1", + "DfxEadrDebugLogs": "0x2", + "PsfUrEnable": "0x1" + }, + "Id": "BiosSettingsV1", + "Name": "Bios Settings Version 1" +} + +By running Redfish-Service-Validator +Result: +Elapsed time: 0:09:36 +invalidPropertyValue: 108 +metadataNamespaces: 2185 +missingNamespaces: 1 +optionalAction: 9 +pass: 13772 +passAction: 22 +passGet: 541 +reflink: 1 +repeat: 47 +serviceNamespaces: 75 +skipOptional: 9276 +unverifiedComplexAdditional: 1 +warnDeprecated: 230 +warningPresent: 54 +Validation has succeeded. + +Change-Id: Ib92eb7a1b81bef5adaf432b9225a183d7a78ebef +Signed-off-by: Arun Lal K M <arun.lal@intel.com> +--- + redfish-core/lib/bios.hpp | 583 ++++++++++++++++++++++++-------------- + 1 file changed, 374 insertions(+), 209 deletions(-) + +diff --git a/redfish-core/lib/bios.hpp b/redfish-core/lib/bios.hpp +index 360a749..a927772 100644 +--- a/redfish-core/lib/bios.hpp ++++ b/redfish-core/lib/bios.hpp +@@ -12,13 +12,15 @@ map{attributeName,struct{attributeType,readonlyStatus,displayname, + description,menuPath,current,default, + array{struct{optionstring,optionvalue}}}} + */ +-using BiosBaseTableType = std::vector<std::pair< ++ ++using BiosBaseTableType = boost::container::flat_map< + std::string, + std::tuple< + std::string, bool, std::string, std::string, std::string, + std::variant<int64_t, std::string>, std::variant<int64_t, std::string>, + std::vector< +- std::tuple<std::string, std::variant<int64_t, std::string>>>>>>; ++ std::tuple<std::string, std::variant<int64_t, std::string>>>>>; ++ + using BiosBaseTableItemType = std::pair< + std::string, + std::tuple< +@@ -29,6 +31,13 @@ using BiosBaseTableItemType = std::pair< + using OptionsItemType = + std::tuple<std::string, std::variant<int64_t, std::string>>; + ++using PendingAttributesType = boost::container::flat_map< ++ std::string, std::tuple<std::string, std::variant<int64_t, std::string>>>; ++ ++using PendingAttributesItemType = ++ std::pair<std::string, ++ std::tuple<std::string, std::variant<int64_t, std::string>>>; ++ + enum BiosBaseTableIndex + { + biosBaseAttrType = 0, +@@ -45,17 +54,7 @@ enum OptionsItemIndex + optItemType = 0, + optItemValue + }; +-/* +- The Pending attribute name and new value. +- ex- { {"QuietBoot",Type.Integer, 0x1}, +- { "DdrFreqLimit",Type.String,"2933"} +- } +-*/ +-using PendingAttributesType = std::vector<std::pair< +- std::string, std::tuple<std::string, std::variant<int64_t, std::string>>>>; +-using PendingAttributesItemType = +- std::pair<std::string, +- std::tuple<std::string, std::variant<int64_t, std::string>>>; ++ + enum PendingAttributesIndex + { + pendingAttrType = 0, +@@ -64,31 +63,16 @@ enum PendingAttributesIndex + static std::string mapAttrTypeToRedfish(const std::string_view typeDbus) + { + std::string ret; +- if (typeDbus == "xyz.openbmc_project.BIOSConfig.Manager." +- "AttributeType.Enumeration") +- { +- ret = "Enumeration"; +- } +- else if (typeDbus == "xyz.openbmc_project.BIOSConfig." +- "Manager.AttributeType.String") ++ if (typeDbus == "xyz.openbmc_project.BIOSConfig." ++ "Manager.AttributeType.String") + { + ret = "String"; + } +- else if (typeDbus == "xyz.openbmc_project.BIOSConfig." +- "Manager.AttributeType.Password") +- { +- ret = "Password"; +- } + else if (typeDbus == "xyz.openbmc_project.BIOSConfig." + "Manager.AttributeType.Integer") + { + ret = "Integer"; + } +- else if (typeDbus == "xyz.openbmc_project.BIOSConfig." +- "Manager.AttributeType.Boolean") +- { +- ret = "Boolean"; +- } + else + { + ret = "UNKNOWN"; +@@ -96,29 +80,7 @@ static std::string mapAttrTypeToRedfish(const std::string_view typeDbus) + + return ret; + } +-static std::string mapRedfishToAttrType(const std::string_view type) +-{ +- std::string ret; +- if (type == "string") +- { +- ret = "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.String"; +- } +- else if (type == "int") +- { +- ret = "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer"; +- } +- else if (type == "enum") +- { +- ret = "xyz.openbmc_project.BIOSConfig.Manager.AttributeType." +- "Enumeration"; +- } +- else +- { +- ret = "UNKNOWN"; +- } + +- return ret; +-} + static std::string mapBoundTypeToRedfish(const std::string_view typeDbus) + { + std::string ret; +@@ -208,6 +170,15 @@ inline void requestRoutesBiosService(App& app) + + return; + } ++ ++ if (getObjectType.empty()) ++ { ++ BMCWEB_LOG_ERROR << "getObjectType is empty."; ++ messages::internalError(asyncResp->res); ++ ++ return; ++ } ++ + const std::string& service = + getObjectType.begin()->first; + +@@ -231,7 +202,7 @@ inline void requestRoutesBiosService(App& app) + if (baseBiosTable == nullptr) + { + BMCWEB_LOG_ERROR +- << "baseBiosTable == nullptr "; ++ << "baseBiosTable is empty"; + messages::internalError(asyncResp->res); + return; + } +@@ -269,7 +240,6 @@ inline void requestRoutesBiosService(App& app) + { + BMCWEB_LOG_ERROR + << "Unsupported attribute type."; +- messages::internalError(asyncResp->res); + } + } + }, +@@ -293,7 +263,7 @@ inline void requestRoutesBiosService(App& app) + inline void requestRoutesBiosChangePassword(App& app) + { + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/") +- .privileges({{"ConfigureComponents"}}) ++ .privileges(redfish::privileges::postBios) + .methods(boost::beast::http::verb::post)( + [](const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { +@@ -359,180 +329,298 @@ inline void requestRoutesBiosSettings(App& app) + { + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/Settings") + .privileges(redfish::privileges::getBios) +- .methods(boost::beast::http::verb::get)( +- [](const crow::Request&, +- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { +- asyncResp->res.jsonValue["@odata.id"] = +- asyncResp->res.jsonValue["@odata.id"] = +- "/redfish/v1/Systems/system/Bios/Settings"; +- asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios"; +- asyncResp->res.jsonValue["Name"] = "Bios Settings Version 1"; +- asyncResp->res.jsonValue["Id"] = "BiosSettingsV1"; +- asyncResp->res.jsonValue["AttributeRegistry"] = +- "BiosAttributeRegistry"; +- asyncResp->res.jsonValue["Attributes"] = {}; ++ .methods( ++ boost::beast::http::verb:: ++ get)([](const crow::Request&, ++ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { ++ asyncResp->res.jsonValue["@odata.id"] = ++ "/redfish/v1/Systems/system/Bios/Settings"; ++ asyncResp->res.jsonValue["@odata.type"] = "#Bios.v1_1_0.Bios"; ++ asyncResp->res.jsonValue["Name"] = "Bios Settings Version 1"; ++ asyncResp->res.jsonValue["Id"] = "BiosSettingsV1"; ++ asyncResp->res.jsonValue["AttributeRegistry"] = ++ "BiosAttributeRegistry"; ++ asyncResp->res.jsonValue["Attributes"] = {}; + +- crow::connections::systemBus->async_method_call( +- [asyncResp](const boost::system::error_code ec, +- const GetObjectType& getObjectType) { +- if (ec) +- { +- BMCWEB_LOG_ERROR +- << "ObjectMapper::GetObject call failed: " +- << ec; +- messages::internalError(asyncResp->res); ++ crow::connections::systemBus->async_method_call( ++ [asyncResp](const boost::system::error_code ec, ++ const GetObjectType& getObjectType) { ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR ++ << "ObjectMapper::GetObject call failed: " << ec; ++ messages::internalError(asyncResp->res); + +- return; +- } +- std::string service = getObjectType.begin()->first; ++ return; ++ } + +- crow::connections::systemBus->async_method_call( +- [asyncResp]( +- const boost::system::error_code ec, +- const std::variant<PendingAttributesType>& +- retPendingAttributes) { +- if (ec) +- { +- BMCWEB_LOG_ERROR +- << "getBiosSettings DBUS error: " << ec; +- messages::resourceNotFound( +- asyncResp->res, "Systems/system/Bios", +- "Settings"); +- return; +- } +- const PendingAttributesType* pendingAttributes = +- std::get_if<PendingAttributesType>( +- &retPendingAttributes); +- nlohmann::json& attributesJson = +- asyncResp->res.jsonValue["Attributes"]; +- if (pendingAttributes == nullptr) +- { +- BMCWEB_LOG_ERROR +- << "pendingAttributes == nullptr "; +- messages::internalError(asyncResp->res); +- return; +- } +- for (const PendingAttributesItemType& item : +- *pendingAttributes) ++ if (getObjectType.empty()) ++ { ++ BMCWEB_LOG_ERROR << "getObjectType is empty."; ++ messages::internalError(asyncResp->res); ++ ++ return; ++ } ++ ++ std::string service = getObjectType.begin()->first; ++ ++ crow::connections::systemBus->async_method_call( ++ [asyncResp](const boost::system::error_code ec, ++ const std::variant<PendingAttributesType>& ++ retPendingAttributes) { ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR ++ << "getBiosSettings DBUS error: " << ec; ++ messages::resourceNotFound( ++ asyncResp->res, "Systems/system/Bios", ++ "Settings"); ++ return; ++ } ++ ++ const PendingAttributesType* pendingAttributes = ++ std::get_if<PendingAttributesType>( ++ &retPendingAttributes); ++ nlohmann::json& attributesJson = ++ asyncResp->res.jsonValue["Attributes"]; ++ if (pendingAttributes == nullptr) ++ { ++ BMCWEB_LOG_ERROR ++ << "pendingAttributes is empty"; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ for (const PendingAttributesItemType& ++ pendingAttributesItem : *pendingAttributes) ++ { ++ const std::string& biosAttrType = ++ std::get<pendingAttrType>( ++ pendingAttributesItem.second); ++ ++ std::string itemType = ++ mapAttrTypeToRedfish(biosAttrType); ++ ++ if (itemType == "String") + { +- const std::string& key = item.first; +- const std::string& itemType = +- std::get<pendingAttrType>(item.second); +- std::string attrType = +- mapAttrTypeToRedfish(itemType); +- if (attrType == "String") +- { +- const std::string* currValue = +- std::get_if<std::string>( +- &std::get<pendingAttrValue>( +- item.second)); +- attributesJson.emplace( +- key, currValue != nullptr +- ? *currValue +- : ""); +- } +- else if (attrType == "Integer") ++ const std::string* currValue = ++ std::get_if<std::string>( ++ &std::get<pendingAttrValue>( ++ pendingAttributesItem.second)); ++ ++ if (!currValue) + { +- const int64_t* currValue = +- std::get_if<int64_t>( +- &std::get<pendingAttrValue>( +- item.second)); +- attributesJson.emplace( +- key, currValue != nullptr +- ? *currValue +- : 0); ++ BMCWEB_LOG_ERROR ++ << "No string data in pending " ++ "attributes item data"; ++ messages::internalError(asyncResp->res); ++ return; + } +- else ++ ++ attributesJson.emplace( ++ pendingAttributesItem.first, ++ *currValue); ++ } ++ else if (itemType == "Integer") ++ { ++ const int64_t* currValue = ++ std::get_if<int64_t>( ++ &std::get<pendingAttrValue>( ++ pendingAttributesItem.second)); ++ ++ if (!currValue) + { + BMCWEB_LOG_ERROR +- << "Unsupported attribute type."; ++ << "No int64_t data in pending " ++ "attributes item data"; + messages::internalError(asyncResp->res); ++ return; + } ++ ++ attributesJson.emplace( ++ pendingAttributesItem.first, ++ *currValue); + } +- }, +- service, "/xyz/openbmc_project/bios_config/manager", +- "org.freedesktop.DBus.Properties", "Get", +- "xyz.openbmc_project.BIOSConfig.Manager", +- "PendingAttributes"); +- }, +- "xyz.openbmc_project.ObjectMapper", +- "/xyz/openbmc_project/object_mapper", +- "xyz.openbmc_project.ObjectMapper", "GetObject", +- "/xyz/openbmc_project/bios_config/manager", +- std::array<const char*, 0>()); +- }); ++ else ++ { ++ BMCWEB_LOG_ERROR ++ << "Unsupported attribute type."; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ } ++ }, ++ service, "/xyz/openbmc_project/bios_config/manager", ++ "org.freedesktop.DBus.Properties", "Get", ++ "xyz.openbmc_project.BIOSConfig.Manager", ++ "PendingAttributes"); ++ }, ++ "xyz.openbmc_project.ObjectMapper", ++ "/xyz/openbmc_project/object_mapper", ++ "xyz.openbmc_project.ObjectMapper", "GetObject", ++ "/xyz/openbmc_project/bios_config/manager", ++ std::array<const char*, 0>()); ++ }); + + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Bios/Settings") +- .privileges({{"ConfigureComponents"}}) +- .methods(boost::beast::http::verb::patch)( +- [](const crow::Request& req, +- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { +- nlohmann::json inpJson; +- +- if (!redfish::json_util::readJson(req, asyncResp->res, "data", +- inpJson)) +- { +- return; +- } ++ .privileges(redfish::privileges::patchBios) ++ .methods( ++ boost::beast::http::verb:: ++ patch)([](const crow::Request& req, ++ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { ++ nlohmann::json inpJson; ++ ++ if (!redfish::json_util::readJson(req, asyncResp->res, "data", ++ inpJson)) ++ { ++ BMCWEB_LOG_ERROR << "No 'data' in req!"; ++ return; ++ } ++ ++ if (inpJson.empty()) ++ { ++ messages::invalidObject(asyncResp->res, "data"); ++ BMCWEB_LOG_ERROR << "No input in req!"; ++ return; ++ } + +- for (auto& attrInfo : inpJson) +- { +- std::optional<std::string> attrName; +- std::optional<std::string> attrType; +- std::optional<std::string> attrValue; +- if (!json_util::getValueFromJsonObject( +- attrInfo, "AttributeName", attrName)) +- { +- messages::propertyMissing(asyncResp->res, +- "AttributeName"); +- return; +- } +- if (!json_util::getValueFromJsonObject( +- attrInfo, "AttributeType", attrType)) +- { +- messages::propertyMissing(asyncResp->res, +- "AttributeType"); +- return; +- } +- if (!json_util::getValueFromJsonObject( +- attrInfo, "AttributeValue", attrValue)) ++ crow::connections::systemBus->async_method_call( ++ [asyncResp, inpJson](const boost::system::error_code ec, ++ const GetObjectType& getObjectType) { ++ if (ec) + { +- messages::propertyMissing(asyncResp->res, +- "AttributeValue"); ++ BMCWEB_LOG_ERROR ++ << "ObjectMapper::GetObject call failed: " << ec; ++ messages::internalError(asyncResp->res); ++ + return; + } +- std::string biosAttrType = mapRedfishToAttrType(*attrType); + +- if (biosAttrType == "UNKNOWN") ++ if (getObjectType.empty()) + { +- BMCWEB_LOG_ERROR << "Invalid attribute type"; +- messages::propertyValueNotInList( +- asyncResp->res, "AttributeType", *attrType); ++ BMCWEB_LOG_ERROR << "getObjectType is empty."; ++ messages::internalError(asyncResp->res); ++ + return; + } + +- PendingAttributesType pendingAttributes; +- pendingAttributes.emplace_back(std::make_pair( +- *attrName, std::make_tuple(biosAttrType, *attrValue))); ++ std::string service = getObjectType.begin()->first; + + crow::connections::systemBus->async_method_call( +- [asyncResp](const boost::system::error_code ec) { ++ [asyncResp, ++ inpJson](const boost::system::error_code ec, ++ const std::variant<BiosBaseTableType>& ++ retBiosTable) { + if (ec) + { + BMCWEB_LOG_ERROR +- << "doPatch resp_handler got error " << ec; ++ << "getBiosAttributes DBUS error: " << ec; + messages::internalError(asyncResp->res); + return; + } ++ ++ const BiosBaseTableType* baseBiosTable = ++ std::get_if<BiosBaseTableType>(&retBiosTable); ++ ++ if (baseBiosTable == nullptr) ++ { ++ BMCWEB_LOG_ERROR << "baseBiosTable is empty."; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ PendingAttributesType pendingAttributes{}; ++ ++ for (nlohmann::detail::iteration_proxy_value< ++ nlohmann::detail::iter_impl< ++ const nlohmann::basic_json<>>>& ++ attributes : inpJson.items()) ++ { ++ BiosBaseTableType::const_iterator knobIter = ++ baseBiosTable->find(attributes.key()); ++ if (knobIter == baseBiosTable->end()) ++ { ++ BMCWEB_LOG_ERROR << "Cannot find " ++ << attributes.key() ++ << " in baseBiosTable"; ++ messages::propertyValueNotInList( ++ asyncResp->res, attributes.key(), ++ "data"); ++ return; ++ } ++ ++ const std::string& itemType = ++ std::get<biosBaseAttrType>( ++ knobIter->second); ++ std::string attrType = ++ mapAttrTypeToRedfish(itemType); ++ ++ if (attrType == "String") ++ { ++ std::string val = attributes.value(); ++ ++ pendingAttributes.emplace( ++ attributes.key(), ++ std::make_tuple(itemType, val)); ++ } ++ else if (attrType == "Integer") ++ { ++ pendingAttributes.emplace( ++ attributes.key(), ++ std::make_tuple( ++ itemType, static_cast<int64_t>( ++ attributes.value()))); ++ } ++ else ++ { ++ BMCWEB_LOG_ERROR << "UNKNOWN attrType == " ++ << itemType; ++ messages::internalError(asyncResp->res); ++ ++ return; ++ } ++ } ++ ++ if (pendingAttributes.empty()) ++ { ++ BMCWEB_LOG_ERROR ++ << "pendingAttributes is empty."; ++ messages::invalidObject(asyncResp->res, "data"); ++ } ++ ++ crow::connections::systemBus->async_method_call( ++ [asyncResp]( ++ const boost::system::error_code ec) { ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR ++ << "doPatch resp_handler got error " ++ << ec << "\n"; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ messages::success(asyncResp->res); ++ }, ++ "xyz.openbmc_project.BIOSConfigManager", ++ "/xyz/openbmc_project/bios_config/manager", ++ "org.freedesktop.DBus.Properties", "Set", ++ "xyz.openbmc_project.BIOSConfig.Manager", ++ "PendingAttributes", ++ std::variant<PendingAttributesType>( ++ pendingAttributes)); + }, +- "xyz.openbmc_project.BIOSConfigManager", +- "/xyz/openbmc_project/bios_config/manager", +- "org.freedesktop.DBus.Properties", "Set", ++ service, "/xyz/openbmc_project/bios_config/manager", ++ "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.BIOSConfig.Manager", +- "PendingAttributes", +- std::variant<PendingAttributesType>(pendingAttributes)); +- } +- }); ++ "BaseBIOSTable"); ++ }, ++ "xyz.openbmc_project.ObjectMapper", ++ "/xyz/openbmc_project/object_mapper", ++ "xyz.openbmc_project.ObjectMapper", "GetObject", ++ "/xyz/openbmc_project/bios_config/manager", ++ std::array<const char*, 0>()); ++ }); + } + /** + * BiosAttributeRegistry class supports handle get method for BIOS attribute +@@ -572,6 +660,15 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + + return; + } ++ ++ if (getObjectType.empty()) ++ { ++ BMCWEB_LOG_ERROR << "getObjectType is empty."; ++ messages::internalError(asyncResp->res); ++ ++ return; ++ } ++ + std::string service = getObjectType.begin()->first; + + crow::connections::systemBus->async_method_call( +@@ -592,8 +689,6 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + nlohmann::json& attributeArray = + asyncResp->res + .jsonValue["RegistryEntries"]["Attributes"]; +- nlohmann::json optionsArray = +- nlohmann::json::array(); + if (baseBiosTable == nullptr) + { + BMCWEB_LOG_ERROR << "baseBiosTable == nullptr "; +@@ -609,10 +704,11 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + mapAttrTypeToRedfish(itemType); + if (attrType == "UNKNOWN") + { +- BMCWEB_LOG_ERROR << "attrType == UNKNOWN"; +- messages::internalError(asyncResp->res); +- return; ++ BMCWEB_LOG_ERROR << "UNKNOWN attrType == " ++ << itemType; ++ continue; + } ++ + nlohmann::json attributeItem; + attributeItem["AttributeName"] = item.first; + attributeItem["Type"] = attrType; +@@ -632,10 +728,30 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + std::get_if<std::string>( + &std::get<biosBaseCurrValue>( + item.second)); ++ ++ if (!currValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get currValue, no " ++ "std::string data in BIOS " ++ "attributes item data"; ++ continue; ++ } ++ + const std::string* defValue = + std::get_if<std::string>( + &std::get<biosBaseDefaultValue>( + item.second)); ++ ++ if (!defValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get defValue, no " ++ "std::string data in BIOS " ++ "attributes item data"; ++ continue; ++ } ++ + attributeItem["CurrentValue"] = + currValue != nullptr ? *currValue : ""; + attributeItem["DefaultValue"] = +@@ -647,10 +763,30 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + std::get_if<int64_t>( + &std::get<biosBaseCurrValue>( + item.second)); ++ ++ if (!currValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get currValue, no " ++ "int64_t data in BIOS " ++ "attributes item data"; ++ continue; ++ } ++ + const int64_t* defValue = + std::get_if<int64_t>( + &std::get<biosBaseDefaultValue>( + item.second)); ++ ++ if (!defValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get defValue, no " ++ "int64_t data in BIOS " ++ "attributes item data"; ++ continue; ++ } ++ + attributeItem["CurrentValue"] = + currValue != nullptr ? *currValue : 0; + attributeItem["DefaultValue"] = +@@ -658,12 +794,13 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + } + else + { +- BMCWEB_LOG_ERROR +- << "Unsupported attribute type."; +- messages::internalError(asyncResp->res); +- return; ++ BMCWEB_LOG_ERROR << "UNKNOWN attrType == " ++ << itemType; ++ continue; + } + ++ nlohmann::json optionsArray = ++ nlohmann::json::array(); + const std::vector<OptionsItemType>& + optionsVector = + std::get<biosBaseOptions>(item.second); +@@ -678,9 +815,9 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + if (optItemTypeRedfish == "UNKNOWN") + { + BMCWEB_LOG_ERROR +- << "optItemTypeRedfish == UNKNOWN"; +- messages::internalError(asyncResp->res); +- return; ++ << "UNKNOWN optItemTypeRedfish == " ++ << strOptItemType; ++ continue; + } + if (optItemTypeRedfish == "OneOf") + { +@@ -688,6 +825,17 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + std::get_if<std::string>( + &std::get<optItemValue>( + optItem)); ++ ++ if (!currValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get currValue, " ++ "no " ++ "std::string data in option " ++ "item value"; ++ continue; ++ } ++ + optItemJson[optItemTypeRedfish] = + currValue != nullptr ? *currValue + : ""; +@@ -698,6 +846,17 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + std::get_if<int64_t>( + &std::get<optItemValue>( + optItem)); ++ ++ if (!currValue) ++ { ++ BMCWEB_LOG_ERROR ++ << "Unable to get currValue, " ++ "no " ++ "int64_t data in option " ++ "item value"; ++ continue; ++ } ++ + optItemJson[optItemTypeRedfish] = + currValue != nullptr ? *currValue + : 0; +@@ -706,6 +865,12 @@ inline void requestRoutesBiosAttributeRegistry(App& app) + optionsArray.push_back(optItemJson); + } + ++ if (optionsArray.empty()) ++ { ++ BMCWEB_LOG_ERROR << "optionsArray is empty"; ++ continue; ++ } ++ + attributeItem["Value"] = optionsArray; + attributeArray.push_back(attributeItem); + } +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0010-Remove-Terminated-Event-Subscriptions.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0010-Remove-Terminated-Event-Subscriptions.patch new file mode 100644 index 000000000..7fcc235d2 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0010-Remove-Terminated-Event-Subscriptions.patch @@ -0,0 +1,258 @@ +From adaa5cb4c494148430b90edb248260eb2e66bca7 Mon Sep 17 00:00:00 2001 +From: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com> +Date: Wed, 8 Sep 2021 15:42:52 +0530 +Subject: [PATCH] Delete/Remove Terminated Event Subscription(s) + +Added functionality to delete/remove event subscription(s) which are +configured to Terminate after retries. + +Currently, when an Event is subscribed with Retry Policy as +"TerminateAfterRetries", the state of the connection is set to +"Terminated" after retrying, but the Subscription is not removed. +This commit adds the functionality to detect terminated connection and +remove the respective subscription. + +Tested: + - Created a Subscription with + DeliveryRetryPolicy: "TerminateAfterRetries" + - Received Events successfully on Event listener + - Once the Event listener was stopped, the Subscription was + removed/deleted after retries. + +Change-Id: If447acb2db74fb29a5d1cfe6194b77cda82bc8a1 +Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com> +--- + http/http_client.hpp | 43 +++++++++++++++---- + .../include/event_service_manager.hpp | 37 ++++++++++++++++ + 2 files changed, 71 insertions(+), 9 deletions(-) + +diff --git a/http/http_client.hpp b/http/http_client.hpp +index aaf1b2d..4f62c40 100644 +--- a/http/http_client.hpp ++++ b/http/http_client.hpp +@@ -56,6 +56,8 @@ enum class ConnState + closeInProgress, + closed, + suspended, ++ terminate, ++ terminateInProgress, + terminated, + abortConnection, + retry +@@ -263,7 +265,14 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + } + void doClose() + { +- state = ConnState::closeInProgress; ++ if (state == ConnState::terminate) ++ { ++ state = ConnState::terminateInProgress; ++ } ++ else if (state != ConnState::suspended) ++ { ++ state = ConnState::closeInProgress; ++ } + + // Set the timeout on the tcp stream socket for the async operation + conn.expires_after(std::chrono::seconds(30)); +@@ -293,8 +302,11 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + } + self->conn.close(); + +- if ((self->state != ConnState::suspended) && +- (self->state != ConnState::terminated)) ++ if (self->state == ConnState::terminateInProgress) ++ { ++ self->state = ConnState::terminated; ++ } ++ else if (self->state == ConnState::closeInProgress) + { + self->state = ConnState::closed; + self->handleConnState(); +@@ -316,8 +328,11 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + } + conn.close(); + +- if ((state != ConnState::suspended) && +- (state != ConnState::terminated)) ++ if (state == ConnState::terminateInProgress) ++ { ++ state = ConnState::terminated; ++ } ++ else if (state == ConnState::closeInProgress) + { + state = ConnState::closed; + handleConnState(); +@@ -340,8 +355,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + BMCWEB_LOG_DEBUG << "Retry policy: " << retryPolicyAction; + if (retryPolicyAction == "TerminateAfterRetries") + { +- // TODO: delete subscription +- state = ConnState::terminated; ++ state = ConnState::terminate; + } + if (retryPolicyAction == "SuspendRetries") + { +@@ -392,6 +406,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + case ConnState::sendInProgress: + case ConnState::recvInProgress: + case ConnState::closeInProgress: ++ case ConnState::terminateInProgress: + { + BMCWEB_LOG_DEBUG << "Async operation is already in progress"; + break; +@@ -413,7 +428,7 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + break; + } + case ConnState::suspended: +- case ConnState::terminated: ++ case ConnState::terminate: + { + doClose(); + break; +@@ -480,7 +495,8 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + } + void sendData(const std::string& data) + { +- if ((state == ConnState::suspended) || (state == ConnState::terminated)) ++ if ((state == ConnState::terminate) || ++ (state == ConnState::terminated) || (state == ConnState::suspended)) + { + return; + } +@@ -489,6 +505,15 @@ class HttpClient : public std::enable_shared_from_this<HttpClient> + return; + } + ++ bool isTerminated() ++ { ++ if (state == ConnState::terminated) ++ { ++ return true; ++ } ++ return false; ++ } ++ + void addHeaders( + const std::vector<std::pair<std::string, std::string>>& httpHeaders) + { +diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp +index 8d7067b..79618f6 100644 +--- a/redfish-core/include/event_service_manager.hpp ++++ b/redfish-core/include/event_service_manager.hpp +@@ -591,6 +591,14 @@ class Subscription : public persistent_data::UserSubscription + return std::nullopt; + } + ++ bool isTerminated() ++ { ++ if (conn != nullptr) ++ return conn->isTerminated(); ++ ++ return false; ++ } ++ + private: + std::shared_ptr<crow::SseConnection> sseConn = nullptr; + uint64_t eventSeqNum; +@@ -847,6 +855,22 @@ class EventServiceManager + } + } + ++ void deleteTerminatedSubcriptions() ++ { ++ boost::container::flat_map<std::string, ++ std::shared_ptr<Subscription>>::iterator it = ++ subscriptionsMap.begin(); ++ while (it != subscriptionsMap.end()) ++ { ++ std::shared_ptr<Subscription> entry = it->second; ++ if (entry->isTerminated()) ++ { ++ subscriptionsMap.erase(it); ++ } ++ it++; ++ } ++ } ++ + void updateNoOfSubscribersCount() + { + size_t eventLogSubCount = 0; +@@ -881,6 +905,7 @@ class EventServiceManager + + std::shared_ptr<Subscription> getSubscription(const std::string& id) + { ++ deleteTerminatedSubcriptions(); + auto obj = subscriptionsMap.find(id); + if (obj == subscriptionsMap.end()) + { +@@ -971,6 +996,7 @@ class EventServiceManager + + bool isSubscriptionExist(const std::string& id) + { ++ deleteTerminatedSubcriptions(); + auto obj = subscriptionsMap.find(id); + if (obj == subscriptionsMap.end()) + { +@@ -1033,6 +1059,7 @@ class EventServiceManager + + size_t getNumberOfSubscriptions() + { ++ deleteTerminatedSubcriptions(); + return subscriptionsMap.size(); + } + +@@ -1049,6 +1076,7 @@ class EventServiceManager + + std::vector<std::string> getAllIDs() + { ++ deleteTerminatedSubcriptions(); + std::vector<std::string> idList; + for (const auto& it : subscriptionsMap) + { +@@ -1059,6 +1087,7 @@ class EventServiceManager + + bool isDestinationExist(const std::string& destUrl) + { ++ deleteTerminatedSubcriptions(); + for (const auto& it : subscriptionsMap) + { + std::shared_ptr<Subscription> entry = it.second; +@@ -1073,6 +1102,7 @@ class EventServiceManager + + void sendTestEventLog() + { ++ deleteTerminatedSubcriptions(); + for (const auto& it : this->subscriptionsMap) + { + std::shared_ptr<Subscription> entry = it.second; +@@ -1100,6 +1130,8 @@ class EventServiceManager + } + eventRecord.push_back(eventMessage); + ++ deleteTerminatedSubcriptions(); ++ + for (const auto& it : this->subscriptionsMap) + { + std::shared_ptr<Subscription> entry = it.second; +@@ -1143,6 +1175,8 @@ class EventServiceManager + } + void sendBroadcastMsg(const std::string& broadcastMsg) + { ++ deleteTerminatedSubcriptions(); ++ + for (const auto& it : this->subscriptionsMap) + { + std::shared_ptr<Subscription> entry = it.second; +@@ -1291,6 +1325,8 @@ class EventServiceManager + return; + } + ++ deleteTerminatedSubcriptions(); ++ + for (const auto& it : this->subscriptionsMap) + { + std::shared_ptr<Subscription> entry = it.second; +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch deleted file mode 100644 index aabe500f5..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 4cf883dba6e16c56d04dbd092d30c9a13d5a5eb4 Mon Sep 17 00:00:00 2001 -From: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> -Date: Fri, 6 Aug 2021 15:15:17 +0200 -Subject: [PATCH] Add DELETE method for MetricReport - -Added DELETE method for removing Reports by using MetricReports uri; -metric_report.hpp and metric_report_definition.hpp files are sharing -now common lambda function for DELETE operations - -Tested on QEMU: -- Added Reports and requested from bmcweb to delete them via - /redfish/v1/TelemetryService/MetricReports/<reportname> or via - /redfish/v1/TelemetryService/MetricReportDefinitions/<reportname> -- Added two different reports via POST, deleted first of them via - MetricReports DELETE, checked by MetricReports GET if list of reports - contain only second report, deleted second report via MetricReports - DELETE and checked by MetricReports GET if list of reports is empty -- Same as one above but using MetricReportDefinitions DELETE and GET - -Signed-off-by: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> -Change-Id: I151bad363dcabd57246eb10b501abd24107b937e ---- - .../include/utils/telemetry_utils.hpp | 35 +++++++++++++++++++ - redfish-core/lib/metric_report.hpp | 4 +++ - redfish-core/lib/metric_report_definition.hpp | 34 +----------------- - 3 files changed, 40 insertions(+), 33 deletions(-) - -diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp -index 5872350..743585f 100644 ---- a/redfish-core/include/utils/telemetry_utils.hpp -+++ b/redfish-core/include/utils/telemetry_utils.hpp -@@ -70,5 +70,40 @@ inline std::string getDbusReportPath(const std::string& id) - return path; - } - -+inline std::function<void(const crow::Request&, -+ const std::shared_ptr<bmcweb::AsyncResp>&, -+ const std::string&)> -+ getMetricReportDeleteHandler(const std::string& type) -+{ -+ return [type](const crow::Request&, -+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, -+ const std::string& id) { -+ const std::string reportPath = getDbusReportPath(id); -+ -+ crow::connections::systemBus->async_method_call( -+ [asyncResp, type, id](const boost::system::error_code ec) { -+ /* -+ * boost::system::errc and std::errc are missing value -+ * for EBADR error that is defined in Linux. -+ */ -+ if (ec.value() == EBADR) -+ { -+ messages::resourceNotFound(asyncResp->res, type, id); -+ return; -+ } -+ -+ if (ec) -+ { -+ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ -+ asyncResp->res.result(boost::beast::http::status::no_content); -+ }, -+ service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete"); -+ }; -+} -+ - } // namespace telemetry - } // namespace redfish -diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp -index 63c8c19..60ce74e 100644 ---- a/redfish-core/lib/metric_report.hpp -+++ b/redfish-core/lib/metric_report.hpp -@@ -127,5 +127,9 @@ inline void requestRoutesMetricReport(App& app) - telemetry::service, reportPath, telemetry::reportInterface, - "Update"); - }); -+ BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/") -+ .privileges(redfish::privileges::deleteMetricReport) -+ .methods(boost::beast::http::verb::delete_)( -+ telemetry::getMetricReportDeleteHandler("MetricReports")); - } - } // namespace redfish -diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp -index a0c4f1d..e0505e5 100644 ---- a/redfish-core/lib/metric_report_definition.hpp -+++ b/redfish-core/lib/metric_report_definition.hpp -@@ -450,38 +450,6 @@ inline void requestRoutesMetricReportDefinition(App& app) - "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") - .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) - .methods(boost::beast::http::verb::delete_)( -- [](const crow::Request&, -- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, -- const std::string& id) -- -- { -- const std::string reportPath = telemetry::getDbusReportPath(id); -- -- crow::connections::systemBus->async_method_call( -- [asyncResp, id](const boost::system::error_code ec) { -- /* -- * boost::system::errc and std::errc are missing value -- * for EBADR error that is defined in Linux. -- */ -- if (ec.value() == EBADR) -- { -- messages::resourceNotFound( -- asyncResp->res, "MetricReportDefinition", id); -- return; -- } -- -- if (ec) -- { -- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; -- messages::internalError(asyncResp->res); -- return; -- } -- -- asyncResp->res.result( -- boost::beast::http::status::no_content); -- }, -- telemetry::service, reportPath, -- "xyz.openbmc_project.Object.Delete", "Delete"); -- }); -+ telemetry::getMetricReportDeleteHandler("MetricReportDefinition")); - } - } // namespace redfish --- -2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-GET-method-for-TriggerCollection.patch index 0646aba5c..0646aba5c 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-GET-method-for-TriggerCollection.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Revert-Remove-LogService-from-TelemetryService.patch index 987a43b4c..987a43b4c 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Revert-Remove-LogService-from-TelemetryService.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-event-service-fix-added-Context-field-to-response.patch index ffab743f6..ffab743f6 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-event-service-fix-added-Context-field-to-response.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-Generalize-ReadingType-in-MetricDefinition.patch index bd6e64346..bd6e64346 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-Generalize-ReadingType-in-MetricDefinition.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Add-support-for-deleting-terminated-subscriptions.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Add-support-for-deleting-terminated-subscriptions.patch new file mode 100644 index 000000000..548e3d9c6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Add-support-for-deleting-terminated-subscriptions.patch @@ -0,0 +1,46 @@ +From ef83a4fb14648edc6c8370363ff88fb6f060a43b Mon Sep 17 00:00:00 2001 +From: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com> +Date: Mon, 20 Sep 2021 21:55:57 +0530 +Subject: [PATCH] Add support for deleting terminated subscriptions + +Added functionality to delete/remove event subscription(s) which are +configured to Terminate after retries. + +Currently, when an Event is subscribed with Retry Policy as +"TerminateAfterRetries", the state of the connection is set to +"Terminated" after retrying, but the Subscription is not removed. +This commit adds the functionality to detect terminated connection and +remove the respective subscription. + +This commit adds this check for metric reports. + +Tested: + - Created a Subscription with + DeliveryRetryPolicy: "TerminateAfterRetries" + - Received Events successfully on Event listener + - Once the Event listener was stopped, the Subscription was + removed/deleted after retries. + +Change-Id: I3cb0af5bc24411cddcdb3d1d9de25e8e9144106c +Signed-off-by: P Dheeraj Srujan Kumar <p.dheeraj.srujan.kumar@intel.com> +--- + redfish-core/include/event_service_manager.hpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp +index c9e2812..c2fefb3 100644 +--- a/redfish-core/include/event_service_manager.hpp ++++ b/redfish-core/include/event_service_manager.hpp +@@ -1535,6 +1535,9 @@ class EventServiceManager + + std::variant<telemetry::TimestampReadings>& readings = + found->second; ++ ++ this->deleteTerminatedSubcriptions(); ++ + for (const auto& it : + EventServiceManager::getInstance().subscriptionsMap) + { +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README index 8dab07e2b..fd88e9e18 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README @@ -14,17 +14,17 @@ Current revisions: - Add support for MetricDefinition property in MetricReport https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44512/9 -- Add DELETE method for MetricReport - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/45688/5 - - Add GET method for TriggerCollection - file://telemetry/0006-Add-GET-method-for-TriggerCollection.patch + file://telemetry/0005-Add-GET-method-for-TriggerCollection.patch - LogService field, actual implementation will be upstreamed with triggers feature - file://telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch + file://telemetry/0006-Revert-Remove-LogService-from-TelemetryService.patch - Event service fix for Context field - file://telemetry/0008-event-service-fix-added-Context-field-to-response.patch + file://telemetry/0007-event-service-fix-added-Context-field-to-response.patch - Generalize ReadingType in MetricDefinition - file://telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch + file://telemetry/0008-Generalize-ReadingType-in-MetricDefinition.patch + +- Add support for deleting terminated subscriptions + file://telemetry/0009-Add-support-for-deleting-terminated-subscriptions.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend index 0a7d18085..7806b5481 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -36,6 +36,7 @@ SRC_URI += "file://biosconfig/0001-Define-Redfish-interface-Registries-Bios.patc file://biosconfig/0003-Add-support-to-ResetBios-action.patch \ file://biosconfig/0004-Add-support-to-ChangePassword-action.patch \ file://biosconfig/0005-Fix-remove-bios-user-pwd-change-option-via-Redfish.patch \ + file://biosconfig/0006-Add-fix-for-broken-feature-Pending-Attributes.patch \ " # Virtual Media: Backend code is not upstreamed so downstream only patches. @@ -57,6 +58,7 @@ SRC_URI += "file://eventservice/0001-EventService-Fix-retry-handling-for-http-cl file://eventservice/0007-EventService-Log-events-for-subscription-actions.patch \ file://eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch \ file://eventservice/0009-Restructure-Redifsh-EventLog-Transmit-code-flow.patch \ + file://eventservice/0010-Remove-Terminated-Event-Subscriptions.patch \ " # Temporary downstream mirror of upstream patches, see telemetry\README for details @@ -64,11 +66,11 @@ SRC_URI += " file://telemetry/0001-Add-support-for-MetricDefinition-scheme.patch file://telemetry/0002-Sync-Telmetry-service-with-EventService.patch \ file://telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch \ file://telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch \ - file://telemetry/0005-Add-DELETE-method-for-MetricReport.patch \ - file://telemetry/0006-Add-GET-method-for-TriggerCollection.patch \ - file://telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch \ - file://telemetry/0008-event-service-fix-added-Context-field-to-response.patch \ - file://telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch \ + file://telemetry/0005-Add-GET-method-for-TriggerCollection.patch \ + file://telemetry/0006-Revert-Remove-LogService-from-TelemetryService.patch \ + file://telemetry/0007-event-service-fix-added-Context-field-to-response.patch \ + file://telemetry/0008-Generalize-ReadingType-in-MetricDefinition.patch \ + file://telemetry/0009-Add-support-for-deleting-terminated-subscriptions.patch \ " # Temporary fix: Move it to service file @@ -77,6 +79,10 @@ do_install:append() { install -d ${D}/etc/ssl/certs/authority } +# Temporary fix:Enable new power and thermal subsystem +EXTRA_OEMESON += " -Dredfish-new-powersubsystem-thermalsubsystem=enabled" +EXTRA_OEMESON += " -Dredfish-allow-deprecated-power-thermal=disabled" + # Enable PFR support EXTRA_OEMESON += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', '-Dredfish-provisioning-feature=enabled', '', d)}" |