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