blob: 74ec563f4c62b1eaa0dd42ed58af8e5dc58fd8aa [file] [log] [blame]
Dhruvaraj Subhashchandran858d1aa2021-10-27 03:26:06 -05001#include "dump_utils.hpp"
2
3#include <phosphor-logging/elog-errors.hpp>
4#include <phosphor-logging/elog.hpp>
5#include <phosphor-logging/lg2.hpp>
6#include <phosphor-logging/log.hpp>
7#include <xyz/openbmc_project/Common/File/error.hpp>
8
9#include <format>
10#include <fstream>
11#include <string>
12
13namespace openpower::dump::util
14{
15using namespace phosphor::logging;
16
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050017static void monitorDumpCreation(const std::string& path, const uint32_t timeout)
18{
19 bool inProgress = true;
20 auto bus = sdbusplus::bus::new_system();
Patrick Williams9ae780d2024-04-26 02:34:31 -050021 auto match = sdbusplus::bus::match_t(
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050022 bus,
23 sdbusplus::bus::match::rules::propertiesChanged(
24 path, "xyz.openbmc_project.Common.Progress"),
Patrick Williams9ae780d2024-04-26 02:34:31 -050025 [&](sdbusplus::message_t& msg) {
Patrick Williams540521e2024-08-16 15:20:03 -040026 std::string interface;
27 std::map<std::string, std::variant<std::string, uint8_t>> property;
28 msg.read(interface, property);
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050029
Patrick Williams540521e2024-08-16 15:20:03 -040030 const auto dumpStatus = property.find("Status");
31 if (dumpStatus != property.end())
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050032 {
Patrick Williams540521e2024-08-16 15:20:03 -040033 const std::string* status =
34 std::get_if<std::string>(&(dumpStatus->second));
35 if (status &&
36 *status !=
37 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
38 {
39 lg2::info("Dump status({STATUS}) : path={PATH}", "STATUS",
40 status->c_str(), "PATH", path.c_str());
41 inProgress = false;
42 }
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050043 }
Patrick Williams540521e2024-08-16 15:20:03 -040044 });
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050045
46 // Timeout management
47 for (uint32_t secondsCount = 0; inProgress && secondsCount < timeout;
48 ++secondsCount)
49 {
50 bus.wait(std::chrono::seconds(1));
51 bus.process_discard();
52 }
53
54 if (inProgress)
55 {
56 lg2::error("Dump progress timeout; dump may not be complete.");
57 }
58}
59
60void requestSBEDump(const uint32_t failingUnit, const uint32_t eid,
61 SBETypes sbeType)
62{
Dhruvaraj Subhashchandrane74e9162024-04-01 09:53:13 -050063 lg2::info(
64 "Requesting Dump PEL({EID}) chip({CHIPTYPE}) position({FAILINGUNIT})",
65 "EID", eid, "CHIPTYPE", sbeTypeAttributes.at(sbeType).chipName,
66 "FAILINGUNIT", failingUnit);
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050067
Dhruvaraj Subhashchandrand48f8e32024-06-01 11:16:26 -050068 constexpr auto path = "/xyz/openbmc_project/dump/system";
69 auto dumpRequestType = sbeTypeAttributes.at(sbeType).dumpType;
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050070 constexpr auto interface = "xyz.openbmc_project.Dump.Create";
71 constexpr auto function = "CreateDump";
72
73 try
74 {
75 auto bus = sdbusplus::bus::new_default();
76 auto service = getService(bus, interface, path);
Patrick Williams540521e2024-08-16 15:20:03 -040077 auto method =
78 bus.new_method_call(service.c_str(), path, interface, function);
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050079
80 std::unordered_map<std::string, std::variant<std::string, uint64_t>>
81 createParams = {
Dhruvaraj Subhashchandrand48f8e32024-06-01 11:16:26 -050082 {"com.ibm.Dump.Create.CreateParameters.DumpType",
83 dumpRequestType},
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050084 {"com.ibm.Dump.Create.CreateParameters.ErrorLogId",
85 uint64_t(eid)},
86 {"com.ibm.Dump.Create.CreateParameters.FailingUnitId",
87 uint64_t(failingUnit)}};
88
89 method.append(createParams);
90 sdbusplus::message::object_path reply;
91 bus.call(method).read(reply);
92
93 monitorDumpCreation(reply.str, SBE_DUMP_TIMEOUT);
94 }
Patrick Williams9ae780d2024-04-26 02:34:31 -050095 catch (const sdbusplus::exception_t& e)
Dhruvaraj Subhashchandran5f5c94d2021-10-19 07:18:30 -050096 {
97 lg2::error("D-Bus call createDump exception OBJPATH={OBJPATH}, "
98 "INTERFACE={INTERFACE}, EXCEPTION={ERROR}",
99 "OBJPATH", path, "INTERFACE", interface, "ERROR", e);
100 constexpr auto ERROR_DUMP_DISABLED =
101 "xyz.openbmc_project.Dump.Create.Error.Disabled";
102 if (e.name() == ERROR_DUMP_DISABLED)
103 {
104 // Dump is disabled, Skip the dump collection.
105 lg2::info("Dump is disabled unit({FAILINGUNIT}), "
106 "skipping dump collection",
107 "FAILINGUNIT", failingUnit);
108 }
109 else
110 {
111 throw;
112 }
113 }
114 catch (const std::exception& e)
115 {
116 throw e;
117 }
118}
119
Patrick Williams9ae780d2024-04-26 02:34:31 -0500120std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
Dhruvaraj Subhashchandran858d1aa2021-10-27 03:26:06 -0500121 const std::string& path)
122{
123 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
124 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
125 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
126 try
127 {
128 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
129 MAPPER_INTERFACE, "GetObject");
130
131 mapper.append(path, std::vector<std::string>({intf}));
132
133 auto mapperResponseMsg = bus.call(mapper);
134 std::map<std::string, std::vector<std::string>> mapperResponse;
135 mapperResponseMsg.read(mapperResponse);
136
137 if (mapperResponse.empty())
138 {
139 lg2::error(
140 "Empty mapper response for GetObject interface({INTERFACE}), "
141 "path({PATH})",
142 "INTERFACE", intf, "PATH", path);
143
144 throw std::runtime_error("Empty mapper response for GetObject");
145 }
146 return mapperResponse.begin()->first;
147 }
Patrick Williams9ae780d2024-04-26 02:34:31 -0500148 catch (const sdbusplus::exception_t& ex)
Dhruvaraj Subhashchandran858d1aa2021-10-27 03:26:06 -0500149 {
150 lg2::error(
151 "Mapper call failed for GetObject errorMsg({ERROR}), path({PATH}),"
152 "interface({INTERFACE})",
153 "ERROR", ex, "PATH", path, "INTERFACE", intf);
154
155 throw;
156 }
157}
158
159} // namespace openpower::dump::util