blob: 6c5322871c629a45c1ade465e7c1c97d3e832057 [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 }
73 catch (const sdbusplus::exception::SdBusError& e)
74 {
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 Othayothac95c562021-07-16 05:56:04 -050089void createPEL(const std::string& event)
Andrew Geissler61febf02021-06-22 17:19:32 -050090{
91 std::map<std::string, std::string> additionalData;
92 auto bus = sdbusplus::bus::new_default();
93 additionalData.emplace("_PID", std::to_string(getpid()));
94
95 try
96 {
Andrew Geissler61febf02021-06-22 17:19:32 -050097 std::string service =
98 util::getService(bus, loggingObjectPath, loggingInterface);
99 auto method = bus.new_method_call(service.c_str(), loggingObjectPath,
100 loggingInterface, "Create");
101 auto level =
102 sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
103 sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
104 Error);
Jayanth Othayothac95c562021-07-16 05:56:04 -0500105 method.append(event, level, additionalData);
Andrew Geissler61febf02021-06-22 17:19:32 -0500106 auto resp = bus.call(method);
107 }
108 catch (const sdbusplus::exception::SdBusError& e)
109 {
Jayanth Othayothac95c562021-07-16 05:56:04 -0500110 log<level::ERR>(fmt::format("sdbusplus D-Bus call exception",
111 "OBJPATH={}, INTERFACE={}, EXCEPTION={}",
112 loggingObjectPath, loggingInterface,
113 e.what())
114 .c_str());
115 ;
Andrew Geissler61febf02021-06-22 17:19:32 -0500116
117 throw std::runtime_error(
118 "Error in invoking D-Bus logging create interface");
119 }
120 catch (std::exception& e)
121 {
Jayanth Othayothac95c562021-07-16 05:56:04 -0500122 log<level::ERR>(
123 fmt::format("D-bus call exception", "EXCEPTION={}", e.what())
124 .c_str());
Andrew Geissler61febf02021-06-22 17:19:32 -0500125 throw e;
126 }
127}
128
Brad Bishopf6783cd2020-10-27 19:25:09 -0400129FFDCFile::FFDCFile(const json& pHALCalloutData) :
130 calloutData(pHALCalloutData.dump()),
131 calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
132{
133 prepareFFDCFile();
134}
135
136FFDCFile::~FFDCFile()
137{
138 removeCalloutFile();
139}
140
141int FFDCFile::getFileFD() const
142{
143 return fileFD;
144}
145
146void FFDCFile::prepareFFDCFile()
147{
148 createCalloutFile();
149 writeCalloutData();
150 setCalloutFileSeekPos();
151}
152
153void FFDCFile::createCalloutFile()
154{
155 fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
156
157 if (fileFD == -1)
158 {
159 log<level::ERR>(fmt::format("Failed to create phalPELCallouts "
160 "file({}), errorno({}) and errormsg({})",
161 calloutFile, errno, strerror(errno))
162 .c_str());
163 throw std::runtime_error("Failed to create phalPELCallouts file");
164 }
165}
166
167void FFDCFile::writeCalloutData()
168{
169 ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
170
171 if (rc == -1)
172 {
173 log<level::ERR>(fmt::format("Failed to write phaPELCallout info "
174 "in file({}), errorno({}), errormsg({})",
175 calloutFile, errno, strerror(errno))
176 .c_str());
177 throw std::runtime_error("Failed to write phalPELCallouts info");
178 }
179 else if (rc != static_cast<ssize_t>(calloutData.size()))
180 {
181 log<level::WARNING>(fmt::format("Could not write all phal callout "
182 "info in file({}), written byte({}) "
183 "and total byte({})",
184 calloutFile, rc, calloutData.size())
185 .c_str());
186 }
187}
188
189void FFDCFile::setCalloutFileSeekPos()
190{
191 int rc = lseek(fileFD, 0, SEEK_SET);
192
193 if (rc == -1)
194 {
195 log<level::ERR>(fmt::format("Failed to set SEEK_SET for "
196 "phalPELCallouts in file({}), errorno({}) "
197 "and errormsg({})",
198 calloutFile, errno, strerror(errno))
199 .c_str());
200 throw std::runtime_error(
201 "Failed to set SEEK_SET for phalPELCallouts file");
202 }
203}
204
205void FFDCFile::removeCalloutFile()
206{
207 close(fileFD);
208 std::remove(calloutFile.c_str());
209}
210
211} // namespace pel
212} // namespace openpower