xref: /openbmc/openpower-proc-control/extensions/phal/dump_utils.cpp (revision aaea68675bcc020ad360d3decbd6f9c9c5f6dd45)
1 #include "dump_utils.hpp"
2 
3 #include "util.hpp"
4 
5 #include <fmt/format.h>
6 
7 #include <phosphor-logging/log.hpp>
8 #include <sdbusplus/bus.hpp>
9 #include <sdbusplus/exception.hpp>
10 #include <sdbusplus/server.hpp>
11 
12 namespace openpower::phal::dump
13 {
14 
15 using namespace phosphor::logging;
16 
17 /**
18  *  Callback for dump request properties change signal monitor
19  *
20  * @param[in] msg         Dbus message from the dbus match infrastructure
21  * @param[in] path        The object path we are monitoring
22  * @param[out] inProgress Used to break out of our dbus wait loop
23  * @reutn Always non-zero indicating no error, no cascading callbacks
24  */
25 uint32_t dumpStatusChanged(sdbusplus::message_t& msg, const std::string& path,
26                            bool& inProgress)
27 {
28     // reply (msg) will be a property change message
29     std::string interface;
30     std::map<std::string, std::variant<std::string, uint8_t>> property;
31     msg.read(interface, property);
32 
33     // looking for property Status changes
34     std::string propertyType = "Status";
35     auto dumpStatus = property.find(propertyType);
36 
37     if (dumpStatus != property.end())
38     {
39         const std::string* status =
40             std::get_if<std::string>(&(dumpStatus->second));
41 
42         if ((nullptr != status) && ("xyz.openbmc_project.Common.Progress."
43                                     "OperationStatus.InProgress" != *status))
44         {
45             // dump is done, trace some info and change in progress flag
46             log<level::INFO>(fmt::format("Dump status({}) : path={}",
47                                          status->c_str(), path.c_str())
48                                  .c_str());
49             inProgress = false;
50         }
51     }
52 
53     return 1; // non-negative return code for successful callback
54 }
55 
56 /**
57  * Register a callback for dump progress status changes
58  *
59  * @param[in] path The object path of the dump to monitor
60  * @param timeout - timeout - timeout interval in seconds
61  */
62 void monitorDump(const std::string& path, const uint32_t timeout)
63 {
64     bool inProgress = true; // callback will update this
65 
66     // setup the signal match rules and callback
67     std::string matchInterface = "xyz.openbmc_project.Common.Progress";
68     auto bus = sdbusplus::bus::new_system();
69 
70     std::unique_ptr<sdbusplus::bus::match_t> match =
71         std::make_unique<sdbusplus::bus::match_t>(
72             bus,
73             sdbusplus::bus::match::rules::propertiesChanged(
74                 path.c_str(), matchInterface.c_str()),
75             [&](auto& msg) {
76                 return dumpStatusChanged(msg, path, inProgress);
77             });
78 
79     // wait for dump status to be completed (complete == true)
80     // or until timeout interval
81     log<level::INFO>("dump requested (waiting)");
82     bool timedOut = false;
83     uint32_t secondsCount = 0;
84     while ((true == inProgress) && !timedOut)
85     {
86         bus.wait(std::chrono::seconds(1));
87         bus.process_discard();
88 
89         if (++secondsCount == timeout)
90         {
91             timedOut = true;
92         }
93     }
94     if (timedOut)
95     {
96         log<level::ERR>("Dump progress status did not change to "
97                         "complete within the timeout interval, exiting...");
98     }
99 }
100 
101 void requestDump(const DumpParameters& dumpParameters)
102 {
103     log<level::INFO>(fmt::format("Requesting Dump PEL({}) Index({})",
104                                  dumpParameters.logId, dumpParameters.unitId)
105                          .c_str());
106 
107     constexpr auto path = "/org/openpower/dump";
108     constexpr auto interface = "xyz.openbmc_project.Dump.Create";
109     constexpr auto function = "CreateDump";
110 
111     sdbusplus::message_t method;
112 
113     auto bus = sdbusplus::bus::new_default();
114 
115     try
116     {
117         std::string service = util::getService(bus, path, interface);
118         auto method =
119             bus.new_method_call(service.c_str(), path, interface, function);
120 
121         // dbus call arguments
122         std::map<std::string, std::variant<std::string, uint64_t>> createParams;
123         createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
124             uint64_t(dumpParameters.logId);
125         if (DumpType::SBE == dumpParameters.dumpType)
126         {
127             createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
128                 "com.ibm.Dump.Create.DumpType.SBE";
129             createParams["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
130                 dumpParameters.unitId;
131         }
132         method.append(createParams);
133 
134         auto response = bus.call(method);
135 
136         // reply will be type dbus::ObjectPath
137         sdbusplus::message::object_path reply;
138         response.read(reply);
139 
140         // monitor dump progress
141         monitorDump(reply, dumpParameters.timeout);
142     }
143     catch (const sdbusplus::exception_t& e)
144     {
145         log<level::ERR>(fmt::format("D-Bus call createDump exception",
146                                     "OBJPATH={}, INTERFACE={}, EXCEPTION={}",
147                                     path, interface, e.what())
148                             .c_str());
149         constexpr auto ERROR_DUMP_DISABLED =
150             "xyz.openbmc_project.Dump.Create.Error.Disabled";
151         if (e.name() == ERROR_DUMP_DISABLED)
152         {
153             // Dump is disabled, Skip the dump collection.
154             log<level::INFO>(
155                 fmt::format("Dump is disabled on({}), skipping dump collection",
156                             dumpParameters.unitId)
157                     .c_str());
158         }
159         else
160         {
161             throw std::runtime_error(
162                 "Error in invoking D-Bus createDump interface");
163         }
164     }
165     catch (const std::exception& e)
166     {
167         throw e;
168     }
169 }
170 
171 } // namespace openpower::phal::dump
172