blob: 3f325bdbb0c2c178475312896c0e9d7588ef2c87 [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>
6
7namespace 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 */
18uint 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 */
53void 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 */
81void 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 }
Ben Tyner7f6ce6a2021-08-17 19:40:00 -0500111 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 }
Ben Tyner7029e522021-08-09 19:18:24 -0500119 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