blob: 6199f85d830a5976336c205d00ff6adf0add212b [file] [log] [blame]
Dhruvaraj Subhashchandran0c1487c2024-06-01 11:07:26 -05001#include "config.h"
2
Ben Tyner7029e522021-08-09 19:18:24 -05003#include <attn/attn_dbus.hpp>
4#include <attn/attn_dump.hpp>
5#include <attn/attn_logging.hpp>
6#include <sdbusplus/bus.hpp>
7#include <sdbusplus/exception.hpp>
Deepa Karthikeyana92dc022024-04-16 03:45:57 -05008#include <util/dbus.hpp>
austinfcuibfa831a2022-01-26 15:37:07 -06009#include <util/trace.hpp>
Ben Tyner7029e522021-08-09 19:18:24 -050010
Ben Tynere38a90b2022-03-02 19:30:35 -060011constexpr uint64_t dumpTimeout = 3600000000; // microseconds
12
13constexpr auto operationStatusInProgress =
14 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress";
15
Ben Tyner7029e522021-08-09 19:18:24 -050016namespace attn
17{
18
19/**
20 * Callback for dump request properties change signal monitor
21 *
22 * @param[in] i_msg Dbus message from the dbus match infrastructure
Ben Tynere38a90b2022-03-02 19:30:35 -060023 * @param[out] o_dumpStatus Dump status dbus response string
24 * @return Always non-zero indicating no error, no cascading callbacks
Ben Tyner7029e522021-08-09 19:18:24 -050025 */
Patrick Williamse212fb02022-07-22 19:26:57 -050026uint dumpStatusChanged(sdbusplus::message_t& i_msg, std::string& o_dumpStatus)
Ben Tyner7029e522021-08-09 19:18:24 -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 i_msg.read(interface, property);
32
33 // looking for property Status changes
34 std::string propertyType = "Status";
Patrick Williams27dd6362023-05-10 07:51:20 -050035 auto dumpStatus = property.find(propertyType);
Ben Tyner7029e522021-08-09 19:18:24 -050036
37 if (dumpStatus != property.end())
38 {
39 const std::string* status =
40 std::get_if<std::string>(&(dumpStatus->second));
41
Ben Tynere38a90b2022-03-02 19:30:35 -060042 if (nullptr != status)
Ben Tyner7029e522021-08-09 19:18:24 -050043 {
Ben Tynere38a90b2022-03-02 19:30:35 -060044 o_dumpStatus = *status;
Ben Tyner7029e522021-08-09 19:18:24 -050045 }
46 }
47
48 return 1; // non-negative return code for successful callback
49}
50
51/**
52 * Register a callback for dump progress status changes
53 *
54 * @param[in] i_path The object path of the dump to monitor
55 */
56void monitorDump(const std::string& i_path)
57{
Ben Tyner7029e522021-08-09 19:18:24 -050058 // setup the signal match rules and callback
59 std::string matchInterface = "xyz.openbmc_project.Common.Progress";
Patrick Williams27dd6362023-05-10 07:51:20 -050060 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -050061
Ben Tynere38a90b2022-03-02 19:30:35 -060062 // monitor dump status change property, will update dumpStatus
63 std::string dumpStatus = "requested";
Ben Tyner7029e522021-08-09 19:18:24 -050064 std::unique_ptr<sdbusplus::bus::match_t> match =
65 std::make_unique<sdbusplus::bus::match_t>(
66 bus,
67 sdbusplus::bus::match::rules::propertiesChanged(
68 i_path.c_str(), matchInterface.c_str()),
Ben Tynere38a90b2022-03-02 19:30:35 -060069 [&](auto& msg) { return dumpStatusChanged(msg, dumpStatus); });
Ben Tyner7029e522021-08-09 19:18:24 -050070
71 // wait for dump status to be completed (complete == true)
Ben Tynere38a90b2022-03-02 19:30:35 -060072 trace::inf("dump requested %s", i_path.c_str());
73
74 // wait for dump status not InProgress or timeout
75 uint64_t timeRemaining = dumpTimeout;
76
77 std::chrono::steady_clock::time_point begin =
78 std::chrono::steady_clock::now();
79
80 while (("requested" == dumpStatus ||
81 operationStatusInProgress == dumpStatus) &&
82 0 != timeRemaining)
Ben Tyner7029e522021-08-09 19:18:24 -050083 {
Ben Tynere38a90b2022-03-02 19:30:35 -060084 bus.wait(timeRemaining);
85 uint64_t timeElapsed =
86 std::chrono::duration_cast<std::chrono::microseconds>(
87 std::chrono::steady_clock::now() - begin)
88 .count();
89
90 timeRemaining =
91 timeElapsed > timeRemaining ? 0 : timeRemaining - timeElapsed;
92
Ben Tyner7029e522021-08-09 19:18:24 -050093 bus.process_discard();
94 }
Ben Tynere38a90b2022-03-02 19:30:35 -060095
96 if (0 == timeRemaining)
97 {
98 trace::err("dump request timed out after %" PRIu64 " microseconds",
99 dumpTimeout);
100 }
101
102 trace::inf("dump status: %s", dumpStatus.c_str());
Ben Tyner7029e522021-08-09 19:18:24 -0500103}
104
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500105/** Api used to enable or disable watchdog dbus property */
106void enableWatchdog(bool enable)
107{
108 constexpr auto service = "xyz.openbmc_project.Watchdog";
109 constexpr auto object = "/xyz/openbmc_project/watchdog/host0";
110 constexpr auto interface = "xyz.openbmc_project.State.Watchdog";
111 constexpr auto property = "Enabled";
112 util::dbus::setProperty<bool>(service, object, interface, property, enable);
113}
114
Ben Tyner7029e522021-08-09 19:18:24 -0500115/** Request a dump from the dump manager */
Zane Shelley611b3442021-11-19 16:02:01 -0600116void requestDump(uint32_t i_logId, const DumpParameters& i_dumpParameters)
Ben Tyner7029e522021-08-09 19:18:24 -0500117{
Ben Tyner7029e522021-08-09 19:18:24 -0500118 constexpr auto interface = "xyz.openbmc_project.Dump.Create";
Patrick Williams27dd6362023-05-10 07:51:20 -0500119 constexpr auto function = "CreateDump";
Ben Tyner7029e522021-08-09 19:18:24 -0500120
Patrick Williamse212fb02022-07-22 19:26:57 -0500121 sdbusplus::message_t method;
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500122 bool watchdogDisabled = false;
Ben Tyner7029e522021-08-09 19:18:24 -0500123
Dhruvaraj Subhashchandran0c1487c2024-06-01 11:07:26 -0500124 if (0 == dbusMethod(OP_DUMP_OBJ_PATH, interface, function, method))
Ben Tyner7029e522021-08-09 19:18:24 -0500125 {
126 try
127 {
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500128 // During a checkstop attention, the system is not functioning
129 // normally. So a hardware or hostboot dump is collected and it
130 // could take a while to get completed. So disable the watchdog when
131 // the dump collection is in progress.
132 if (DumpType::Hostboot == i_dumpParameters.dumpType ||
133 DumpType::Hardware == i_dumpParameters.dumpType)
134 {
135 watchdogDisabled = true;
136 enableWatchdog(false);
137 }
Ben Tyner7029e522021-08-09 19:18:24 -0500138 // dbus call arguments
139 std::map<std::string, std::variant<std::string, uint64_t>>
140 createParams;
141 createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
Zane Shelley611b3442021-11-19 16:02:01 -0600142 uint64_t(i_logId);
Ben Tyner7029e522021-08-09 19:18:24 -0500143 if (DumpType::Hostboot == i_dumpParameters.dumpType)
144 {
145 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
146 "com.ibm.Dump.Create.DumpType.Hostboot";
147 }
148 else if (DumpType::Hardware == i_dumpParameters.dumpType)
149 {
150 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
151 "com.ibm.Dump.Create.DumpType.Hardware";
152 createParams
153 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
154 i_dumpParameters.unitId;
155 }
Ben Tyner7f6ce6a2021-08-17 19:40:00 -0500156 else if (DumpType::SBE == i_dumpParameters.dumpType)
157 {
158 createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
159 "com.ibm.Dump.Create.DumpType.SBE";
160 createParams
161 ["com.ibm.Dump.Create.CreateParameters.FailingUnitId"] =
162 i_dumpParameters.unitId;
163 }
Ben Tyner7029e522021-08-09 19:18:24 -0500164 method.append(createParams);
165
166 // using system dbus
Patrick Williams27dd6362023-05-10 07:51:20 -0500167 auto bus = sdbusplus::bus::new_system();
Ben Tyner7029e522021-08-09 19:18:24 -0500168 auto response = bus.call(method);
169
170 // reply will be type dbus::ObjectPath
171 sdbusplus::message::object_path reply;
172 response.read(reply);
173
174 // monitor dump progress
175 monitorDump(reply);
176 }
177 catch (const sdbusplus::exception::SdBusError& e)
178 {
austinfcuibfa831a2022-01-26 15:37:07 -0600179 trace::err("requestDump exception");
180 trace::err(e.what());
Ben Tyner7029e522021-08-09 19:18:24 -0500181 }
Deepa Karthikeyana92dc022024-04-16 03:45:57 -0500182
183 if (watchdogDisabled)
184 {
185 // Dump collection is over, enable the watchdog
186 enableWatchdog(true);
187 }
Ben Tyner7029e522021-08-09 19:18:24 -0500188 }
189}
190
191} // namespace attn