blob: 89e1842b48f6d6b1c0dd6a2aabbd61edbf92fbf7 [file] [log] [blame]
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -05001#include "create_pel.hpp"
2
3#include "dump_utils.hpp"
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -05004#include "sbe_consts.hpp"
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -05005
6#include <fcntl.h>
7#include <libekb.H>
8#include <unistd.h>
9
10#include <phosphor-logging/elog.hpp>
11#include <phosphor-logging/lg2.hpp>
12#include <xyz/openbmc_project/Logging/Create/server.hpp>
13#include <xyz/openbmc_project/Logging/Entry/server.hpp>
14
15#include <cerrno>
16#include <cstdio>
17#include <cstdlib>
18#include <cstring>
19#include <format>
20#include <map>
21#include <stdexcept>
22#include <string>
23#include <tuple>
24#include <vector>
25
26namespace openpower::dump::pel
27{
28
29using namespace phosphor::logging;
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -050030using namespace openpower::dump::SBE;
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050031constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
32constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create";
33constexpr auto opLoggingInterface = "org.open_power.Logging.PEL";
34
35uint32_t createSbeErrorPEL(const std::string& event, const sbeError_t& sbeError,
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -050036 const FFDCData& ffdcData, const Severity severity,
37 const std::optional<PELFFDCInfo>& pelFFDCInfoOpt)
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050038{
39 uint32_t plid = 0;
40 std::unordered_map<std::string, std::string> additionalData = {
41 {"_PID", std::to_string(getpid())}, {"SBE_ERR_MSG", sbeError.what()}};
42 auto bus = sdbusplus::bus::new_default();
43
44 additionalData.emplace("_PID", std::to_string(getpid()));
45 additionalData.emplace("SBE_ERR_MSG", sbeError.what());
46
47 for (auto& data : ffdcData)
48 {
49 additionalData.emplace(data);
50 }
51
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -050052 PELFFDCInfo pelFFDCInfo;
53 if (pelFFDCInfoOpt)
54 {
55 pelFFDCInfo = *pelFFDCInfoOpt;
56 }
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050057
58 // Negative fd value indicates error case or invalid file
59 // No need of special processing , just log error with additional ffdc.
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -050060 else if (sbeError.getFd() > 0)
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050061 {
62 // Refer phosphor-logging/extensions/openpower-pels/README.md section
63 // "Self Boot Engine(SBE) First Failure Data Capture(FFDC) Support"
64 // for details of related to createPEL with SBE FFDC information
65 // usin g CreateWithFFDCFiles api.
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -050066 pelFFDCInfo.emplace_back(std::make_tuple(
67 sdbusplus::xyz::openbmc_project::Logging::server::Create::
68 FFDCFormat::Custom,
69 FFDC_FORMAT_SUBTYPE, FFDC_FORMAT_VERSION, sbeError.getFd()));
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050070 }
71 try
72 {
73 auto service = util::getService(bus, opLoggingInterface,
74 loggingObjectPath);
75 auto method = bus.new_method_call(service.c_str(), loggingObjectPath,
76 opLoggingInterface,
77 "CreatePELWithFFDCFiles");
78 auto level =
79 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
Dhruvaraj Subhashchandranf9f65b82022-10-13 06:46:43 -050080 severity);
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050081 method.append(event, level, additionalData, pelFFDCInfo);
82 auto response = bus.call(method);
83
84 // reply will be tuple containing bmc log id, platform log id
85 std::tuple<uint32_t, uint32_t> reply = {0, 0};
86
87 // parse dbus response into reply
88 response.read(reply);
89 plid = std::get<1>(reply); // platform log id is tuple "second"
90 }
Patrick Williams9ae780d2024-04-26 02:34:31 -050091 catch (const sdbusplus::exception_t& e)
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -050092 {
93 lg2::error(
94 "D-Bus call exception OBJPATH={OBJPATH}, INTERFACE={INTERFACE}, "
95 "EXCEPTION={ERROR}",
96 "OBJPATH", loggingObjectPath, "INTERFACE", loggingInterface,
97 "ERROR", e);
98
99 throw;
100 }
101 catch (const std::exception& e)
102 {
103 throw;
104 }
105
106 return plid;
107}
108
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -0500109openpower::dump::pel::Severity convertSeverityToEnum(uint8_t severity)
110{
111 switch (severity)
112 {
113 case openpower::phal::FAPI2_ERRL_SEV_RECOVERED:
114 return openpower::dump::pel::Severity::Informational;
115 case openpower::phal::FAPI2_ERRL_SEV_PREDICTIVE:
116 return openpower::dump::pel::Severity::Warning;
117 case openpower::phal::FAPI2_ERRL_SEV_UNRECOVERABLE:
118 return openpower::dump::pel::Severity::Error;
119 default:
120 return openpower::dump::pel::Severity::Error;
121 }
122}
123
124void processFFDCPackets(const openpower::phal::sbeError_t& sbeError,
125 const std::string& event,
126 openpower::dump::pel::FFDCData& pelAdditionalData)
127{
128 const auto& ffdcFileList = sbeError.getFfdcFileList();
129 for (const auto& [slid, ffdcTuple] : ffdcFileList)
130 {
131 uint8_t severity;
132 int fd;
133 std::filesystem::path path;
134 std::tie(severity, fd, path) = ffdcTuple;
135
136 Severity logSeverity = convertSeverityToEnum(severity);
137
Dhruvaraj Subhashchandranef646042024-05-03 09:25:03 -0500138 if (logSeverity != openpower::dump::pel::Severity::Informational)
139 {
140 lg2::info(
141 "Changing severity from {SEV_ORIG} to informational in the "
142 "dumping path",
143 "SEV_ORIG", logSeverity);
144 logSeverity = openpower::dump::pel::Severity::Informational;
145 }
146
Dhruvaraj Subhashchandranf2298892024-04-21 04:42:55 -0500147 PELFFDCInfo pelFFDCInfo;
148 pelFFDCInfo.emplace_back(
149 std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
150 Create::FFDCFormat::Custom,
151 FFDC_FORMAT_SUBTYPE, FFDC_FORMAT_VERSION, fd));
152
153 auto logId = openpower::dump::pel::createSbeErrorPEL(
154 event, sbeError, pelAdditionalData, logSeverity);
155 lg2::info("Logged PEL {PELID} for SLID {SLID}", "PELID", logId, "SLID",
156 slid);
157 }
158}
159
Dhruvaraj Subhashchandran6feeebd2021-10-19 05:03:59 -0500160FFDCFile::FFDCFile(const json& pHALCalloutData) :
161 calloutData(pHALCalloutData.dump()),
162 calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
163{
164 prepareFFDCFile();
165}
166
167FFDCFile::~FFDCFile()
168{
169 removeCalloutFile();
170}
171
172int FFDCFile::getFileFD() const
173{
174 return fileFD;
175}
176
177void FFDCFile::prepareFFDCFile()
178{
179 createCalloutFile();
180 writeCalloutData();
181 setCalloutFileSeekPos();
182}
183
184void FFDCFile::createCalloutFile()
185{
186 fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
187
188 if (fileFD == -1)
189 {
190 lg2::error("Failed to create phalPELCallouts file({FILE}), "
191 "errorno({ERRNO}) and errormsg({ERRORMSG})",
192 "FILE", calloutFile, "ERRNO", errno, "ERRORMSG",
193 strerror(errno));
194 throw std::runtime_error("Failed to create phalPELCallouts file");
195 }
196}
197
198void FFDCFile::writeCalloutData()
199{
200 ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
201
202 if (rc == -1)
203 {
204 lg2::error("Failed to write phaPELCallout info in file({FILE}), "
205 "errorno({ERRNO}), errormsg({ERRORMSG})",
206 "FILE", calloutFile, "ERRNO", errno, "ERRORMSG",
207 strerror(errno));
208 throw std::runtime_error("Failed to write phalPELCallouts info");
209 }
210 else if (rc != static_cast<ssize_t>(calloutData.size()))
211 {
212 lg2::warning("Could not write all phal callout info in file({FILE}), "
213 "written byte({WRITTEN}), total byte({TOTAL})",
214 "FILE", calloutFile, "WRITTEN", rc, "TOTAL",
215 calloutData.size());
216 }
217}
218
219void FFDCFile::setCalloutFileSeekPos()
220{
221 int rc = lseek(fileFD, 0, SEEK_SET);
222
223 if (rc == -1)
224 {
225 lg2::error("Failed to set SEEK_SET for phalPELCallouts in "
226 "file({FILE}), errorno({ERRNO}), errormsg({ERRORMSG})",
227 "FILE", calloutFile, "ERRNO", errno, "ERRORMSG",
228 strerror(errno));
229
230 throw std::runtime_error(
231 "Failed to set SEEK_SET for phalPELCallouts file");
232 }
233}
234
235void FFDCFile::removeCalloutFile()
236{
237 close(fileFD);
238 std::remove(calloutFile.c_str());
239}
240
241} // namespace openpower::dump::pel