blob: 167835aba7bf9586156ce37991d426ee8847d466 [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>
Deepa Karthikeyana92dc022024-04-16 03:45:57 -05006#include <util/dbus.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06007#include <util/trace.hpp>
Ben Tyner7029e522021-08-09 19:18:24 -05008
Ben Tynere38a90b2022-03-02 19:30:35 -06009constexpr uint64_t dumpTimeout = 3600000000; // microseconds
10
11constexpr auto operationStatusInProgress =
12 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress";
13
Ben Tyner7029e522021-08-09 19:18:24 -050014namespace attn
15{
16
17/**
18 * Callback for dump request properties change signal monitor
19 *
20 * @param[in] i_msg Dbus message from the dbus match infrastructure
Ben Tynere38a90b2022-03-02 19:30:35 -060021 * @param[out] o_dumpStatus Dump status dbus response string
22 * @return Always non-zero indicating no error, no cascading callbacks
Ben Tyner7029e522021-08-09 19:18:24 -050023 */
Patrick Williamse212fb02022-07-22 19:26:57 -050024uint dumpStatusChanged(sdbusplus::message_t& i_msg, std::string& o_dumpStatus)
Ben Tyner7029e522021-08-09 19:18:24 -050025{
26 // reply (msg) will be a property change message
27 std::string interface;
28 std::map<std::string, std::variant<std::string, uint8_t>> property;
29 i_msg.read(interface, property);
30
31 // looking for property Status changes
32 std::string propertyType = "Status";
Patrick Williams27dd6362023-05-10 07:51:20 -050033 auto dumpStatus = property.find(propertyType);
Ben Tyner7029e522021-08-09 19:18:24 -050034
35 if (dumpStatus != property.end())
36 {
37 const std::string* status =
38 std::get_if<std::string>(&(dumpStatus->second));
39
Ben Tynere38a90b2022-03-02 19:30:35 -060040 if (nullptr != status)
Ben Tyner7029e522021-08-09 19:18:24 -050041 {
Ben Tynere38a90b2022-03-02 19:30:35 -060042 o_dumpStatus = *status;
Ben Tyner7029e522021-08-09 19:18:24 -050043 }
44 }
45
46 return 1; // non-negative return code for successful callback
47}
48
49/**
50 * Register a callback for dump progress status changes
51 *
52 * @param[in] i_path The object path of the dump to monitor
53 */
54void monitorDump(const std::string& i_path)
55{
Ben Tyner7029e522021-08-09 19:18:24 -050056 // setup the signal match rules and callback
57 std::string matchInterface = "xyz.openbmc_project.Common.Progress";
Patrick Williams27dd6362023-05-10 07:51:20 -050058 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -050059
Ben Tynere38a90b2022-03-02 19:30:35 -060060 // monitor dump status change property, will update dumpStatus
61 std::string dumpStatus = "requested";
Ben Tyner7029e522021-08-09 19:18:24 -050062 std::unique_ptr<sdbusplus::bus::match_t> match =
63 std::make_unique<sdbusplus::bus::match_t>(
64 bus,
65 sdbusplus::bus::match::rules::propertiesChanged(
66 i_path.c_str(), matchInterface.c_str()),
Ben Tynere38a90b2022-03-02 19:30:35 -060067 [&](auto& msg) { return dumpStatusChanged(msg, dumpStatus); });
Ben Tyner7029e522021-08-09 19:18:24 -050068
69 // wait for dump status to be completed (complete == true)
Ben Tynere38a90b2022-03-02 19:30:35 -060070 trace::inf("dump requested %s", i_path.c_str());
71
72 // wait for dump status not InProgress or timeout
73 uint64_t timeRemaining = dumpTimeout;
74
75 std::chrono::steady_clock::time_point begin =
76 std::chrono::steady_clock::now();
77
78 while (("requested" == dumpStatus ||
79 operationStatusInProgress == dumpStatus) &&
80 0 != timeRemaining)
Ben Tyner7029e522021-08-09 19:18:24 -050081 {
Ben Tynere38a90b2022-03-02 19:30:35 -060082 bus.wait(timeRemaining);
83 uint64_t timeElapsed =
84 std::chrono::duration_cast<std::chrono::microseconds>(
85 std::chrono::steady_clock::now() - begin)
86 .count();
87
88 timeRemaining =
89 timeElapsed > timeRemaining ? 0 : timeRemaining - timeElapsed;
90
Ben Tyner7029e522021-08-09 19:18:24 -050091 bus.process_discard();
92 }
Ben Tynere38a90b2022-03-02 19:30:35 -060093
94 if (0 == timeRemaining)
95 {
96 trace::err("dump request timed out after %" PRIu64 " microseconds",
97 dumpTimeout);
98 }
99
100 trace::inf("dump status: %s", dumpStatus.c_str());
Ben Tyner7029e522021-08-09 19:18:24 -0500101}
102
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500103/** Api used to enable or disable watchdog dbus property */
104void enableWatchdog(bool enable)
105{
106 constexpr auto service = "xyz.openbmc_project.Watchdog";
107 constexpr auto object = "/xyz/openbmc_project/watchdog/host0";
108 constexpr auto interface = "xyz.openbmc_project.State.Watchdog";
109 constexpr auto property = "Enabled";
110 util::dbus::setProperty<bool>(service, object, interface, property, enable);
111}
112
Ben Tyner7029e522021-08-09 19:18:24 -0500113/** Request a dump from the dump manager */
Zane Shelley611b3442021-11-19 16:02:01 -0600114void requestDump(uint32_t i_logId, const DumpParameters& i_dumpParameters)
Ben Tyner7029e522021-08-09 19:18:24 -0500115{
Patrick Williams27dd6362023-05-10 07:51:20 -0500116 constexpr auto path = "/org/openpower/dump";
Ben Tyner7029e522021-08-09 19:18:24 -0500117 constexpr auto interface = "xyz.openbmc_project.Dump.Create";
Patrick Williams27dd6362023-05-10 07:51:20 -0500118 constexpr auto function = "CreateDump";
Ben Tyner7029e522021-08-09 19:18:24 -0500119
Patrick Williamse212fb02022-07-22 19:26:57 -0500120 sdbusplus::message_t method;
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500121 bool watchdogDisabled = false;
Ben Tyner7029e522021-08-09 19:18:24 -0500122
123 if (0 == dbusMethod(path, interface, function, method))
124 {
125 try
126 {
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500127 // During a checkstop attention, the system is not functioning
128 // normally. So a hardware or hostboot dump is collected and it
129 // could take a while to get completed. So disable the watchdog when
130 // the dump collection is in progress.
131 if (DumpType::Hostboot == i_dumpParameters.dumpType ||
132 DumpType::Hardware == i_dumpParameters.dumpType)
133 {
134 watchdogDisabled = true;
135 enableWatchdog(false);
136 }
Ben Tyner7029e522021-08-09 19:18:24 -0500137 // dbus call arguments
138 std::map<std::string, std::variant<std::string, uint64_t>>
139 createParams;
140 createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
Zane Shelley611b3442021-11-19 16:02:01 -0600141 uint64_t(i_logId);
Ben Tyner7029e522021-08-09 19:18:24 -0500142 if (DumpType::Hostboot == i_dumpParameters.dumpType)
143 {
144 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
145 "com.ibm.Dump.Create.DumpType.Hostboot";
146 }
147 else if (DumpType::Hardware == i_dumpParameters.dumpType)
148 {
149 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
150 "com.ibm.Dump.Create.DumpType.Hardware";
151 createParams
152 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
153 i_dumpParameters.unitId;
154 }
Ben Tyner7f6ce6a2021-08-17 19:40:00 -0500155 else if (DumpType::SBE == i_dumpParameters.dumpType)
156 {
157 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
158 "com.ibm.Dump.Create.DumpType.SBE";
159 createParams
160 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
161 i_dumpParameters.unitId;
162 }
Ben Tyner7029e522021-08-09 19:18:24 -0500163 method.append(createParams);
164
165 // using system dbus
Patrick Williams27dd6362023-05-10 07:51:20 -0500166 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -0500167 auto response = bus.call(method);
168
169 // reply will be type dbus::ObjectPath
170 sdbusplus::message::object_path reply;
171 response.read(reply);
172
173 // monitor dump progress
174 monitorDump(reply);
175 }
176 catch (const sdbusplus::exception::SdBusError& e)
177 {
austinfcuibfa831a2022-01-26 15:37:07 -0600178 trace::err("requestDump exception");
179 trace::err(e.what());
Ben Tyner7029e522021-08-09 19:18:24 -0500180 }
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500181
182 if (watchdogDisabled)
183 {
184 // Dump collection is over, enable the watchdog
185 enableWatchdog(true);
186 }
Ben Tyner7029e522021-08-09 19:18:24 -0500187 }
188}
189
190} // namespace attn