Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 1 | #include "create_pel.hpp"
|
| 2 |
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 3 | #include <fcntl.h>
|
| 4 | #include <fmt/format.h>
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 5 | #include <libekb.H>
|
| 6 | #include <unistd.h>
|
| 7 |
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 8 | #include <cerrno>
|
| 9 | #include <cstdio>
|
| 10 | #include <cstdlib>
|
| 11 | #include <cstring>
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 12 | #include <map>
|
| 13 | #include <phosphor-logging/elog.hpp>
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 14 | #include <stdexcept>
|
| 15 | #include <string>
|
| 16 | #include <tuple>
|
| 17 | #include <vector>
|
| 18 | #include <xyz/openbmc_project/Logging/Create/server.hpp>
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 19 | #include <xyz/openbmc_project/Logging/Entry/server.hpp>
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 20 |
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 21 | namespace openpower
|
| 22 | {
|
| 23 | using namespace phosphor::logging;
|
| 24 |
|
| 25 | namespace util
|
| 26 | {
|
| 27 | std::string getService(sdbusplus::bus::bus& bus, const std::string& objectPath,
|
| 28 | const std::string& interface)
|
| 29 | {
|
| 30 | constexpr auto mapperBusBame = "xyz.openbmc_project.ObjectMapper";
|
| 31 | constexpr auto mapperObjectPath = "/xyz/openbmc_project/object_mapper";
|
| 32 | constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";
|
| 33 | std::vector<std::pair<std::string, std::vector<std::string>>> response;
|
| 34 | auto method = bus.new_method_call(mapperBusBame, mapperObjectPath,
|
| 35 | mapperInterface, "GetObject");
|
| 36 | method.append(objectPath, std::vector<std::string>({interface}));
|
| 37 | try
|
| 38 | {
|
| 39 | auto reply = bus.call(method);
|
| 40 | reply.read(response);
|
| 41 | }
|
| 42 | catch (const sdbusplus::exception::SdBusError& e)
|
| 43 | {
|
| 44 | log<level::ERR>("D-Bus call exception",
|
| 45 | entry("OBJPATH=%s", mapperObjectPath),
|
| 46 | entry("INTERFACE=%s", mapperInterface),
|
| 47 | entry("EXCEPTION=%s", e.what()));
|
| 48 |
|
| 49 | throw std::runtime_error("Service name is not found");
|
| 50 | }
|
| 51 |
|
| 52 | if (response.empty())
|
| 53 | {
|
| 54 | throw std::runtime_error("Service name response is empty");
|
| 55 | }
|
| 56 | return response.begin()->first;
|
| 57 | }
|
| 58 | } // namespace util
|
| 59 |
|
| 60 | namespace pel
|
| 61 | {
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 62 | void createBootErrorPEL(const FFDCData& ffdcData, const json& calloutData)
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 63 | {
|
| 64 | constexpr auto loggingObjectPath = "/xyz/openbmc_project/logging";
|
| 65 | constexpr auto loggingInterface = "xyz.openbmc_project.Logging.Create";
|
| 66 |
|
| 67 | std::map<std::string, std::string> additionalData;
|
| 68 | auto bus = sdbusplus::bus::new_default();
|
| 69 | additionalData.emplace("_PID", std::to_string(getpid()));
|
| 70 | for (auto& data : ffdcData)
|
| 71 | {
|
| 72 | additionalData.emplace(data);
|
| 73 | }
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 74 |
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 75 | try
|
| 76 | {
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 77 | FFDCFile ffdcFile(calloutData);
|
| 78 |
|
| 79 | std::vector<std::tuple<sdbusplus::xyz::openbmc_project::Logging::
|
| 80 | server::Create::FFDCFormat,
|
| 81 | uint8_t, uint8_t, sdbusplus::message::unix_fd>>
|
| 82 | pelCalloutInfo;
|
| 83 |
|
| 84 | pelCalloutInfo.push_back(
|
| 85 | std::make_tuple(sdbusplus::xyz::openbmc_project::Logging::server::
|
| 86 | Create::FFDCFormat::JSON,
|
| 87 | static_cast<uint8_t>(0xCA),
|
| 88 | static_cast<uint8_t>(0x01), ffdcFile.getFileFD()));
|
| 89 |
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 90 | static constexpr auto bootErrorMessage =
|
| 91 | "org.open_power.PHAL.Error.Boot";
|
| 92 | std::string service =
|
| 93 | util::getService(bus, loggingObjectPath, loggingInterface);
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 94 | auto method =
|
| 95 | bus.new_method_call(service.c_str(), loggingObjectPath,
|
| 96 | loggingInterface, "CreateWithFFDCFiles");
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 97 | auto level =
|
| 98 | sdbusplus::xyz::openbmc_project::Logging::server::convertForMessage(
|
| 99 | sdbusplus::xyz::openbmc_project::Logging::server::Entry::Level::
|
| 100 | Error);
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 101 | method.append(bootErrorMessage, level, additionalData, pelCalloutInfo);
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 102 | auto resp = bus.call(method);
|
| 103 | }
|
| 104 | catch (const sdbusplus::exception::SdBusError& e)
|
| 105 | {
|
| 106 | log<level::ERR>("D-Bus call exception",
|
| 107 | entry("OBJPATH=%s", loggingObjectPath),
|
| 108 | entry("INTERFACE=%s", loggingInterface),
|
| 109 | entry("EXCEPTION=%s", e.what()));
|
| 110 |
|
| 111 | throw std::runtime_error(
|
| 112 | "Error in invoking D-Bus logging create interface");
|
| 113 | }
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 114 | catch (std::exception& e)
|
| 115 | {
|
| 116 | throw e;
|
| 117 | }
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 118 | }
|
Ramesh Iyyar | ef767ee | 2020-09-22 02:46:51 -0500 | [diff] [blame^] | 119 |
|
| 120 | FFDCFile::FFDCFile(const json& pHALCalloutData) :
|
| 121 | calloutData(pHALCalloutData.dump()),
|
| 122 | calloutFile("/tmp/phalPELCalloutsJson.XXXXXX"), fileFD(-1)
|
| 123 | {
|
| 124 | prepareFFDCFile();
|
| 125 | }
|
| 126 |
|
| 127 | FFDCFile::~FFDCFile()
|
| 128 | {
|
| 129 | removeCalloutFile();
|
| 130 | }
|
| 131 |
|
| 132 | int FFDCFile::getFileFD() const
|
| 133 | {
|
| 134 | return fileFD;
|
| 135 | }
|
| 136 |
|
| 137 | void FFDCFile::prepareFFDCFile()
|
| 138 | {
|
| 139 | createCalloutFile();
|
| 140 | writeCalloutData();
|
| 141 | setCalloutFileSeekPos();
|
| 142 | }
|
| 143 |
|
| 144 | void FFDCFile::createCalloutFile()
|
| 145 | {
|
| 146 | fileFD = mkostemp(const_cast<char*>(calloutFile.c_str()), O_RDWR);
|
| 147 |
|
| 148 | if (fileFD == -1)
|
| 149 | {
|
| 150 | log<level::ERR>(fmt::format("Failed to create phalPELCallouts "
|
| 151 | "file({}), errorno({}) and errormsg({})",
|
| 152 | calloutFile, errno, strerror(errno))
|
| 153 | .c_str());
|
| 154 | throw std::runtime_error("Failed to create phalPELCallouts file");
|
| 155 | }
|
| 156 | }
|
| 157 |
|
| 158 | void FFDCFile::writeCalloutData()
|
| 159 | {
|
| 160 | ssize_t rc = write(fileFD, calloutData.c_str(), calloutData.size());
|
| 161 |
|
| 162 | if (rc == -1)
|
| 163 | {
|
| 164 | log<level::ERR>(fmt::format("Failed to write phaPELCallout info "
|
| 165 | "in file({}), errorno({}), errormsg({})",
|
| 166 | calloutFile, errno, strerror(errno))
|
| 167 | .c_str());
|
| 168 | throw std::runtime_error("Failed to write phalPELCallouts info");
|
| 169 | }
|
| 170 | else if (rc != static_cast<ssize_t>(calloutData.size()))
|
| 171 | {
|
| 172 | log<level::WARNING>(fmt::format("Could not write all phal callout "
|
| 173 | "info in file({}), written byte({}) "
|
| 174 | "and total byte({})",
|
| 175 | calloutFile, rc, calloutData.size())
|
| 176 | .c_str());
|
| 177 | }
|
| 178 | }
|
| 179 |
|
| 180 | void FFDCFile::setCalloutFileSeekPos()
|
| 181 | {
|
| 182 | int rc = lseek(fileFD, 0, SEEK_SET);
|
| 183 |
|
| 184 | if (rc == -1)
|
| 185 | {
|
| 186 | log<level::ERR>(fmt::format("Failed to set SEEK_SET for "
|
| 187 | "phalPELCallouts in file({}), errorno({}) "
|
| 188 | "and errormsg({})",
|
| 189 | calloutFile, errno, strerror(errno))
|
| 190 | .c_str());
|
| 191 | throw std::runtime_error(
|
| 192 | "Failed to set SEEK_SET for phalPELCallouts file");
|
| 193 | }
|
| 194 | }
|
| 195 |
|
| 196 | void FFDCFile::removeCalloutFile()
|
| 197 | {
|
| 198 | close(fileFD);
|
| 199 | std::remove(calloutFile.c_str());
|
| 200 | }
|
| 201 |
|
Marri Devender Rao | 7847960 | 2020-01-06 03:45:11 -0600 | [diff] [blame] | 202 | } // namespace pel
|
| 203 | } // namespace openpower
|