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