blob: 74ec563f4c62b1eaa0dd42ed58af8e5dc58fd8aa [file] [log] [blame]
#include "dump_utils.hpp"
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/lg2.hpp>
#include <phosphor-logging/log.hpp>
#include <xyz/openbmc_project/Common/File/error.hpp>
#include <format>
#include <fstream>
#include <string>
namespace openpower::dump::util
{
using namespace phosphor::logging;
static void monitorDumpCreation(const std::string& path, const uint32_t timeout)
{
bool inProgress = true;
auto bus = sdbusplus::bus::new_system();
auto match = sdbusplus::bus::match_t(
bus,
sdbusplus::bus::match::rules::propertiesChanged(
path, "xyz.openbmc_project.Common.Progress"),
[&](sdbusplus::message_t& msg) {
std::string interface;
std::map<std::string, std::variant<std::string, uint8_t>> property;
msg.read(interface, property);
const auto dumpStatus = property.find("Status");
if (dumpStatus != property.end())
{
const std::string* status =
std::get_if<std::string>(&(dumpStatus->second));
if (status &&
*status !=
"xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
{
lg2::info("Dump status({STATUS}) : path={PATH}", "STATUS",
status->c_str(), "PATH", path.c_str());
inProgress = false;
}
}
});
// Timeout management
for (uint32_t secondsCount = 0; inProgress && secondsCount < timeout;
++secondsCount)
{
bus.wait(std::chrono::seconds(1));
bus.process_discard();
}
if (inProgress)
{
lg2::error("Dump progress timeout; dump may not be complete.");
}
}
void requestSBEDump(const uint32_t failingUnit, const uint32_t eid,
SBETypes sbeType)
{
lg2::info(
"Requesting Dump PEL({EID}) chip({CHIPTYPE}) position({FAILINGUNIT})",
"EID", eid, "CHIPTYPE", sbeTypeAttributes.at(sbeType).chipName,
"FAILINGUNIT", failingUnit);
constexpr auto path = "/xyz/openbmc_project/dump/system";
auto dumpRequestType = sbeTypeAttributes.at(sbeType).dumpType;
constexpr auto interface = "xyz.openbmc_project.Dump.Create";
constexpr auto function = "CreateDump";
try
{
auto bus = sdbusplus::bus::new_default();
auto service = getService(bus, interface, path);
auto method =
bus.new_method_call(service.c_str(), path, interface, function);
std::unordered_map<std::string, std::variant<std::string, uint64_t>>
createParams = {
{"com.ibm.Dump.Create.CreateParameters.DumpType",
dumpRequestType},
{"com.ibm.Dump.Create.CreateParameters.ErrorLogId",
uint64_t(eid)},
{"com.ibm.Dump.Create.CreateParameters.FailingUnitId",
uint64_t(failingUnit)}};
method.append(createParams);
sdbusplus::message::object_path reply;
bus.call(method).read(reply);
monitorDumpCreation(reply.str, SBE_DUMP_TIMEOUT);
}
catch (const sdbusplus::exception_t& e)
{
lg2::error("D-Bus call createDump exception OBJPATH={OBJPATH}, "
"INTERFACE={INTERFACE}, EXCEPTION={ERROR}",
"OBJPATH", path, "INTERFACE", interface, "ERROR", e);
constexpr auto ERROR_DUMP_DISABLED =
"xyz.openbmc_project.Dump.Create.Error.Disabled";
if (e.name() == ERROR_DUMP_DISABLED)
{
// Dump is disabled, Skip the dump collection.
lg2::info("Dump is disabled unit({FAILINGUNIT}), "
"skipping dump collection",
"FAILINGUNIT", failingUnit);
}
else
{
throw;
}
}
catch (const std::exception& e)
{
throw e;
}
}
std::string getService(sdbusplus::bus_t& bus, const std::string& intf,
const std::string& path)
{
constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
try
{
auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
MAPPER_INTERFACE, "GetObject");
mapper.append(path, std::vector<std::string>({intf}));
auto mapperResponseMsg = bus.call(mapper);
std::map<std::string, std::vector<std::string>> mapperResponse;
mapperResponseMsg.read(mapperResponse);
if (mapperResponse.empty())
{
lg2::error(
"Empty mapper response for GetObject interface({INTERFACE}), "
"path({PATH})",
"INTERFACE", intf, "PATH", path);
throw std::runtime_error("Empty mapper response for GetObject");
}
return mapperResponse.begin()->first;
}
catch (const sdbusplus::exception_t& ex)
{
lg2::error(
"Mapper call failed for GetObject errorMsg({ERROR}), path({PATH}),"
"interface({INTERFACE})",
"ERROR", ex, "PATH", path, "INTERFACE", intf);
throw;
}
}
} // namespace openpower::dump::util