summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch331
1 files changed, 331 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch
new file mode 100644
index 000000000..995b62750
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0002-Match-BMCWeb-crashdump-to-the-D-Bus-interface-provid.patch
@@ -0,0 +1,331 @@
+From 7c55dfb33e035f8a31f11fd3e047a4b674f392ac Mon Sep 17 00:00:00 2001
+From: Johnathan Mantey <johnathanx.mantey@intel.com>
+Date: Tue, 10 Mar 2020 17:15:28 -0700
+Subject: [PATCH] Match BMCWeb crashdump to the D-Bus interface provided by
+ crashdump
+
+The crashdump service changed to eliminate hangs, and failures to
+retrieve the crashdump data. The BMCWeb crashdump handling code has to
+be aligned with the server.
+
+Tested:
+Confirmed each of the primary functions operates as expected.
+Getting the collection
+Getting the entries
+Forcing an on demand capture
+Polling for the on demand capture to complete
+Retrieving the creashdump data
+Clearing all of the crashdump content
+
+Change-Id: Ie8fb48369a782d905b942c1f9bef11f387f6463e
+Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
+---
+ redfish-core/lib/log_services.hpp | 268 +++++++++++++++++-------------
+ 1 file changed, 150 insertions(+), 118 deletions(-)
+
+diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
+index f864007..4b13897 100644
+--- a/redfish-core/lib/log_services.hpp
++++ b/redfish-core/lib/log_services.hpp
+@@ -1575,109 +1575,80 @@ class CrashdumpClear : public Node
+ }
+ };
+
+-std::string getLogCreatedTime(const std::string &crashdump)
+-{
+- nlohmann::json crashdumpJson =
+- nlohmann::json::parse(crashdump, nullptr, false);
+- if (crashdumpJson.is_discarded())
+- {
+- return std::string();
+- }
+-
+- nlohmann::json::const_iterator cdIt = crashdumpJson.find("crash_data");
+- if (cdIt == crashdumpJson.end())
+- {
+- return std::string();
+- }
+-
+- nlohmann::json::const_iterator siIt = cdIt->find("METADATA");
+- if (siIt == cdIt->end())
+- {
+- return std::string();
+- }
+-
+- nlohmann::json::const_iterator tsIt = siIt->find("timestamp");
+- if (tsIt == siIt->end())
+- {
+- return std::string();
+- }
+-
+- const std::string *logTime = tsIt->get_ptr<const std::string *>();
+- if (logTime == nullptr)
+- {
+- return std::string();
+- }
+-
+- std::string redfishDateTime = *logTime;
+- if (redfishDateTime.length() > 2)
+- {
+- redfishDateTime.insert(redfishDateTime.end() - 2, ':');
+- }
+-
+- return redfishDateTime;
+-}
+-
+-std::string getLogFileName(const std::string &logTime)
+-{
+- // Set the crashdump file name to "crashdump_<logTime>.json" using the
+- // created time without the timezone info
+- std::string fileTime = logTime;
+- size_t plusPos = fileTime.rfind('+');
+- if (plusPos != std::string::npos)
+- {
+- fileTime.erase(plusPos);
+- }
+- return "crashdump_" + fileTime + ".json";
+-}
+-
+ static void logCrashdumpEntry(std::shared_ptr<AsyncResp> asyncResp,
+ const std::string &logID,
+ nlohmann::json &logEntryJson)
+ {
+- auto getStoredLogCallback = [asyncResp, logID, &logEntryJson](
+- const boost::system::error_code ec,
+- const std::variant<std::string> &resp) {
+- if (ec)
+- {
+- BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
+- if (ec.value() ==
+- boost::system::linux_error::bad_request_descriptor)
++ auto getStoredLogCallback =
++ [asyncResp, logID, &logEntryJson](
++ const boost::system::error_code ec,
++ const std::vector<std::pair<std::string, VariantType>> &params) {
++ if (ec)
+ {
+- messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
++ BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
++ if (ec.value() ==
++ boost::system::linux_error::bad_request_descriptor)
++ {
++ messages::resourceNotFound(asyncResp->res, "LogEntry",
++ logID);
++ }
++ else
++ {
++ messages::internalError(asyncResp->res);
++ }
++ return;
+ }
+- else
++
++ std::string timestamp{};
++ std::string filename{};
++ for (auto property : params)
+ {
+- messages::internalError(asyncResp->res);
++ if (property.first == "Timestamp")
++ {
++ const std::string *value =
++ sdbusplus::message::variant_ns::get_if<std::string>(
++ &property.second);
++ if (value != nullptr)
++ {
++ timestamp = *value;
++ }
++ }
++ else if (property.first == "Filename")
++ {
++ const std::string *value =
++ sdbusplus::message::variant_ns::get_if<std::string>(
++ &property.second);
++ if (value != nullptr)
++ {
++ filename = *value;
++ }
++ }
+ }
+- return;
+- }
+- const std::string *log = std::get_if<std::string>(&resp);
+- if (log == nullptr)
+- {
+- messages::internalError(asyncResp->res);
+- return;
+- }
+- std::string logTime = getLogCreatedTime(*log);
+- std::string fileName = getLogFileName(logTime);
+
+- logEntryJson = {
+- {"@odata.type", "#LogEntry.v1_4_0.LogEntry"},
+- {"@odata.id",
+- "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/" +
+- logID},
+- {"Name", "CPU Crashdump"},
+- {"Id", logID},
+- {"EntryType", "Oem"},
+- {"OemRecordFormat", "Crashdump URI"},
+- {"Message",
+- "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/" +
+- logID + "/" + fileName},
+- {"Created", std::move(logTime)}};
+- };
++ if (filename.empty() || timestamp.empty())
++ {
++ messages::resourceMissingAtURI(asyncResp->res, logID);
++ return;
++ }
++
++ std::string crashdumpURI =
++ "/redfish/v1/Systems/system/LogServices/Crashdump/Entries/" +
++ logID + "/" + filename;
++ logEntryJson = {{"@odata.type", "#LogEntry.v1_4_0.LogEntry"},
++ {"@odata.id", "/redfish/v1/Systems/system/"
++ "LogServices/Crashdump/Entries/" +
++ logID},
++ {"Name", "CPU Crashdump"},
++ {"Id", logID},
++ {"EntryType", "Oem"},
++ {"OemRecordFormat", "Crashdump URI"},
++ {"Message", std::move(crashdumpURI)},
++ {"Created", std::move(timestamp)}};
++ };
+ crow::connections::systemBus->async_method_call(
+ std::move(getStoredLogCallback), crashdumpObject,
+ crashdumpPath + std::string("/") + logID,
+- "org.freedesktop.DBus.Properties", "Get", crashdumpInterface, "Log");
++ "org.freedesktop.DBus.Properties", "GetAll", crashdumpInterface);
+ }
+
+ class CrashdumpEntryCollection : public Node
+@@ -1827,38 +1798,99 @@ class CrashdumpFile : public Node
+ const std::string &logID = params[0];
+ const std::string &fileName = params[1];
+
+- auto getStoredLogCallback = [asyncResp, logID, fileName](
+- const boost::system::error_code ec,
+- const std::variant<std::string> &resp) {
+- if (ec)
+- {
+- BMCWEB_LOG_DEBUG << "failed to get log ec: " << ec.message();
+- messages::internalError(asyncResp->res);
+- return;
+- }
+- const std::string *log = std::get_if<std::string>(&resp);
+- if (log == nullptr)
+- {
+- messages::internalError(asyncResp->res);
+- return;
+- }
++ auto getStoredLogCallback =
++ [asyncResp, logID, fileName](
++ const boost::system::error_code ec,
++ const std::vector<std::pair<std::string, VariantType>> &resp) {
++ if (ec)
++ {
++ BMCWEB_LOG_DEBUG << "failed to get log ec: "
++ << ec.message();
++ messages::internalError(asyncResp->res);
++ return;
++ }
+
+- // Verify the file name parameter is correct
+- if (fileName != getLogFileName(getLogCreatedTime(*log)))
+- {
+- messages::resourceMissingAtURI(asyncResp->res, fileName);
+- return;
+- }
++ std::string dbusFilename{};
++ std::string dbusTimestamp{};
++ std::string dbusFilepath{};
+
+- // Configure this to be a file download when accessed from a browser
+- asyncResp->res.addHeader("Content-Disposition", "attachment");
+- asyncResp->res.body() = *log;
+- };
++ for (auto property : resp)
++ {
++ if (property.first == "Timestamp")
++ {
++ const std::string *value =
++ sdbusplus::message::variant_ns::get_if<std::string>(
++ &property.second);
++ if (value != nullptr)
++ {
++ dbusTimestamp = *value;
++ }
++ }
++ else if (property.first == "Filename")
++ {
++ const std::string *value =
++ sdbusplus::message::variant_ns::get_if<std::string>(
++ &property.second);
++ if (value != nullptr)
++ {
++ dbusFilename = *value;
++ }
++ }
++ else if (property.first == "Log")
++ {
++ const std::string *value =
++ sdbusplus::message::variant_ns::get_if<std::string>(
++ &property.second);
++ if (value != nullptr)
++ {
++ dbusFilepath = *value;
++ }
++ }
++ }
++
++ if (dbusFilename.empty() || dbusTimestamp.empty() ||
++ dbusFilepath.empty())
++ {
++ messages::resourceMissingAtURI(asyncResp->res, fileName);
++ return;
++ }
++
++ // Verify the file name parameter is correct
++ if (fileName != dbusFilename)
++ {
++ messages::resourceMissingAtURI(asyncResp->res, fileName);
++ return;
++ }
++
++ if (!std::filesystem::exists(dbusFilepath))
++ {
++ messages::resourceMissingAtURI(asyncResp->res, fileName);
++ return;
++ }
++ std::ifstream ifs(dbusFilepath, std::ios::in |
++ std::ios::binary |
++ std::ios::ate);
++ std::ifstream::pos_type fileSize = ifs.tellg();
++ if (fileSize < 0)
++ {
++ messages::generalError(asyncResp->res);
++ return;
++ }
++ ifs.seekg(0, std::ios::beg);
++
++ std::string dumpData;
++ dumpData.reserve(static_cast<unsigned int>(fileSize));
++ ifs.read(dumpData.data(), static_cast<int>(fileSize));
++
++ // Configure this to be a file download when accessed from
++ // a browser
++ asyncResp->res.addHeader("Content-Disposition", "attachment");
++ asyncResp->res.body() = dumpData.data();
++ };
+ crow::connections::systemBus->async_method_call(
+ std::move(getStoredLogCallback), crashdumpObject,
+ crashdumpPath + std::string("/") + logID,
+- "org.freedesktop.DBus.Properties", "Get", crashdumpInterface,
+- "Log");
++ "org.freedesktop.DBus.Properties", "GetAll", crashdumpInterface);
+ }
+ };
+
+--
+2.25.1
+