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