diff options
author | Asmitha Karunanithi <asmitk01@in.ibm.com> | 2020-05-07 12:35:02 +0300 |
---|---|---|
committer | Ratan Gupta <ratagupt@linux.vnet.ibm.com> | 2020-07-28 08:27:23 +0300 |
commit | 5cb1dd27f5868ad8b027aa3f29cc0c4e6c429f39 (patch) | |
tree | f755336bd8756450ccbc1cde5b0284a7b7125702 | |
parent | 40e7fea29c31dc16b31119986b0a4adc06f7e52f (diff) | |
download | bmcweb-5cb1dd27f5868ad8b027aa3f29cc0c4e6c429f39.tar.xz |
Redfish: BMC dump logEntry service implementation
This commit supports adding a BMC dump entry under /redfish/
v1/Managers/bmc/LogServices/Dump
* Removed the option for enabling each dump separately. Instead
introduced one common option to enable dump.
* Defined few methods that are common for both BMC and System dumps.
* Compilation flag DBMCWEB_ENABLE_REDFISH_DUMP_LOG must be enabled.
Tested-By:
* curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${bmc}/
redfish/v1/Managers/bmc/LogServices/
* curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${bmc}/
redfish/v1/Managers/bmc/LogServices/Dump
* curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${bmc}/
redfish/v1/Managers/bmc/LogServices/Dump/Entries
* curl -k -H "X-Auth-Token: $bmc_token" -X GET https://${bmc}/
redfish/v1/Managers/bmc/LogServices/Dump/Entries/<dump-id>
* curl -k -H "X-Auth-Token: $bmc_token" -X DELETE https://${bmc}/
redfish/v1/Managers/bmc/LogServices/Dump/Entries/<dump-id>
Redfish Validator passed.
Signed-off-by: Asmitha Karunanithi <asmitk01@in.ibm.com>
Change-Id: Iac9daa8242154e249fad66609b837cf7d2b16091
-rw-r--r-- | CMakeLists.txt | 11 | ||||
-rw-r--r-- | redfish-core/include/redfish.hpp | 7 | ||||
-rw-r--r-- | redfish-core/lib/log_services.hpp | 688 |
3 files changed, 475 insertions, 231 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index aacd34fe5b..288643819e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,9 +71,10 @@ option ( OFF ) option ( - BMCWEB_ENABLE_REDFISH_SYSTEMDUMP_LOG - "Enable System dump log service transactions through Redfish. Paths are under - '/redfish/v1/Systems/system/LogServices/SystemDump'." + BMCWEB_ENABLE_REDFISH_DUMP_LOG + "Enable BMC and System dump log service transactions through Redfish. For BMC dump, paths + are under '/redfish/v1/Managers/bmc/LogServices/Dump' and for System dump, + paths are under '/redfish/v1/Systems/system/LogServices/Dump'." OFF ) option ( @@ -413,8 +414,8 @@ target_compile_definitions ( -DBMCWEB_ENABLE_REDFISH_RAW_PECI> $<$<BOOL:${BMCWEB_ENABLE_REDFISH_CPU_LOG}>: -DBMCWEB_ENABLE_REDFISH_CPU_LOG> - $<$<BOOL:${BMCWEB_ENABLE_REDFISH_SYSTEMDUMP_LOG}>: - -DBMCWEB_ENABLE_REDFISH_SYSTEMDUMP_LOG> + $<$<BOOL:${BMCWEB_ENABLE_REDFISH_DUMP_LOG}>: + -DBMCWEB_ENABLE_REDFISH_DUMP_LOG> $<$<BOOL:${BMCWEB_ENABLE_REDFISH_BMC_JOURNAL}>: -DBMCWEB_ENABLE_REDFISH_BMC_JOURNAL> $<$<BOOL:${BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES}>: diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp index cc98e1a2ed..5dee66b2e2 100644 --- a/redfish-core/include/redfish.hpp +++ b/redfish-core/include/redfish.hpp @@ -104,12 +104,17 @@ class RedfishService nodes.emplace_back(std::make_unique<PostCodesEntry>(app)); nodes.emplace_back(std::make_unique<PostCodesEntryCollection>(app)); -#ifdef BMCWEB_ENABLE_REDFISH_SYSTEMDUMP_LOG +#ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG nodes.emplace_back(std::make_unique<SystemDumpService>(app)); nodes.emplace_back(std::make_unique<SystemDumpEntryCollection>(app)); nodes.emplace_back(std::make_unique<SystemDumpEntry>(app)); nodes.emplace_back(std::make_unique<SystemDumpEntryDownload>(app)); nodes.emplace_back(std::make_unique<SystemDumpClear>(app)); + + nodes.emplace_back(std::make_unique<BMCDumpService>(app)); + nodes.emplace_back(std::make_unique<BMCDumpEntryCollection>(app)); + nodes.emplace_back(std::make_unique<BMCDumpEntry>(app)); + #endif #ifndef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp index baef92f48e..22c3ad78bb 100644 --- a/redfish-core/lib/log_services.hpp +++ b/redfish-core/lib/log_services.hpp @@ -143,28 +143,6 @@ inline std::string translateSeverityDbusToRedfish(const std::string& s) return ""; } -inline void deleteSystemDumpEntry(crow::Response& res, - const std::string& entryID) -{ - std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); - - auto respHandler = [asyncResp](const boost::system::error_code ec) { - BMCWEB_LOG_DEBUG << "System Dump Entry doDelete callback: Done"; - if (ec) - { - BMCWEB_LOG_ERROR - << "System Dump (DBus) doDelete respHandler got error " << ec; - asyncResp->res.result( - boost::beast::http::status::internal_server_error); - return; - } - }; - crow::connections::systemBus->async_method_call( - respHandler, "xyz.openbmc_project.Dump.Manager", - "/xyz/openbmc_project/dump/entry/" + entryID, - "xyz.openbmc_project.Object.Delete", "Delete"); -} - static int getJournalMetadata(sd_journal* journal, const std::string_view& field, std::string_view& contents) @@ -450,6 +428,317 @@ static bool return !redfishLogFiles.empty(); } +inline void getDumpEntryCollection(std::shared_ptr<AsyncResp>& asyncResp, + const std::string& dumpType) +{ + std::string dumpPath; + if (dumpType == "BMC") + { + dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/"; + } + else if (dumpType == "System") + { + dumpPath = "/redfish/v1/Systems/system/LogServices/Dump/Entries/"; + } + else + { + BMCWEB_LOG_ERROR << "Invalid dump type" << dumpType; + messages::internalError(asyncResp->res); + return; + } + + crow::connections::systemBus->async_method_call( + [asyncResp, dumpPath, dumpType](const boost::system::error_code ec, + GetManagedObjectsType& resp) { + if (ec) + { + BMCWEB_LOG_ERROR << "DumpEntry resp_handler got error " << ec; + messages::internalError(asyncResp->res); + return; + } + + nlohmann::json& entriesArray = asyncResp->res.jsonValue["Members"]; + entriesArray = nlohmann::json::array(); + + for (auto& object : resp) + { + bool foundDumpEntry = false; + for (auto& interfaceMap : object.second) + { + if (interfaceMap.first == + ("xyz.openbmc_project.Dump.Entry." + dumpType)) + { + foundDumpEntry = true; + break; + } + } + + if (foundDumpEntry == false) + { + continue; + } + std::time_t timestamp; + uint64_t size = 0; + entriesArray.push_back({}); + nlohmann::json& thisEntry = entriesArray.back(); + const std::string& path = + static_cast<const std::string&>(object.first); + std::size_t lastPos = path.rfind("/"); + if (lastPos == std::string::npos) + { + continue; + } + std::string entryID = path.substr(lastPos + 1); + + for (auto& interfaceMap : object.second) + { + if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry") + { + + for (auto& propertyMap : interfaceMap.second) + { + if (propertyMap.first == "Size") + { + auto sizePtr = + std::get_if<uint64_t>(&propertyMap.second); + if (sizePtr == nullptr) + { + messages::internalError(asyncResp->res); + break; + } + size = *sizePtr; + break; + } + } + } + else if (interfaceMap.first == + "xyz.openbmc_project.Time.EpochTime") + { + + for (auto& propertyMap : interfaceMap.second) + { + if (propertyMap.first == "Elapsed") + { + const uint64_t* usecsTimeStamp = + std::get_if<uint64_t>(&propertyMap.second); + if (usecsTimeStamp == nullptr) + { + messages::internalError(asyncResp->res); + break; + } + timestamp = + static_cast<std::time_t>(*usecsTimeStamp); + break; + } + } + } + } + + thisEntry["@odata.type"] = "#LogEntry.v1_5_1.LogEntry"; + thisEntry["@odata.id"] = dumpPath + entryID; + thisEntry["Id"] = entryID; + thisEntry["EntryType"] = "Event"; + thisEntry["Created"] = crow::utility::getDateTime(timestamp); + thisEntry["Name"] = dumpType + " Dump Entry"; + + thisEntry["Oem"]["OpenBmc"]["@odata.type"] = + "#OemLogEntry.v1_0_0.OpenBmc"; + thisEntry["Oem"]["OpenBmc"]["AdditionalDataSizeBytes"] = size; + + if (dumpType == "BMC") + { + thisEntry["Oem"]["OpenBmc"]["DiagnosticDataType"] = + "Manager"; + thisEntry["Oem"]["OpenBmc"]["AdditionalDataURI"] = + "/redfish/v1/Managers/bmc/LogServices/Dump/" + "attachment/" + + entryID; + } + else if (dumpType == "System") + { + thisEntry["Oem"]["OpenBmc"]["DiagnosticDataType"] = "OEM"; + thisEntry["Oem"]["OpenBmc"]["OEMDiagnosticDataType"] = + "System"; + thisEntry["Oem"]["OpenBmc"]["AdditionalDataURI"] = + "/redfish/v1/Systems/system/LogServices/Dump/" + "attachment/" + + entryID; + } + } + asyncResp->res.jsonValue["Members@odata.count"] = + entriesArray.size(); + }, + "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump", + "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); +} + +inline void getDumpEntryById(std::shared_ptr<AsyncResp>& asyncResp, + const std::string& entryID, + const std::string& dumpType) +{ + std::string dumpPath; + if (dumpType == "BMC") + { + dumpPath = "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/"; + } + else if (dumpType == "System") + { + dumpPath = "/redfish/v1/Systems/system/LogServices/Dump/Entries/"; + } + else + { + BMCWEB_LOG_ERROR << "Invalid dump type" << dumpType; + messages::internalError(asyncResp->res); + return; + } + + crow::connections::systemBus->async_method_call( + [asyncResp, entryID, dumpPath, dumpType]( + const boost::system::error_code ec, GetManagedObjectsType& resp) { + if (ec) + { + BMCWEB_LOG_ERROR << "DumpEntry resp_handler got error " << ec; + messages::internalError(asyncResp->res); + return; + } + + for (auto& objectPath : resp) + { + if (objectPath.first.str.find( + "/xyz/openbmc_project/dump/entry/" + entryID) == + std::string::npos) + { + continue; + } + + bool foundDumpEntry = false; + for (auto& interfaceMap : objectPath.second) + { + if (interfaceMap.first == + ("xyz.openbmc_project.Dump.Entry." + dumpType)) + { + foundDumpEntry = true; + break; + } + } + if (foundDumpEntry == false) + { + BMCWEB_LOG_ERROR << "Can't find Dump Entry"; + messages::internalError(asyncResp->res); + return; + } + + std::time_t timestamp; + uint64_t size = 0; + + for (auto& interfaceMap : objectPath.second) + { + if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry") + { + for (auto& propertyMap : interfaceMap.second) + { + if (propertyMap.first == "Size") + { + auto sizePtr = + std::get_if<uint64_t>(&propertyMap.second); + if (sizePtr == nullptr) + { + messages::internalError(asyncResp->res); + break; + } + size = *sizePtr; + break; + } + } + } + else if (interfaceMap.first == + "xyz.openbmc_project.Time.EpochTime") + { + for (auto& propertyMap : interfaceMap.second) + { + if (propertyMap.first == "Elapsed") + { + const uint64_t* usecsTimeStamp = + std::get_if<uint64_t>(&propertyMap.second); + if (usecsTimeStamp == nullptr) + { + messages::internalError(asyncResp->res); + break; + } + timestamp = + static_cast<std::time_t>(*usecsTimeStamp); + break; + } + } + } + } + + asyncResp->res.jsonValue["@odata.type"] = + "#LogEntry.v1_5_1.LogEntry"; + asyncResp->res.jsonValue["@odata.id"] = dumpPath + entryID; + asyncResp->res.jsonValue["Id"] = entryID; + asyncResp->res.jsonValue["EntryType"] = "Event"; + asyncResp->res.jsonValue["Created"] = + crow::utility::getDateTime(timestamp); + asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry"; + + asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] = + "#OemLogEntry.v1_0_0.OpenBmc"; + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["AdditionalDataSizeBytes"] = + size; + + if (dumpType == "BMC") + { + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["DiagnosticDataType"] = + "Manager"; + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["AdditionalDataURI"] = + "/redfish/v1/Managers/bmc/LogServices/Dump/" + "attachment/" + + entryID; + } + else if (dumpType == "System") + { + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["DiagnosticDataType"] = + "OEM"; + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["OEMDiagnosticDataType"] = + "System"; + asyncResp->res + .jsonValue["Oem"]["OpenBmc"]["AdditionalDataURI"] = + "/redfish/v1/Systems/system/LogServices/Dump/" + "attachment/" + + entryID; + } + } + }, + "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump", + "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); +} + +inline void deleteDumpEntry(crow::Response& res, const std::string& entryID) +{ + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); + + auto respHandler = [asyncResp](const boost::system::error_code ec) { + BMCWEB_LOG_DEBUG << "Dump Entry doDelete callback: Done"; + if (ec) + { + BMCWEB_LOG_ERROR << "Dump (DBus) doDelete respHandler got error " + << ec; + messages::internalError(asyncResp->res); + return; + } + }; + crow::connections::systemBus->async_method_call( + respHandler, "xyz.openbmc_project.Dump.Manager", + "/xyz/openbmc_project/dump/entry/" + entryID, + "xyz.openbmc_project.Object.Delete", "Delete"); +} + static void ParseCrashdumpParameters( const std::vector<std::pair<std::string, VariantType>>& params, std::string& filename, std::string& timestamp, std::string& logfile) @@ -524,9 +813,9 @@ class SystemLogServiceCollection : public Node logServiceArray = nlohmann::json::array(); logServiceArray.push_back( {{"@odata.id", "/redfish/v1/Systems/system/LogServices/EventLog"}}); -#ifdef BMCWEB_ENABLE_REDFISH_SYSTEMDUMP_LOG +#ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG logServiceArray.push_back( - {{"@odata.id", "/redfish/v1/Systems/system/LogServices/System"}}); + {{"@odata.id", "/redfish/v1/Systems/system/LogServices/Dump"}}); #endif #ifdef BMCWEB_ENABLE_REDFISH_CPU_LOG @@ -1274,6 +1563,10 @@ class BMCLogServiceCollection : public Node "Collection of LogServices for this Manager"; nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"]; logServiceArray = nlohmann::json::array(); +#ifdef BMCWEB_ENABLE_REDFISH_DUMP_LOG + logServiceArray.push_back( + {{"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Dump"}}); +#endif #ifdef BMCWEB_ENABLE_REDFISH_BMC_JOURNAL logServiceArray.push_back( {{"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Journal"}}); @@ -1555,12 +1848,135 @@ class BMCJournalLogEntry : public Node } }; +class BMCDumpService : public Node +{ + public: + template <typename CrowApp> + BMCDumpService(CrowApp& app) : + Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/") + { + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, + {boost::beast::http::verb::put, {{"ConfigureManager"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, + {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; + } + + private: + void doGet(crow::Response& res, const crow::Request& req, + const std::vector<std::string>& params) override + { + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); + + asyncResp->res.jsonValue["@odata.id"] = + "/redfish/v1/Managers/bmc/LogServices/Dump"; + asyncResp->res.jsonValue["@odata.type"] = + "#LogService.v1_1_0.LogService"; + asyncResp->res.jsonValue["Name"] = "Dump LogService"; + asyncResp->res.jsonValue["Description"] = "BMC Dump LogService"; + asyncResp->res.jsonValue["Id"] = "Dump"; + asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; + asyncResp->res.jsonValue["Entries"] = { + {"@odata.id", "/redfish/v1/Managers/bmc/LogServices/Dump/Entries"}}; + asyncResp->res.jsonValue["Actions"] = { + {"#LogService.ClearLog", + {{"target", "/redfish/v1/Managers/bmc/LogServices/Dump/" + "Actions/LogService.ClearLog"}}}, + {"Oem", + {{"#OemLogService.CollectDiagnosticData", + {{"target", + "/redfish/v1/Managers/bmc/LogServices/Dump/" + "Actions/Oem/OemLogService.CollectDiagnosticData"}}}}}}; + } +}; + +class BMCDumpEntryCollection : public Node +{ + public: + template <typename CrowApp> + BMCDumpEntryCollection(CrowApp& app) : + Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/") + { + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, + {boost::beast::http::verb::put, {{"ConfigureManager"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, + {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; + } + + private: + /** + * Functions triggers appropriate requests on DBus + */ + void doGet(crow::Response& res, const crow::Request& req, + const std::vector<std::string>& params) override + { + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); + + asyncResp->res.jsonValue["@odata.type"] = + "#LogEntryCollection.LogEntryCollection"; + asyncResp->res.jsonValue["@odata.id"] = + "/redfish/v1/Managers/bmc/LogServices/Dump/Entries"; + asyncResp->res.jsonValue["Name"] = "BMC Dump Entries"; + asyncResp->res.jsonValue["Description"] = + "Collection of BMC Dump Entries"; + + getDumpEntryCollection(asyncResp, "BMC"); + } +}; + +class BMCDumpEntry : public Node +{ + public: + BMCDumpEntry(CrowApp& app) : + Node(app, "/redfish/v1/Managers/bmc/LogServices/Dump/Entries/<str>/", + std::string()) + { + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, + {boost::beast::http::verb::put, {{"ConfigureManager"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, + {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; + } + + private: + void doGet(crow::Response& res, const crow::Request& req, + const std::vector<std::string>& params) override + { + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); + if (params.size() != 1) + { + messages::internalError(asyncResp->res); + return; + } + getDumpEntryById(asyncResp, params[0], "BMC"); + } + + void doDelete(crow::Response& res, const crow::Request& req, + const std::vector<std::string>& params) override + { + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); + if (params.size() != 1) + { + messages::internalError(asyncResp->res); + return; + } + deleteDumpEntry(asyncResp->res, params[0]); + } +}; + class SystemDumpService : public Node { public: template <typename CrowApp> SystemDumpService(CrowApp& app) : - Node(app, "/redfish/v1/Systems/system/LogServices/System/") + Node(app, "/redfish/v1/Systems/system/LogServices/Dump/") { entityPrivileges = { {boost::beast::http::verb::get, {{"Login"}}}, @@ -1578,25 +1994,25 @@ class SystemDumpService : public Node std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); asyncResp->res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/LogServices/System"; + "/redfish/v1/Systems/system/LogServices/Dump"; asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_1_0.LogService"; - asyncResp->res.jsonValue["Name"] = "Dump Log Service"; - asyncResp->res.jsonValue["Description"] = "System Dump Log Service"; - asyncResp->res.jsonValue["Id"] = "System"; + asyncResp->res.jsonValue["Name"] = "Dump LogService"; + asyncResp->res.jsonValue["Description"] = "System Dump LogService"; + asyncResp->res.jsonValue["Id"] = "Dump"; asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull"; - asyncResp->res.jsonValue["LogEntryTypes"] = "Dump"; - asyncResp->res.jsonValue["Oem"]["DumpType"] = "System"; - asyncResp->res.jsonValue["Entries"] = { {"@odata.id", - "/redfish/v1/Systems/system/LogServices/System/Entries"}}; - asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"] = { - {"target", "/redfish/v1/Systems/system/LogServices/System/" - "Actions/LogService.ClearLog"}}; - asyncResp->res.jsonValue["Actions"]["#LogService.CreateLog"] = { - {"target", "/redfish/v1/Systems/system/LogServices/System/" - "Actions/LogService.CreateLog"}}; + "/redfish/v1/Systems/system/LogServices/Dump/Entries"}}; + asyncResp->res.jsonValue["Actions"] = { + {"#LogService.ClearLog", + {{"target", "/redfish/v1/Systems/system/LogServices/Dump/Actions/" + "LogService.ClearLog"}}}, + {"Oem", + {{"#OemLogService.CollectDiagnosticData", + {{"target", + "/redfish/v1/Systems/system/LogServices/Dump/Actions/Oem/" + "OemLogService.CollectDiagnosticData"}}}}}}; } }; @@ -1605,7 +2021,7 @@ class SystemDumpEntryCollection : public Node public: template <typename CrowApp> SystemDumpEntryCollection(CrowApp& app) : - Node(app, "/redfish/v1/Systems/system/LogServices/System/Entries/") + Node(app, "/redfish/v1/Systems/system/LogServices/Dump/Entries/") { entityPrivileges = { {boost::beast::http::verb::get, {{"Login"}}}, @@ -1628,47 +2044,12 @@ class SystemDumpEntryCollection : public Node asyncResp->res.jsonValue["@odata.type"] = "#LogEntryCollection.LogEntryCollection"; asyncResp->res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/LogServices/System/Entries"; + "/redfish/v1/Systems/system/LogServices/Dump/Entries"; asyncResp->res.jsonValue["Name"] = "System Dump Entries"; asyncResp->res.jsonValue["Description"] = "Collection of System Dump Entries"; - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec, - const crow::openbmc_mapper::GetSubTreeType& resp) { - if (ec) - { - BMCWEB_LOG_ERROR << " resp_handler got error " << ec; - messages::internalError(asyncResp->res); - return; - } - - nlohmann::json& logArray = asyncResp->res.jsonValue["Members"]; - logArray = nlohmann::json::array(); - for (auto& object : resp) - { - const std::string& path = - static_cast<const std::string&>(object.first); - std::size_t lastPos = path.rfind("/"); - if (lastPos == std::string::npos) - { - continue; - } - std::string logID = path.substr(lastPos + 1); - logArray.push_back( - {{"@odata.id", "/redfish/v1/Systems/system/LogServices/" - "System/Entries/" + - logID}}); - } - asyncResp->res.jsonValue["Members@odata.count"] = - logArray.size(); - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTree", - "/xyz/openbmc_project/dump", 0, - std::array<const char*, 1>{ - "xyz.openbmc_project.Dump.Entry.System"}); + getDumpEntryCollection(asyncResp, "System"); } }; @@ -1676,8 +2057,7 @@ class SystemDumpEntry : public Node { public: SystemDumpEntry(CrowApp& app) : - Node(app, - "/redfish/v1/Systems/system/LogServices/System/Entries/<str>/", + Node(app, "/redfish/v1/Systems/system/LogServices/Dump/Entries/<str>/", std::string()) { entityPrivileges = { @@ -1699,161 +2079,19 @@ class SystemDumpEntry : public Node messages::internalError(asyncResp->res); return; } - const std::string& entryID = params[0]; - crow::connections::systemBus->async_method_call( - [asyncResp, entryID](const boost::system::error_code ec, - GetManagedObjectsType& resp) { - if (ec) - { - BMCWEB_LOG_ERROR - << "SystemDumpEntry resp_handler got error " << ec; - messages::internalError(asyncResp->res); - return; - } - - for (auto& objectPath : resp) - { - if (objectPath.first.str.find( - "/xyz/openbmc_project/dump/entry/" + entryID) == - std::string::npos) - { - continue; - } - - bool foundSystemDumpEntry = false; - for (auto& interfaceMap : objectPath.second) - { - if (interfaceMap.first == - "xyz.openbmc_project.Dump.Entry.System") - { - foundSystemDumpEntry = true; - break; - } - } - if (foundSystemDumpEntry == false) - { - BMCWEB_LOG_DEBUG << "Can't find System Dump Entry"; - messages::internalError(asyncResp->res); - return; - } - - std::string timestamp{}; - uint64_t size = 0; - - for (auto& interfaceMap : objectPath.second) - { - if (interfaceMap.first == - "xyz.openbmc_project.Dump.Entry") - { - for (auto& propertyMap : interfaceMap.second) - { - if (propertyMap.first == "Size") - { - auto sizePtr = std::get_if<uint64_t>( - &propertyMap.second); - if (sizePtr == nullptr) - { - messages::propertyMissing( - asyncResp->res, "Size"); - break; - } - size = *sizePtr; - break; - } - } - } - else if (interfaceMap.first == - "xyz.openbmc_project.Time.EpochTime") - { - for (auto& propertyMap : interfaceMap.second) - { - if (propertyMap.first == "Elapsed") - { - const uint64_t* usecsTimeStamp = - std::get_if<uint64_t>( - &propertyMap.second); - if (usecsTimeStamp == nullptr) - { - messages::propertyMissing( - asyncResp->res, "Elapsed"); - break; - } - getTimestampStr(*usecsTimeStamp, timestamp); - break; - } - } - } - } - asyncResp->res.jsonValue = { - {"@odata.type", "#LogEntry.v1_4_0.LogEntry"}, - {"@odata.id", - "/redfish/v1/Systems/system/LogServices/System/" - "Entries/" + - entryID}, - {"Name", "System Dump Entry"}, - {"Id", entryID}, - {"SizeInB", size}, - {"EntryType", "Dump"}, - {"EntryCode", "User generated dump"}, - {"Created", timestamp}}; - - asyncResp->res - .jsonValue["Actions"]["#LogEntry.DownloadLog"] = { - {"target", - "/redfish/v1/Systems/system/LogServices/System/" - "Entries/" + - entryID + "/Actions/LogEntry.DownloadLog"}}; - } - }, - "xyz.openbmc_project.Dump.Manager", "/xyz/openbmc_project/dump", - "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); + getDumpEntryById(asyncResp, params[0], "System"); } void doDelete(crow::Response& res, const crow::Request& req, const std::vector<std::string>& params) override { - BMCWEB_LOG_DEBUG << "Do delete single dump entry"; - - auto asyncResp = std::make_shared<AsyncResp>(res); - + std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); if (params.size() != 1) { messages::internalError(asyncResp->res); return; } - std::string entryID = params[0]; - - crow::connections::systemBus->async_method_call( - [asyncResp, - entryID](const boost::system::error_code ec, - const crow::openbmc_mapper::GetSubTreeType& resp) { - if (ec) - { - BMCWEB_LOG_ERROR << " resp_handler got error " << ec; - messages::internalError(asyncResp->res); - return; - } - - for (auto& object : resp) - { - const std::string& path = - static_cast<const std::string&>(object.first); - - std::size_t pos = path.rfind( - "/xyz/openbmc_project/dump/entry/" + entryID); - if (pos != std::string::npos) - { - deleteSystemDumpEntry(asyncResp->res, entryID); - return; - } - } - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTree", - "/xyz/openbmc_project/dump", 0, - std::array<const char*, 1>{ - "xyz.openbmc_project.Dump.Entry.System"}); + deleteDumpEntry(asyncResp->res, params[0]); } }; @@ -1922,7 +2160,7 @@ class SystemDumpClear : public Node if (pos != std::string::npos) { std::string logID = objectPath.substr(pos + 1); - deleteSystemDumpEntry(asyncResp->res, logID); + deleteDumpEntry(asyncResp->res, logID); } } }, |