blob: c4afb2a1c26523dac0d9a9aabd8151a274ca52ac [file] [log] [blame]
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -05001#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
Patrick Williams40fccd52023-07-17 11:24:09 -05008#include <format>
9
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050010namespace watchdog
11{
12namespace dump
13{
14
15using namespace phosphor::logging;
16
17/**
18 * @brief Callback for dump request properties change signal monitor
19 *
20 * @param msg - dbus message from the dbus match infrastructure
21 * @param path - the object path we are monitoring
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050022 * @param progressStatus - dump progress status
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050023 * @return Always non-zero indicating no error, no cascading callbacks
24 */
Patrick Williamsfc437562022-07-22 19:26:52 -050025uint dumpStatusChanged(sdbusplus::message_t& msg, std::string path,
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050026 DumpProgressStatus& progressStatus)
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050027{
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 {
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050045 // dump is not in InProgress state, trace some info and change in
46 // progress status
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050047 log<level::INFO>(path.c_str());
48 log<level::INFO>((*status).c_str());
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050049
50 if ("xyz.openbmc_project.Common.Progress.OperationStatus."
51 "Completed" == *status)
52 {
53 // Dump completed successfully
54 progressStatus = DumpProgressStatus::Completed;
55 }
56 else
57 {
58 // Dump Failed
59 progressStatus = DumpProgressStatus::Failed;
60 }
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050061 }
62 }
63
64 return 1; // non-negative return code for successful callback
65}
66
67/**
68 * @brief Register a callback for dump progress status changes
69 *
70 * @param path - the object path of the dump to monitor
71 * @param timeout - timeout - timeout interval in seconds
72 */
73void monitorDump(const std::string& path, const uint32_t timeout)
74{
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050075 // callback will update progressStatus
76 DumpProgressStatus progressStatus = DumpProgressStatus::InProgress;
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050077
78 // setup the signal match rules and callback
79 std::string matchInterface = "xyz.openbmc_project.Common.Progress";
80 auto bus = sdbusplus::bus::new_system();
81
82 std::unique_ptr<sdbusplus::bus::match_t> match =
83 std::make_unique<sdbusplus::bus::match_t>(
84 bus,
85 sdbusplus::bus::match::rules::propertiesChanged(
86 path.c_str(), matchInterface.c_str()),
87 [&](auto& msg) {
Patrick Williamsa9779c42023-05-10 07:50:20 -050088 return dumpStatusChanged(msg, path, progressStatus);
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050089 });
90
91 // wait for dump status to be completed (complete == true)
92 // or until timeout interval
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050093
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050094 bool timedOut = false;
95 uint32_t secondsCount = 0;
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -050096 while ((DumpProgressStatus::InProgress == progressStatus) && !timedOut)
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -050097 {
98 bus.wait(std::chrono::seconds(1));
99 bus.process_discard();
100
101 if (++secondsCount == timeout)
102 {
103 timedOut = true;
104 }
105 }
106
107 if (timedOut)
108 {
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500109 log<level::ERR>("Dump progress status did not change to "
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500110 "complete within the timeout interval, exiting...");
111 }
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500112 else if (DumpProgressStatus::Completed == progressStatus)
113 {
114 log<level::INFO>("dump collection completed");
115 }
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500116 else
117 {
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500118 log<level::INFO>("dump collection failed");
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500119 }
120}
121
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500122void requestDump(const DumpParameters& dumpParameters)
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500123{
124 constexpr auto path = "/org/openpower/dump";
125 constexpr auto interface = "xyz.openbmc_project.Dump.Create";
126 constexpr auto function = "CreateDump";
127
Patrick Williamsfc437562022-07-22 19:26:52 -0500128 sdbusplus::message_t method;
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500129
130 if (0 == dbusMethod(path, interface, function, method))
131 {
132 try
133 {
134 // dbus call arguments
135 std::map<std::string, std::variant<std::string, uint64_t>>
136 createParams;
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500137 createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500138 uint64_t(dumpParameters.logId);
139 if (DumpType::Hostboot == dumpParameters.dumpType)
140 {
141 log<level::INFO>("hostboot dump requested");
142 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
143 "com.ibm.Dump.Create.DumpType.Hostboot";
144 }
145 else if (DumpType::SBE == dumpParameters.dumpType)
146 {
147 log<level::INFO>("SBE dump requested");
148 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
149 "com.ibm.Dump.Create.DumpType.SBE";
150 createParams
151 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
152 dumpParameters.unitId;
153 }
154
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500155 method.append(createParams);
156
157 // using system dbus
158 auto bus = sdbusplus::bus::new_system();
159 auto response = bus.call(method);
160
161 // reply will be type dbus::ObjectPath
162 sdbusplus::message::object_path reply;
163 response.read(reply);
164
165 // monitor dump progress
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500166 monitorDump(reply, dumpParameters.timeout);
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500167 }
Patrick Williamsfc437562022-07-22 19:26:52 -0500168 catch (const sdbusplus::exception_t& e)
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500169 {
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500170 constexpr auto ERROR_DUMP_DISABLED =
171 "xyz.openbmc_project.Dump.Create.Error.Disabled";
172 if (e.name() == ERROR_DUMP_DISABLED)
173 {
174 // Dump is disabled, Skip the dump collection.
175 log<level::INFO>(
Patrick Williams40fccd52023-07-17 11:24:09 -0500176 std::format(
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500177 "Dump is disabled on({}), skipping dump collection",
178 dumpParameters.unitId)
179 .c_str());
180 }
181 else
182 {
183 log<level::ERR>(
Patrick Williams40fccd52023-07-17 11:24:09 -0500184 std::format("D-Bus call createDump exception ",
Shantappa Teekappanavar41d507e2021-10-05 12:17:55 -0500185 "OBJPATH={}, INTERFACE={}, EXCEPTION={}", path,
186 interface, e.what())
187 .c_str());
188 }
Shantappa Teekappanavar1ac61622021-06-22 19:07:29 -0500189 }
190 }
191}
192
193} // namespace dump
194} // namespace watchdog