blob: 847eb8e3da004418876af66f05c10a2fc95e43cd [file] [log] [blame]
Ben Tyner7029e522021-08-09 19:18:24 -05001#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>
austinfcuibfa831a2022-01-26 15:37:07 -06006#include <util/trace.hpp>
Ben Tyner7029e522021-08-09 19:18:24 -05007
Ben Tynere38a90b2022-03-02 19:30:35 -06008constexpr uint64_t dumpTimeout = 3600000000; // microseconds
9
10constexpr auto operationStatusInProgress =
11 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress";
12
Ben Tyner7029e522021-08-09 19:18:24 -050013namespace attn
14{
15
16/**
17 * Callback for dump request properties change signal monitor
18 *
19 * @param[in] i_msg Dbus message from the dbus match infrastructure
Ben Tynere38a90b2022-03-02 19:30:35 -060020 * @param[out] o_dumpStatus Dump status dbus response string
21 * @return Always non-zero indicating no error, no cascading callbacks
Ben Tyner7029e522021-08-09 19:18:24 -050022 */
Patrick Williamse212fb02022-07-22 19:26:57 -050023uint dumpStatusChanged(sdbusplus::message_t& i_msg, std::string& o_dumpStatus)
Ben Tyner7029e522021-08-09 19:18:24 -050024{
25 // reply (msg) will be a property change message
26 std::string interface;
27 std::map<std::string, std::variant<std::string, uint8_t>> property;
28 i_msg.read(interface, property);
29
30 // looking for property Status changes
31 std::string propertyType = "Status";
Patrick Williams27dd6362023-05-10 07:51:20 -050032 auto dumpStatus = property.find(propertyType);
Ben Tyner7029e522021-08-09 19:18:24 -050033
34 if (dumpStatus != property.end())
35 {
36 const std::string* status =
37 std::get_if<std::string>(&(dumpStatus->second));
38
Ben Tynere38a90b2022-03-02 19:30:35 -060039 if (nullptr != status)
Ben Tyner7029e522021-08-09 19:18:24 -050040 {
Ben Tynere38a90b2022-03-02 19:30:35 -060041 o_dumpStatus = *status;
Ben Tyner7029e522021-08-09 19:18:24 -050042 }
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 */
53void monitorDump(const std::string& i_path)
54{
Ben Tyner7029e522021-08-09 19:18:24 -050055 // setup the signal match rules and callback
56 std::string matchInterface = "xyz.openbmc_project.Common.Progress";
Patrick Williams27dd6362023-05-10 07:51:20 -050057 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -050058
Ben Tynere38a90b2022-03-02 19:30:35 -060059 // monitor dump status change property, will update dumpStatus
60 std::string dumpStatus = "requested";
Ben Tyner7029e522021-08-09 19:18:24 -050061 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()),
Ben Tynere38a90b2022-03-02 19:30:35 -060066 [&](auto& msg) { return dumpStatusChanged(msg, dumpStatus); });
Ben Tyner7029e522021-08-09 19:18:24 -050067
68 // wait for dump status to be completed (complete == true)
Ben Tynere38a90b2022-03-02 19:30:35 -060069 trace::inf("dump requested %s", i_path.c_str());
70
71 // wait for dump status not InProgress or timeout
72 uint64_t timeRemaining = dumpTimeout;
73
74 std::chrono::steady_clock::time_point begin =
75 std::chrono::steady_clock::now();
76
77 while (("requested" == dumpStatus ||
78 operationStatusInProgress == dumpStatus) &&
79 0 != timeRemaining)
Ben Tyner7029e522021-08-09 19:18:24 -050080 {
Ben Tynere38a90b2022-03-02 19:30:35 -060081 bus.wait(timeRemaining);
82 uint64_t timeElapsed =
83 std::chrono::duration_cast<std::chrono::microseconds>(
84 std::chrono::steady_clock::now() - begin)
85 .count();
86
87 timeRemaining =
88 timeElapsed > timeRemaining ? 0 : timeRemaining - timeElapsed;
89
Ben Tyner7029e522021-08-09 19:18:24 -050090 bus.process_discard();
91 }
Ben Tynere38a90b2022-03-02 19:30:35 -060092
93 if (0 == timeRemaining)
94 {
95 trace::err("dump request timed out after %" PRIu64 " microseconds",
96 dumpTimeout);
97 }
98
99 trace::inf("dump status: %s", dumpStatus.c_str());
Ben Tyner7029e522021-08-09 19:18:24 -0500100}
101
102/** Request a dump from the dump manager */
Zane Shelley611b3442021-11-19 16:02:01 -0600103void requestDump(uint32_t i_logId, const DumpParameters& i_dumpParameters)
Ben Tyner7029e522021-08-09 19:18:24 -0500104{
Patrick Williams27dd6362023-05-10 07:51:20 -0500105 constexpr auto path = "/org/openpower/dump";
Ben Tyner7029e522021-08-09 19:18:24 -0500106 constexpr auto interface = "xyz.openbmc_project.Dump.Create";
Patrick Williams27dd6362023-05-10 07:51:20 -0500107 constexpr auto function = "CreateDump";
Ben Tyner7029e522021-08-09 19:18:24 -0500108
Patrick Williamse212fb02022-07-22 19:26:57 -0500109 sdbusplus::message_t method;
Ben Tyner7029e522021-08-09 19:18:24 -0500110
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.ErrorLogId"] =
Zane Shelley611b3442021-11-19 16:02:01 -0600119 uint64_t(i_logId);
Ben Tyner7029e522021-08-09 19:18:24 -0500120 if (DumpType::Hostboot == i_dumpParameters.dumpType)
121 {
122 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
123 "com.ibm.Dump.Create.DumpType.Hostboot";
124 }
125 else if (DumpType::Hardware == i_dumpParameters.dumpType)
126 {
127 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
128 "com.ibm.Dump.Create.DumpType.Hardware";
129 createParams
130 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
131 i_dumpParameters.unitId;
132 }
Ben Tyner7f6ce6a2021-08-17 19:40:00 -0500133 else if (DumpType::SBE == i_dumpParameters.dumpType)
134 {
135 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
136 "com.ibm.Dump.Create.DumpType.SBE";
137 createParams
138 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
139 i_dumpParameters.unitId;
140 }
Ben Tyner7029e522021-08-09 19:18:24 -0500141 method.append(createParams);
142
143 // using system dbus
Patrick Williams27dd6362023-05-10 07:51:20 -0500144 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -0500145 auto response = bus.call(method);
146
147 // reply will be type dbus::ObjectPath
148 sdbusplus::message::object_path reply;
149 response.read(reply);
150
151 // monitor dump progress
152 monitorDump(reply);
153 }
154 catch (const sdbusplus::exception::SdBusError& e)
155 {
austinfcuibfa831a2022-01-26 15:37:07 -0600156 trace::err("requestDump exception");
157 trace::err(e.what());
Ben Tyner7029e522021-08-09 19:18:24 -0500158 }
159 }
160}
161
162} // namespace attn