15235dba5SDhruvaraj Subhashchandran #include "config.h"
25235dba5SDhruvaraj Subhashchandran
321a889fdSJayanth Othayoth #include "dump_utils.hpp"
421a889fdSJayanth Othayoth
521a889fdSJayanth Othayoth #include "util.hpp"
621a889fdSJayanth Othayoth
721a889fdSJayanth Othayoth #include <phosphor-logging/log.hpp>
821a889fdSJayanth Othayoth #include <sdbusplus/bus.hpp>
921a889fdSJayanth Othayoth #include <sdbusplus/exception.hpp>
1021a889fdSJayanth Othayoth #include <sdbusplus/server.hpp>
1121a889fdSJayanth Othayoth
12e0dd7af4SJayanth Othayoth #include <format>
13e0dd7af4SJayanth Othayoth
1421a889fdSJayanth Othayoth namespace openpower::phal::dump
1521a889fdSJayanth Othayoth {
1621a889fdSJayanth Othayoth
1721a889fdSJayanth Othayoth using namespace phosphor::logging;
1821a889fdSJayanth Othayoth
1921a889fdSJayanth Othayoth /**
2021a889fdSJayanth Othayoth * Callback for dump request properties change signal monitor
2121a889fdSJayanth Othayoth *
2221a889fdSJayanth Othayoth * @param[in] msg Dbus message from the dbus match infrastructure
2321a889fdSJayanth Othayoth * @param[in] path The object path we are monitoring
2421a889fdSJayanth Othayoth * @param[out] inProgress Used to break out of our dbus wait loop
2521a889fdSJayanth Othayoth * @reutn Always non-zero indicating no error, no cascading callbacks
2621a889fdSJayanth Othayoth */
dumpStatusChanged(sdbusplus::message_t & msg,const std::string & path,bool & inProgress)27aaea6867SPatrick Williams uint32_t dumpStatusChanged(sdbusplus::message_t& msg, const std::string& path,
28aaea6867SPatrick Williams bool& inProgress)
2921a889fdSJayanth Othayoth {
3021a889fdSJayanth Othayoth // reply (msg) will be a property change message
3121a889fdSJayanth Othayoth std::string interface;
3221a889fdSJayanth Othayoth std::map<std::string, std::variant<std::string, uint8_t>> property;
3321a889fdSJayanth Othayoth msg.read(interface, property);
3421a889fdSJayanth Othayoth
3521a889fdSJayanth Othayoth // looking for property Status changes
3621a889fdSJayanth Othayoth std::string propertyType = "Status";
3721a889fdSJayanth Othayoth auto dumpStatus = property.find(propertyType);
3821a889fdSJayanth Othayoth
3921a889fdSJayanth Othayoth if (dumpStatus != property.end())
4021a889fdSJayanth Othayoth {
4121a889fdSJayanth Othayoth const std::string* status =
4221a889fdSJayanth Othayoth std::get_if<std::string>(&(dumpStatus->second));
4321a889fdSJayanth Othayoth
4421a889fdSJayanth Othayoth if ((nullptr != status) && ("xyz.openbmc_project.Common.Progress."
4521a889fdSJayanth Othayoth "OperationStatus.InProgress" != *status))
4621a889fdSJayanth Othayoth {
4721a889fdSJayanth Othayoth // dump is done, trace some info and change in progress flag
48e0dd7af4SJayanth Othayoth log<level::INFO>(std::format("Dump status({}) : path={}",
4921a889fdSJayanth Othayoth status->c_str(), path.c_str())
5021a889fdSJayanth Othayoth .c_str());
5121a889fdSJayanth Othayoth inProgress = false;
5221a889fdSJayanth Othayoth }
5321a889fdSJayanth Othayoth }
5421a889fdSJayanth Othayoth
5521a889fdSJayanth Othayoth return 1; // non-negative return code for successful callback
5621a889fdSJayanth Othayoth }
5721a889fdSJayanth Othayoth
5821a889fdSJayanth Othayoth /**
5921a889fdSJayanth Othayoth * Register a callback for dump progress status changes
6021a889fdSJayanth Othayoth *
6121a889fdSJayanth Othayoth * @param[in] path The object path of the dump to monitor
6221a889fdSJayanth Othayoth * @param timeout - timeout - timeout interval in seconds
6321a889fdSJayanth Othayoth */
monitorDump(const std::string & path,const uint32_t timeout)6421a889fdSJayanth Othayoth void monitorDump(const std::string& path, const uint32_t timeout)
6521a889fdSJayanth Othayoth {
6621a889fdSJayanth Othayoth bool inProgress = true; // callback will update this
6721a889fdSJayanth Othayoth
6821a889fdSJayanth Othayoth // setup the signal match rules and callback
6921a889fdSJayanth Othayoth std::string matchInterface = "xyz.openbmc_project.Common.Progress";
7021a889fdSJayanth Othayoth auto bus = sdbusplus::bus::new_system();
7121a889fdSJayanth Othayoth
7221a889fdSJayanth Othayoth std::unique_ptr<sdbusplus::bus::match_t> match =
7321a889fdSJayanth Othayoth std::make_unique<sdbusplus::bus::match_t>(
7421a889fdSJayanth Othayoth bus,
7521a889fdSJayanth Othayoth sdbusplus::bus::match::rules::propertiesChanged(
7621a889fdSJayanth Othayoth path.c_str(), matchInterface.c_str()),
7721a889fdSJayanth Othayoth [&](auto& msg) {
7821a889fdSJayanth Othayoth return dumpStatusChanged(msg, path, inProgress);
7921a889fdSJayanth Othayoth });
8021a889fdSJayanth Othayoth
8121a889fdSJayanth Othayoth // wait for dump status to be completed (complete == true)
8221a889fdSJayanth Othayoth // or until timeout interval
8321a889fdSJayanth Othayoth log<level::INFO>("dump requested (waiting)");
8421a889fdSJayanth Othayoth bool timedOut = false;
8521a889fdSJayanth Othayoth uint32_t secondsCount = 0;
8621a889fdSJayanth Othayoth while ((true == inProgress) && !timedOut)
8721a889fdSJayanth Othayoth {
8821a889fdSJayanth Othayoth bus.wait(std::chrono::seconds(1));
8921a889fdSJayanth Othayoth bus.process_discard();
9021a889fdSJayanth Othayoth
9121a889fdSJayanth Othayoth if (++secondsCount == timeout)
9221a889fdSJayanth Othayoth {
9321a889fdSJayanth Othayoth timedOut = true;
9421a889fdSJayanth Othayoth }
9521a889fdSJayanth Othayoth }
9621a889fdSJayanth Othayoth if (timedOut)
9721a889fdSJayanth Othayoth {
9821a889fdSJayanth Othayoth log<level::ERR>("Dump progress status did not change to "
9921a889fdSJayanth Othayoth "complete within the timeout interval, exiting...");
10021a889fdSJayanth Othayoth }
10121a889fdSJayanth Othayoth }
10221a889fdSJayanth Othayoth
requestDump(const DumpParameters & dumpParameters)10321a889fdSJayanth Othayoth void requestDump(const DumpParameters& dumpParameters)
10421a889fdSJayanth Othayoth {
105e0dd7af4SJayanth Othayoth log<level::INFO>(std::format("Requesting Dump PEL({}) Index({})",
10621a889fdSJayanth Othayoth dumpParameters.logId, dumpParameters.unitId)
10721a889fdSJayanth Othayoth .c_str());
10821a889fdSJayanth Othayoth
1095235dba5SDhruvaraj Subhashchandran constexpr auto path = OP_DUMP_OBJ_PATH;
11021a889fdSJayanth Othayoth constexpr auto interface = "xyz.openbmc_project.Dump.Create";
11121a889fdSJayanth Othayoth constexpr auto function = "CreateDump";
11221a889fdSJayanth Othayoth
113aaea6867SPatrick Williams sdbusplus::message_t method;
11421a889fdSJayanth Othayoth
11521a889fdSJayanth Othayoth auto bus = sdbusplus::bus::new_default();
11621a889fdSJayanth Othayoth
11721a889fdSJayanth Othayoth try
11821a889fdSJayanth Othayoth {
11921a889fdSJayanth Othayoth std::string service = util::getService(bus, path, interface);
120*1e43be06SPatrick Williams auto method =
121*1e43be06SPatrick Williams bus.new_method_call(service.c_str(), path, interface, function);
12221a889fdSJayanth Othayoth
12321a889fdSJayanth Othayoth // dbus call arguments
12421a889fdSJayanth Othayoth std::map<std::string, std::variant<std::string, uint64_t>> createParams;
12521a889fdSJayanth Othayoth createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
12621a889fdSJayanth Othayoth uint64_t(dumpParameters.logId);
12721a889fdSJayanth Othayoth if (DumpType::SBE == dumpParameters.dumpType)
12821a889fdSJayanth Othayoth {
12921a889fdSJayanth Othayoth createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
13021a889fdSJayanth Othayoth "com.ibm.Dump.Create.DumpType.SBE";
13121a889fdSJayanth Othayoth createParams["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
13221a889fdSJayanth Othayoth dumpParameters.unitId;
13321a889fdSJayanth Othayoth }
13421a889fdSJayanth Othayoth method.append(createParams);
13521a889fdSJayanth Othayoth
13621a889fdSJayanth Othayoth auto response = bus.call(method);
13721a889fdSJayanth Othayoth
13821a889fdSJayanth Othayoth // reply will be type dbus::ObjectPath
13921a889fdSJayanth Othayoth sdbusplus::message::object_path reply;
14021a889fdSJayanth Othayoth response.read(reply);
14121a889fdSJayanth Othayoth
14221a889fdSJayanth Othayoth // monitor dump progress
14321a889fdSJayanth Othayoth monitorDump(reply, dumpParameters.timeout);
14421a889fdSJayanth Othayoth }
145aaea6867SPatrick Williams catch (const sdbusplus::exception_t& e)
14621a889fdSJayanth Othayoth {
147e0dd7af4SJayanth Othayoth log<level::ERR>(std::format("D-Bus call createDump exception",
14821a889fdSJayanth Othayoth "OBJPATH={}, INTERFACE={}, EXCEPTION={}",
14921a889fdSJayanth Othayoth path, interface, e.what())
15021a889fdSJayanth Othayoth .c_str());
15121a889fdSJayanth Othayoth constexpr auto ERROR_DUMP_DISABLED =
15221a889fdSJayanth Othayoth "xyz.openbmc_project.Dump.Create.Error.Disabled";
15321a889fdSJayanth Othayoth if (e.name() == ERROR_DUMP_DISABLED)
15421a889fdSJayanth Othayoth {
15521a889fdSJayanth Othayoth // Dump is disabled, Skip the dump collection.
15621a889fdSJayanth Othayoth log<level::INFO>(
157e0dd7af4SJayanth Othayoth std::format("Dump is disabled on({}), skipping dump collection",
15821a889fdSJayanth Othayoth dumpParameters.unitId)
15921a889fdSJayanth Othayoth .c_str());
16021a889fdSJayanth Othayoth }
16121a889fdSJayanth Othayoth else
16221a889fdSJayanth Othayoth {
16321a889fdSJayanth Othayoth throw std::runtime_error(
16421a889fdSJayanth Othayoth "Error in invoking D-Bus createDump interface");
16521a889fdSJayanth Othayoth }
16621a889fdSJayanth Othayoth }
16721a889fdSJayanth Othayoth catch (const std::exception& e)
16821a889fdSJayanth Othayoth {
16921a889fdSJayanth Othayoth throw e;
17021a889fdSJayanth Othayoth }
17121a889fdSJayanth Othayoth }
17221a889fdSJayanth Othayoth
17321a889fdSJayanth Othayoth } // namespace openpower::phal::dump
174