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