1*5235dba5SDhruvaraj Subhashchandran #include "config.h"
2*5235dba5SDhruvaraj 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 
109*5235dba5SDhruvaraj 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);
12000dd33efSPatrick Williams         auto method = bus.new_method_call(service.c_str(), path, interface,
12100dd33efSPatrick Williams                                           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