blob: 14d796da60e6208a7d51e2717567e1f64134edca [file] [log] [blame]
Brad Bishopf6783cd2020-10-27 19:25:09 -04001#include "create_pel.hpp"
2
Jayanth Othayothc4831812021-06-08 01:33:40 -05003#include "util.hpp"
4
Brad Bishopf6783cd2020-10-27 19:25:09 -04005#include <fcntl.h>
6#include <fmt/format.h>
7#include <libekb.H>
8#include <unistd.h>
9
Brad Bishop5e5d4452020-10-27 19:46:13 -040010#include <phosphor-logging/elog.hpp>
11#include <xyz/openbmc_project/Logging/Create/server.hpp>
12#include <xyz/openbmc_project/Logging/Entry/server.hpp>
13
Brad Bishopf6783cd2020-10-27 19:25:09 -040014#include <cerrno>
15#include <cstdio>
16#include <cstdlib>
17#include <cstring>
18#include <map>
Brad Bishopf6783cd2020-10-27 19:25:09 -040019#include <stdexcept>
20#include <string>
21#include <tuple>
22#include <vector>
Brad Bishopf6783cd2020-10-27 19:25:09 -040023
24namespace openpower
25{
26using namespace phosphor::logging;
27
Brad Bishopf6783cd2020-10-27 19:25:09 -040028namespace pel
29{
Andrew Geissler61febf02021-06-22 17:19:32 -050030
31constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
32constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create";
33
Brad Bishopf6783cd2020-10-27 19:25:09 -040034void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData)
35{
Brad Bishopf6783cd2020-10-27 19:25:09 -040036 std::map<std::string, std::string> additionalData;
37 auto bus = sdbusplus::bus::new_default();
38 additionalData.emplace("_PID", std::to_string(getpid()));
39 for (auto& data : ffdcData)
40 {
41 additionalData.emplace(data);
42 }
43
44 try
45 {
46 FFDCFile ffdcFile(calloutData);
47
48 std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
49 server::Create::FFDCFormat,
50 uint8_t, uint8_t, sdbusplus::message::unix_fd>>
51 pelCalloutInfo;
52
53 pelCalloutInfo.push_back(
54 std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
55 Create::FFDCFormat::JSON,
56 static_cast<uint8_t>(0xCA),
57 static_cast<uint8_t>(0x01), ffdcFile.getFileFD()));
58
59 static constexpr auto bootErrorMessage =
60 "org.open_power.PHAL.Error.Boot";
61 std::string service =
62 util::getService(bus, loggingObjectPath, loggingInterface);
63 auto method =
64 bus.new_method_call(service.c_str(), loggingObjectPath,
65 loggingInterface, "CreateWithFFDCFiles");
66 auto level =
67 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
68 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
69 Error);
70 method.append(bootErrorMessage, level, additionalData, pelCalloutInfo);
71 auto resp = bus.call(method);
72 }
Patrick Williams2246cca2021-09-02 09:32:52 -050073 catch (const sdbusplus::exception::exception& e)
Brad Bishopf6783cd2020-10-27 19:25:09 -040074 {
75 log<level::ERR>("D-Bus call exception",
76 entry("OBJPATH=%s", loggingObjectPath),
77 entry("INTERFACE=%s", loggingInterface),
78 entry("EXCEPTION=%s", e.what()));
79
80 throw std::runtime_error(
81 "Error in invoking D-Bus logging create interface");
82 }
83 catch (std::exception& e)
84 {
85 throw e;
86 }
87}
88
Jayanth Othayotha8d2f712021-09-20 07:02:51 -050089void createPEL(const std::string& event, const FFDCData& ffdcData)
Andrew Geissler61febf02021-06-22 17:19:32 -050090{
91 std::map<std::string, std::string> additionalData;
92 auto bus = sdbusplus::bus::new_default();
Jayanth Othayotha8d2f712021-09-20 07:02:51 -050093
Andrew Geissler61febf02021-06-22 17:19:32 -050094 additionalData.emplace("_PID", std::to_string(getpid()));
Jayanth Othayotha8d2f712021-09-20 07:02:51 -050095 for (auto& data : ffdcData)
96 {
97 additionalData.emplace(data);
98 }
Andrew Geissler61febf02021-06-22 17:19:32 -050099
100 try
101 {
Andrew Geissler61febf02021-06-22 17:19:32 -0500102 std::string service =
103 util::getService(bus, loggingObjectPath, loggingInterface);
104 auto method = bus.new_method_call(service.c_str(), loggingObjectPath,
105 loggingInterface, "Create");
106 auto level =
107 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
108 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
109 Error);
Jayanth Othayothac95c562021-07-16 05:56:04 -0500110 method.append(event, level, additionalData);
Andrew Geissler61febf02021-06-22 17:19:32 -0500111 auto resp = bus.call(method);
112 }
Patrick Williams2246cca2021-09-02 09:32:52 -0500113 catch (const sdbusplus::exception::exception& e)
Andrew Geissler61febf02021-06-22 17:19:32 -0500114 {
Jayanth Othayothac95c562021-07-16 05:56:04 -0500115 log<level::ERR>(fmt::format("sdbusplus D-Bus call exception",
116 "OBJPATH={}, INTERFACE={}, EXCEPTION={}",
117 loggingObjectPath, loggingInterface,
118 e.what())
119 .c_str());
120 ;
Andrew Geissler61febf02021-06-22 17:19:32 -0500121
122 throw std::runtime_error(
123 "Error in invoking D-Bus logging create interface");
124 }
125 catch (std::exception& e)
126 {
Jayanth Othayothac95c562021-07-16 05:56:04 -0500127 log<level::ERR>(
128 fmt::format("D-bus call exception", "EXCEPTION={}", e.what())
129 .c_str());
Andrew Geissler61febf02021-06-22 17:19:32 -0500130 throw e;
131 }
132}
133
Brad Bishopf6783cd2020-10-27 19:25:09 -0400134FFDCFile::FFDCFile(const json& pHALCalloutData) :
135 calloutData(pHALCalloutData.dump()),
136 calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
137{
138 prepareFFDCFile();
139}
140
141FFDCFile::~FFDCFile()
142{
143 removeCalloutFile();
144}
145
146int FFDCFile::getFileFD() const
147{
148 return fileFD;
149}
150
151void FFDCFile::prepareFFDCFile()
152{
153 createCalloutFile();
154 writeCalloutData();
155 setCalloutFileSeekPos();
156}
157
158void FFDCFile::createCalloutFile()
159{
160 fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
161
162 if (fileFD == -1)
163 {
164 log<level::ERR>(fmt::format("Failed to create phalPELCallouts "
165 "file({}), errorno({}) and errormsg({})",
166 calloutFile, errno, strerror(errno))
167 .c_str());
168 throw std::runtime_error("Failed to create phalPELCallouts file");
169 }
170}
171
172void FFDCFile::writeCalloutData()
173{
174 ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
175
176 if (rc == -1)
177 {
178 log<level::ERR>(fmt::format("Failed to write phaPELCallout info "
179 "in file({}), errorno({}), errormsg({})",
180 calloutFile, errno, strerror(errno))
181 .c_str());
182 throw std::runtime_error("Failed to write phalPELCallouts info");
183 }
184 else if (rc != static_cast<ssize_t>(calloutData.size()))
185 {
186 log<level::WARNING>(fmt::format("Could not write all phal callout "
187 "info in file({}), written byte({}) "
188 "and total byte({})",
189 calloutFile, rc, calloutData.size())
190 .c_str());
191 }
192}
193
194void FFDCFile::setCalloutFileSeekPos()
195{
196 int rc = lseek(fileFD, 0, SEEK_SET);
197
198 if (rc == -1)
199 {
200 log<level::ERR>(fmt::format("Failed to set SEEK_SET for "
201 "phalPELCallouts in file({}), errorno({}) "
202 "and errormsg({})",
203 calloutFile, errno, strerror(errno))
204 .c_str());
205 throw std::runtime_error(
206 "Failed to set SEEK_SET for phalPELCallouts file");
207 }
208}
209
210void FFDCFile::removeCalloutFile()
211{
212 close(fileFD);
213 std::remove(calloutFile.c_str());
214}
215
216} // namespace pel
217} // namespace openpower