1 #include <phosphor-logging/log.hpp> 2 #include <sdbusplus/bus.hpp> 3 #include <sdbusplus/bus/match.hpp> 4 #include <watchdog_dbus.hpp> 5 #include <watchdog_handler.hpp> 6 #include <watchdog_logging.hpp> 7 8 namespace watchdog 9 { 10 namespace dump 11 { 12 13 using namespace phosphor::logging; 14 15 /** 16 * @brief Callback for dump request properties change signal monitor 17 * 18 * @param msg - dbus message from the dbus match infrastructure 19 * @param path - the object path we are monitoring 20 * @param inProgress - used to break out of our dbus wait loop 21 * @return Always non-zero indicating no error, no cascading callbacks 22 */ 23 uint dumpStatusChanged(sdbusplus::message::message& msg, std::string path, 24 bool& inProgress) 25 { 26 // reply (msg) will be a property change message 27 std::string interface; 28 std::map<std::string, std::variant<std::string, uint8_t>> property; 29 msg.read(interface, property); 30 31 // looking for property Status changes 32 std::string propertyType = "Status"; 33 auto dumpStatus = property.find(propertyType); 34 35 if (dumpStatus != property.end()) 36 { 37 const std::string* status = 38 std::get_if<std::string>(&(dumpStatus->second)); 39 40 if ((nullptr != status) && ("xyz.openbmc_project.Common.Progress." 41 "OperationStatus.InProgress" != *status)) 42 { 43 // dump is done, trace some info and change in progress flag 44 log<level::INFO>(path.c_str()); 45 log<level::INFO>((*status).c_str()); 46 inProgress = false; 47 } 48 } 49 50 return 1; // non-negative return code for successful callback 51 } 52 53 /** 54 * @brief Register a callback for dump progress status changes 55 * 56 * @param path - the object path of the dump to monitor 57 * @param timeout - timeout - timeout interval in seconds 58 */ 59 void monitorDump(const std::string& path, const uint32_t timeout) 60 { 61 bool inProgress = true; // callback will update this 62 63 // setup the signal match rules and callback 64 std::string matchInterface = "xyz.openbmc_project.Common.Progress"; 65 auto bus = sdbusplus::bus::new_system(); 66 67 std::unique_ptr<sdbusplus::bus::match_t> match = 68 std::make_unique<sdbusplus::bus::match_t>( 69 bus, 70 sdbusplus::bus::match::rules::propertiesChanged( 71 path.c_str(), matchInterface.c_str()), 72 [&](auto& msg) { 73 return dumpStatusChanged(msg, path, inProgress); 74 }); 75 76 // wait for dump status to be completed (complete == true) 77 // or until timeout interval 78 log<level::INFO>("hbdump requested"); 79 bool timedOut = false; 80 uint32_t secondsCount = 0; 81 while ((true == inProgress) && !timedOut) 82 { 83 bus.wait(std::chrono::seconds(1)); 84 bus.process_discard(); 85 86 if (++secondsCount == timeout) 87 { 88 timedOut = true; 89 } 90 } 91 92 if (timedOut) 93 { 94 log<level::ERR>("hbdump dump progress status did not change to " 95 "complete within the timeout interval, exiting..."); 96 } 97 else 98 { 99 log<level::INFO>("hbdump completed"); 100 } 101 } 102 103 void requestDump(const uint32_t logId, const uint32_t timeout) 104 { 105 constexpr auto path = "/org/openpower/dump"; 106 constexpr auto interface = "xyz.openbmc_project.Dump.Create"; 107 constexpr auto function = "CreateDump"; 108 109 sdbusplus::message::message method; 110 111 if (0 == dbusMethod(path, interface, function, method)) 112 { 113 try 114 { 115 // dbus call arguments 116 std::map<std::string, std::variant<std::string, uint64_t>> 117 createParams; 118 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] = 119 "com.ibm.Dump.Create.DumpType.Hostboot"; 120 createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] = 121 uint64_t(logId); 122 method.append(createParams); 123 124 // using system dbus 125 auto bus = sdbusplus::bus::new_system(); 126 auto response = bus.call(method); 127 128 // reply will be type dbus::ObjectPath 129 sdbusplus::message::object_path reply; 130 response.read(reply); 131 132 // monitor dump progress 133 monitorDump(reply, timeout); 134 } 135 catch (const sdbusplus::exception::SdBusError& e) 136 { 137 log<level::ERR>("Error in requestDump", 138 entry("ERROR=%s", e.what())); 139 } 140 } 141 } 142 143 } // namespace dump 144 } // namespace watchdog 145