blob: 87eaa22558de97c4884745a7bd6e8be8aa39a250 [file] [log] [blame]
Sampa Misra18967162020-01-14 02:31:41 -06001#include "file_io_type_dump.hpp"
2
George Liu6492f522020-06-16 10:34:05 +08003#include "libpldm/base.h"
Andrew Jeffery27a022c2022-08-10 23:12:49 +09304#include "libpldm/file_io.h"
George Liu6492f522020-06-16 10:34:05 +08005
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05006#include "common/utils.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05007#include "utils.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06008#include "xyz/openbmc_project/Common/error.hpp"
9
10#include <stdint.h>
11#include <systemd/sd-bus.h>
12#include <unistd.h>
13
Sampa Misra18967162020-01-14 02:31:41 -060014#include <sdbusplus/server.hpp>
15#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
16
George Liu6492f522020-06-16 10:34:05 +080017#include <exception>
18#include <filesystem>
19#include <iostream>
Jayashankar Padathdb124362021-01-28 21:12:34 -060020#include <type_traits>
Sampa Misra18967162020-01-14 02:31:41 -060021
Ravi Tejace1c96f2020-10-05 23:13:01 -050022using namespace pldm::responder::utils;
Deepak Kodihallifd279e12020-02-02 05:20:43 -060023using namespace pldm::utils;
24
Sampa Misra18967162020-01-14 02:31:41 -060025namespace pldm
26{
27namespace responder
28{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050029static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
Deepak Kodihalli14b54a32020-09-29 05:20:02 -050030static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump/system";
Jayashankar Padathdb124362021-01-28 21:12:34 -060031static constexpr auto systemDumpEntry = "xyz.openbmc_project.Dump.Entry.System";
32static constexpr auto resDumpObjPath = "/xyz/openbmc_project/dump/resource";
33static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
Sampa Misra18967162020-01-14 02:31:41 -060034
Jayashankar Padathdb124362021-01-28 21:12:34 -060035// Resource dump file path to be deleted once hyperviosr validates the input
36// parameters. Need to re-look in to this name when we support multiple
37// resource dumps.
38static constexpr auto resDumpDirPath = "/var/lib/pldm/resourcedump/1";
39
40int DumpHandler::fd = -1;
41namespace fs = std::filesystem;
42
43std::string DumpHandler::findDumpObjPath(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050044{
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050045 static constexpr auto DUMP_MANAGER_BUSNAME =
46 "xyz.openbmc_project.Dump.Manager";
47 static constexpr auto DUMP_MANAGER_PATH = "/xyz/openbmc_project/dump";
48 static constexpr auto OBJECT_MANAGER_INTERFACE =
49 "org.freedesktop.DBus.ObjectManager";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050050 auto& bus = pldm::utils::DBusHandler::getBus();
51
Jayashankar Padathdb124362021-01-28 21:12:34 -060052 // Stores the current resource dump entry path
53 std::string curResDumpEntryPath{};
54
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050055 dbus::ObjectValueTree objects;
56 auto method =
57 bus.new_method_call(DUMP_MANAGER_BUSNAME, DUMP_MANAGER_PATH,
58 OBJECT_MANAGER_INTERFACE, "GetManagedObjects");
59
60 // Select the dump entry interface for system dump or resource dump
61 DumpEntryInterface dumpEntryIntf = systemDumpEntry;
62 if ((dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP) ||
63 (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS))
64 {
65 dumpEntryIntf = resDumpEntry;
66 }
67
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050068 try
69 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050070 auto reply = bus.call(method);
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050071 reply.read(objects);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050072 }
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050073
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050074 catch (const std::exception& e)
75 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -050076 std::cerr << "findDumpObjPath: Error " << e.what()
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050077 << "found with GetManagedObjects call in findDumpObjPath "
78 << "with objPath=" << DUMP_MANAGER_PATH
79 << " and intf=" << dumpEntryIntf << "\n";
80 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050081 }
82
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050083 for (const auto& object : objects)
84 {
85 for (const auto& interface : object.second)
86 {
87 if (interface.first != dumpEntryIntf)
88 {
89 continue;
90 }
91
92 for (auto& propertyMap : interface.second)
93 {
94 if (propertyMap.first == "SourceDumpId")
95 {
96 auto dumpIdPtr = std::get_if<uint32_t>(&propertyMap.second);
97 if (dumpIdPtr != nullptr)
98 {
99 auto dumpId = *dumpIdPtr;
100 if (fileHandle == dumpId)
101 {
102 curResDumpEntryPath = object.first.str;
103 return curResDumpEntryPath;
104 }
105 }
106 else
107 {
108 std::cerr
109 << "Invalid SourceDumpId in curResDumpEntryPath "
110 << curResDumpEntryPath
111 << " but continuing with next entry for a match..."
112 << "\n";
113 }
114 }
115 }
116 }
117 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600118 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500119}
120
Sampa Misra18967162020-01-14 02:31:41 -0600121int DumpHandler::newFileAvailable(uint64_t length)
122{
Sampa Misra18967162020-01-14 02:31:41 -0600123 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -0600124 auto& bus = pldm::utils::DBusHandler::getBus();
125
Jayashankar Padathdb124362021-01-28 21:12:34 -0600126 auto notifyObjPath = dumpObjPath;
127 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
128 {
129 // Setting the Notify path for resource dump
130 notifyObjPath = resDumpObjPath;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600131 }
132
Sampa Misra18967162020-01-14 02:31:41 -0600133 try
134 {
135 auto service =
Jayashankar Padathdb124362021-01-28 21:12:34 -0600136 pldm::utils::DBusHandler().getService(notifyObjPath, dumpInterface);
Sampa Misra18967162020-01-14 02:31:41 -0600137 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600138 auto method = bus.new_method_call(service.c_str(), notifyObjPath,
Sampa Misra18967162020-01-14 02:31:41 -0600139 dumpInterface, "Notify");
Dhruvaraj Subhashchandran41989eb2020-11-27 00:22:42 -0600140 method.append(fileHandle, length);
Sampa Misra18967162020-01-14 02:31:41 -0600141 bus.call_noreply(method);
142 }
143 catch (const std::exception& e)
144 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500145 std::cerr << "newFileAvailable: Error " << e.what()
146 << "found while notifying new dump to dump manager "
147 << "with objPath=" << notifyObjPath
148 << " and intf=" << dumpInterface << "\n";
Sampa Misra18967162020-01-14 02:31:41 -0600149 return PLDM_ERROR;
150 }
151
152 return PLDM_SUCCESS;
153}
154
Jayashankar Padathdb124362021-01-28 21:12:34 -0600155std::string DumpHandler::getOffloadUri(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500156{
157 auto path = findDumpObjPath(fileHandle);
158 if (path.empty())
159 {
160 return {};
161 }
162
Ravi Tejace1c96f2020-10-05 23:13:01 -0500163 std::string socketInterface{};
164
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500165 try
166 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500167 socketInterface =
168 pldm::utils::DBusHandler().getDbusProperty<std::string>(
169 path.c_str(), "OffloadUri", dumpEntry);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500170 }
171 catch (const std::exception& e)
172 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500173 std::cerr << "getOffloadUri: Error " << e.what()
174 << "found while fetching the dump offload URI "
175 << "with objPath=" << path.c_str()
176 << " and intf=" << socketInterface << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500177 }
178
Ravi Tejace1c96f2020-10-05 23:13:01 -0500179 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500180}
181
Jayashankar Padathdb124362021-01-28 21:12:34 -0600182int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500183 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600184{
Sampa Misra18967162020-01-14 02:31:41 -0600185 if (DumpHandler::fd == -1)
186 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500187 auto socketInterface = getOffloadUri(fileHandle);
188 int sock = setupUnixSocket(socketInterface);
189 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600190 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500191 sock = -errno;
192 close(DumpHandler::fd);
193 std::cerr
194 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
195 << std::endl;
196 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600197 return PLDM_ERROR;
198 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500199
Ravi Tejace1c96f2020-10-05 23:13:01 -0500200 DumpHandler::fd = sock;
201 }
202 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600203}
204
Jayashankar Padathdb124362021-01-28 21:12:34 -0600205int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500206 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600207{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500208 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
209 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500210 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500211 rc = -errno;
212 close(DumpHandler::fd);
213 auto socketInterface = getOffloadUri(fileHandle);
214 std::remove(socketInterface.c_str());
215 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
216 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500217 return PLDM_ERROR;
218 }
219
Sampa Misra18967162020-01-14 02:31:41 -0600220 return PLDM_SUCCESS;
221}
222
Jayashankar Padathdb124362021-01-28 21:12:34 -0600223int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600224{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600225 auto path = findDumpObjPath(fileHandle);
226 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600227 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600228 if (fileStatus != PLDM_SUCCESS)
229 {
230 std::cerr << "Failue in resource dump file ack" << std::endl;
231 pldm::utils::reportError(
232 "xyz.openbmc_project.bmc.pldm.InternalFailure");
233
234 PropertyValue value{
235 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
236 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
237 "Status", "string"};
238 try
239 {
240 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
241 }
242 catch (const std::exception& e)
243 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500244 std::cerr << "fileAck: Error " << e.what()
245 << "found while setting the dump progress status as "
246 << "Failed with objPath=" << path.c_str()
247 << " and intf=Common.Progress"
248 << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600249 }
250 }
251
252 if (fs::exists(resDumpDirPath))
253 {
254 fs::remove_all(resDumpDirPath);
255 }
256 return PLDM_SUCCESS;
257 }
258
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500259 if (!path.empty())
Jayashankar Padathdb124362021-01-28 21:12:34 -0600260 {
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500261 if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
262 {
263 uint32_t val = 0xFFFFFFFF;
264 PropertyValue value = static_cast<uint32_t>(val);
265 auto dumpIntf = resDumpEntry;
266
267 if (dumpType == PLDM_FILE_TYPE_DUMP)
268 {
269 dumpIntf = systemDumpEntry;
270 }
271
272 DBusMapping dbusMapping{path.c_str(), dumpIntf, "SourceDumpId",
273 "uint32_t"};
274 try
275 {
276 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
277 }
278 catch (const std::exception& e)
279 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500280 std::cerr << "fileAck: Failed to make a d-bus call to DUMP "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500281 "manager to reset source dump id of "
282 << path.c_str() << ", with ERROR=" << e.what()
283 << "\n";
284 pldm::utils::reportError(
285 "xyz.openbmc_project.bmc.PLDM.fileAck.SourceDumpIdResetFail");
286 return PLDM_ERROR;
287 }
288
289 auto& bus = pldm::utils::DBusHandler::getBus();
290 try
291 {
292 auto method = bus.new_method_call(
293 "xyz.openbmc_project.Dump.Manager", path.c_str(),
294 "xyz.openbmc_project.Object.Delete", "Delete");
295 bus.call(method);
296 }
297 catch (const std::exception& e)
298 {
299 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500300 << "fileAck: Failed to make a d-bus method to delete the dump entry "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500301 << path.c_str() << ", with ERROR=" << e.what() << "\n";
302 pldm::utils::reportError(
303 "xyz.openbmc_project.bmc.PLDM.fileAck.DumpEntryDeleteFail");
304 return PLDM_ERROR;
305 }
306 return PLDM_SUCCESS;
307 }
308
Jayashankar Padathdb124362021-01-28 21:12:34 -0600309 if (dumpType == PLDM_FILE_TYPE_DUMP ||
310 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600311 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500312 PropertyValue value{true};
313 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
314 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600315 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500316 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600317 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500318 catch (const std::exception& e)
319 {
320 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500321 << "fileAck: Failed to make a d-bus method to set the dump "
322 << "offloaded property to true with path=" << path.c_str()
323 << "and with ERROR=" << e.what() << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500324 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500325
Ravi Tejace1c96f2020-10-05 23:13:01 -0500326 auto socketInterface = getOffloadUri(fileHandle);
327 std::remove(socketInterface.c_str());
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500328 if (DumpHandler::fd >= 0)
329 {
330 close(DumpHandler::fd);
331 DumpHandler::fd = -1;
332 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600333 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600334 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600335 }
336
337 return PLDM_ERROR;
338}
339
Jayashankar Padathdb124362021-01-28 21:12:34 -0600340int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
341 uint64_t address,
342 oem_platform::Handler* /*oemPlatformHandler*/)
343{
344 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
345 {
346 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
347 }
348 return transferFileData(resDumpDirPath, true, offset, length, address);
349}
350
351int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
352 oem_platform::Handler* /*oemPlatformHandler*/)
353{
354 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
355 {
356 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
357 }
358 return readFile(resDumpDirPath, offset, length, response);
359}
360
Sampa Misra18967162020-01-14 02:31:41 -0600361} // namespace responder
362} // namespace pldm