1ca9236c3SDhruvaraj Subhashchandran #include <phosphor-logging/lg2.hpp>
21ac6162dSShantappa Teekappanavar #include <sdbusplus/bus.hpp>
31ac6162dSShantappa Teekappanavar #include <sdbusplus/bus/match.hpp>
41ac6162dSShantappa Teekappanavar #include <watchdog_dbus.hpp>
51ac6162dSShantappa Teekappanavar #include <watchdog_handler.hpp>
61ac6162dSShantappa Teekappanavar #include <watchdog_logging.hpp>
71ac6162dSShantappa Teekappanavar
81ac6162dSShantappa Teekappanavar namespace watchdog
91ac6162dSShantappa Teekappanavar {
101ac6162dSShantappa Teekappanavar namespace dump
111ac6162dSShantappa Teekappanavar {
121ac6162dSShantappa Teekappanavar
131ac6162dSShantappa Teekappanavar /**
141ac6162dSShantappa Teekappanavar * @brief Callback for dump request properties change signal monitor
151ac6162dSShantappa Teekappanavar *
161ac6162dSShantappa Teekappanavar * @param msg - dbus message from the dbus match infrastructure
171ac6162dSShantappa Teekappanavar * @param path - the object path we are monitoring
1841d507e5SShantappa Teekappanavar * @param progressStatus - dump progress status
191ac6162dSShantappa Teekappanavar * @return Always non-zero indicating no error, no cascading callbacks
201ac6162dSShantappa Teekappanavar */
dumpStatusChanged(sdbusplus::message_t & msg,std::string path,DumpProgressStatus & progressStatus)21fc437560SPatrick Williams uint dumpStatusChanged(sdbusplus::message_t& msg, std::string path,
2241d507e5SShantappa Teekappanavar DumpProgressStatus& progressStatus)
231ac6162dSShantappa Teekappanavar {
241ac6162dSShantappa Teekappanavar // reply (msg) will be a property change message
251ac6162dSShantappa Teekappanavar std::string interface;
261ac6162dSShantappa Teekappanavar std::map<std::string, std::variant<std::string, uint8_t>> property;
271ac6162dSShantappa Teekappanavar msg.read(interface, property);
281ac6162dSShantappa Teekappanavar
291ac6162dSShantappa Teekappanavar // looking for property Status changes
301ac6162dSShantappa Teekappanavar std::string propertyType = "Status";
311ac6162dSShantappa Teekappanavar auto dumpStatus = property.find(propertyType);
321ac6162dSShantappa Teekappanavar
331ac6162dSShantappa Teekappanavar if (dumpStatus != property.end())
341ac6162dSShantappa Teekappanavar {
351ac6162dSShantappa Teekappanavar const std::string* status =
361ac6162dSShantappa Teekappanavar std::get_if<std::string>(&(dumpStatus->second));
371ac6162dSShantappa Teekappanavar
381ac6162dSShantappa Teekappanavar if ((nullptr != status) && ("xyz.openbmc_project.Common.Progress."
391ac6162dSShantappa Teekappanavar "OperationStatus.InProgress" != *status))
401ac6162dSShantappa Teekappanavar {
4141d507e5SShantappa Teekappanavar // dump is not in InProgress state, trace some info and change in
4241d507e5SShantappa Teekappanavar // progress status
43ca9236c3SDhruvaraj Subhashchandran lg2::info("{PATH}", "PATH", path);
44ca9236c3SDhruvaraj Subhashchandran lg2::info("{STATUS}", "STATUS", *status);
4541d507e5SShantappa Teekappanavar
4641d507e5SShantappa Teekappanavar if ("xyz.openbmc_project.Common.Progress.OperationStatus."
4741d507e5SShantappa Teekappanavar "Completed" == *status)
4841d507e5SShantappa Teekappanavar {
4941d507e5SShantappa Teekappanavar // Dump completed successfully
5041d507e5SShantappa Teekappanavar progressStatus = DumpProgressStatus::Completed;
5141d507e5SShantappa Teekappanavar }
5241d507e5SShantappa Teekappanavar else
5341d507e5SShantappa Teekappanavar {
5441d507e5SShantappa Teekappanavar // Dump Failed
5541d507e5SShantappa Teekappanavar progressStatus = DumpProgressStatus::Failed;
5641d507e5SShantappa Teekappanavar }
571ac6162dSShantappa Teekappanavar }
581ac6162dSShantappa Teekappanavar }
591ac6162dSShantappa Teekappanavar
601ac6162dSShantappa Teekappanavar return 1; // non-negative return code for successful callback
611ac6162dSShantappa Teekappanavar }
621ac6162dSShantappa Teekappanavar
631ac6162dSShantappa Teekappanavar /**
641ac6162dSShantappa Teekappanavar * @brief Register a callback for dump progress status changes
651ac6162dSShantappa Teekappanavar *
661ac6162dSShantappa Teekappanavar * @param path - the object path of the dump to monitor
671ac6162dSShantappa Teekappanavar * @param timeout - timeout - timeout interval in seconds
681ac6162dSShantappa Teekappanavar */
monitorDump(const std::string & path,const uint32_t timeout)691ac6162dSShantappa Teekappanavar void monitorDump(const std::string& path, const uint32_t timeout)
701ac6162dSShantappa Teekappanavar {
7141d507e5SShantappa Teekappanavar // callback will update progressStatus
7241d507e5SShantappa Teekappanavar DumpProgressStatus progressStatus = DumpProgressStatus::InProgress;
731ac6162dSShantappa Teekappanavar
741ac6162dSShantappa Teekappanavar // setup the signal match rules and callback
751ac6162dSShantappa Teekappanavar std::string matchInterface = "xyz.openbmc_project.Common.Progress";
761ac6162dSShantappa Teekappanavar auto bus = sdbusplus::bus::new_system();
771ac6162dSShantappa Teekappanavar
781ac6162dSShantappa Teekappanavar std::unique_ptr<sdbusplus::bus::match_t> match =
791ac6162dSShantappa Teekappanavar std::make_unique<sdbusplus::bus::match_t>(
801ac6162dSShantappa Teekappanavar bus,
811ac6162dSShantappa Teekappanavar sdbusplus::bus::match::rules::propertiesChanged(
821ac6162dSShantappa Teekappanavar path.c_str(), matchInterface.c_str()),
831ac6162dSShantappa Teekappanavar [&](auto& msg) {
8441d507e5SShantappa Teekappanavar return dumpStatusChanged(msg, path, progressStatus);
851ac6162dSShantappa Teekappanavar });
861ac6162dSShantappa Teekappanavar
871ac6162dSShantappa Teekappanavar // wait for dump status to be completed (complete == true)
881ac6162dSShantappa Teekappanavar // or until timeout interval
8941d507e5SShantappa Teekappanavar
901ac6162dSShantappa Teekappanavar bool timedOut = false;
911ac6162dSShantappa Teekappanavar uint32_t secondsCount = 0;
9241d507e5SShantappa Teekappanavar while ((DumpProgressStatus::InProgress == progressStatus) && !timedOut)
931ac6162dSShantappa Teekappanavar {
941ac6162dSShantappa Teekappanavar bus.wait(std::chrono::seconds(1));
951ac6162dSShantappa Teekappanavar bus.process_discard();
961ac6162dSShantappa Teekappanavar
971ac6162dSShantappa Teekappanavar if (++secondsCount == timeout)
981ac6162dSShantappa Teekappanavar {
991ac6162dSShantappa Teekappanavar timedOut = true;
1001ac6162dSShantappa Teekappanavar }
1011ac6162dSShantappa Teekappanavar }
1021ac6162dSShantappa Teekappanavar
1031ac6162dSShantappa Teekappanavar if (timedOut)
1041ac6162dSShantappa Teekappanavar {
105ca9236c3SDhruvaraj Subhashchandran lg2::error("Dump progress status did not change to "
1061ac6162dSShantappa Teekappanavar "complete within the timeout interval, exiting...");
1071ac6162dSShantappa Teekappanavar }
10841d507e5SShantappa Teekappanavar else if (DumpProgressStatus::Completed == progressStatus)
10941d507e5SShantappa Teekappanavar {
110ca9236c3SDhruvaraj Subhashchandran lg2::info("dump collection completed");
11141d507e5SShantappa Teekappanavar }
1121ac6162dSShantappa Teekappanavar else
1131ac6162dSShantappa Teekappanavar {
114ca9236c3SDhruvaraj Subhashchandran lg2::info("dump collection failed");
1151ac6162dSShantappa Teekappanavar }
1161ac6162dSShantappa Teekappanavar }
1171ac6162dSShantappa Teekappanavar
requestDump(const DumpParameters & dumpParameters)11841d507e5SShantappa Teekappanavar void requestDump(const DumpParameters& dumpParameters)
1191ac6162dSShantappa Teekappanavar {
120*d48f8e34SDhruvaraj Subhashchandran constexpr auto path = "/xyz/openbmc_project/dump/system";
1211ac6162dSShantappa Teekappanavar constexpr auto interface = "xyz.openbmc_project.Dump.Create";
1221ac6162dSShantappa Teekappanavar constexpr auto function = "CreateDump";
1231ac6162dSShantappa Teekappanavar
124fc437560SPatrick Williams sdbusplus::message_t method;
1251ac6162dSShantappa Teekappanavar
1261ac6162dSShantappa Teekappanavar if (0 == dbusMethod(path, interface, function, method))
1271ac6162dSShantappa Teekappanavar {
1281ac6162dSShantappa Teekappanavar try
1291ac6162dSShantappa Teekappanavar {
1301ac6162dSShantappa Teekappanavar // dbus call arguments
1311ac6162dSShantappa Teekappanavar std::map<std::string, std::variant<std::string, uint64_t>>
1321ac6162dSShantappa Teekappanavar createParams;
13341d507e5SShantappa Teekappanavar createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
13441d507e5SShantappa Teekappanavar uint64_t(dumpParameters.logId);
13541d507e5SShantappa Teekappanavar if (DumpType::Hostboot == dumpParameters.dumpType)
13641d507e5SShantappa Teekappanavar {
137ca9236c3SDhruvaraj Subhashchandran lg2::info("hostboot dump requested");
1381ac6162dSShantappa Teekappanavar createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
1391ac6162dSShantappa Teekappanavar "com.ibm.Dump.Create.DumpType.Hostboot";
14041d507e5SShantappa Teekappanavar }
14141d507e5SShantappa Teekappanavar else if (DumpType::SBE == dumpParameters.dumpType)
14241d507e5SShantappa Teekappanavar {
143ca9236c3SDhruvaraj Subhashchandran lg2::info("SBE dump requested");
14441d507e5SShantappa Teekappanavar createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
14541d507e5SShantappa Teekappanavar "com.ibm.Dump.Create.DumpType.SBE";
14641d507e5SShantappa Teekappanavar createParams
14741d507e5SShantappa Teekappanavar ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
14841d507e5SShantappa Teekappanavar dumpParameters.unitId;
14941d507e5SShantappa Teekappanavar }
15041d507e5SShantappa Teekappanavar
1511ac6162dSShantappa Teekappanavar method.append(createParams);
1521ac6162dSShantappa Teekappanavar
1531ac6162dSShantappa Teekappanavar // using system dbus
1541ac6162dSShantappa Teekappanavar auto bus = sdbusplus::bus::new_system();
1551ac6162dSShantappa Teekappanavar auto response = bus.call(method);
1561ac6162dSShantappa Teekappanavar
1571ac6162dSShantappa Teekappanavar // reply will be type dbus::ObjectPath
1581ac6162dSShantappa Teekappanavar sdbusplus::message::object_path reply;
1591ac6162dSShantappa Teekappanavar response.read(reply);
1601ac6162dSShantappa Teekappanavar
1611ac6162dSShantappa Teekappanavar // monitor dump progress
16241d507e5SShantappa Teekappanavar monitorDump(reply, dumpParameters.timeout);
1631ac6162dSShantappa Teekappanavar }
164fc437560SPatrick Williams catch (const sdbusplus::exception_t& e)
1651ac6162dSShantappa Teekappanavar {
16641d507e5SShantappa Teekappanavar constexpr auto ERROR_DUMP_DISABLED =
16741d507e5SShantappa Teekappanavar "xyz.openbmc_project.Dump.Create.Error.Disabled";
16841d507e5SShantappa Teekappanavar if (e.name() == ERROR_DUMP_DISABLED)
16941d507e5SShantappa Teekappanavar {
17041d507e5SShantappa Teekappanavar // Dump is disabled, Skip the dump collection.
171ca9236c3SDhruvaraj Subhashchandran lg2::info("Dump is disabled on({UNIT}), "
172ca9236c3SDhruvaraj Subhashchandran "skipping dump collection",
173ca9236c3SDhruvaraj Subhashchandran "UNIT", dumpParameters.unitId);
17441d507e5SShantappa Teekappanavar }
17541d507e5SShantappa Teekappanavar else
17641d507e5SShantappa Teekappanavar {
177ca9236c3SDhruvaraj Subhashchandran lg2::error("D-Bus call createDump exception OBJPATH={OBJPATH}, "
178ca9236c3SDhruvaraj Subhashchandran "INTERFACE={INTERFACE}, EXCEPTION={ERROR}",
179ca9236c3SDhruvaraj Subhashchandran "OBJPATH", path, "INTERFACE", interface, "ERROR", e);
18041d507e5SShantappa Teekappanavar }
1811ac6162dSShantappa Teekappanavar }
1821ac6162dSShantappa Teekappanavar }
1831ac6162dSShantappa Teekappanavar }
1841ac6162dSShantappa Teekappanavar
1851ac6162dSShantappa Teekappanavar } // namespace dump
1861ac6162dSShantappa Teekappanavar } // namespace watchdog
187