blob: 13fe9f0fa5e00f84738d7c00f3805a14b0a73725 [file] [log] [blame]
Sampa Misra18967162020-01-14 02:31:41 -06001#include "file_io_type_dump.hpp"
2
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05003#include "common/utils.hpp"
Ravi Tejace1c96f2020-10-05 23:13:01 -05004#include "utils.hpp"
Sampa Misra18967162020-01-14 02:31:41 -06005#include "xyz/openbmc_project/Common/error.hpp"
6
George Liuc453e162022-12-21 17:16:23 +08007#include <libpldm/base.h>
8#include <libpldm/file_io.h>
Sampa Misra18967162020-01-14 02:31:41 -06009#include <stdint.h>
10#include <systemd/sd-bus.h>
11#include <unistd.h>
12
Sampa Misra18967162020-01-14 02:31:41 -060013#include <sdbusplus/server.hpp>
14#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
15
George Liu6492f522020-06-16 10:34:05 +080016#include <exception>
17#include <filesystem>
18#include <iostream>
Jayashankar Padathdb124362021-01-28 21:12:34 -060019#include <type_traits>
Sampa Misra18967162020-01-14 02:31:41 -060020
Ravi Tejace1c96f2020-10-05 23:13:01 -050021using namespace pldm::responder::utils;
Deepak Kodihallifd279e12020-02-02 05:20:43 -060022using namespace pldm::utils;
23
Sampa Misra18967162020-01-14 02:31:41 -060024namespace pldm
25{
26namespace responder
27{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050028static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
Deepak Kodihalli14b54a32020-09-29 05:20:02 -050029static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump/system";
Jayashankar Padathdb124362021-01-28 21:12:34 -060030static constexpr auto systemDumpEntry = "xyz.openbmc_project.Dump.Entry.System";
31static constexpr auto resDumpObjPath = "/xyz/openbmc_project/dump/resource";
32static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
Sampa Misra18967162020-01-14 02:31:41 -060033
Jayashankar Padathdb124362021-01-28 21:12:34 -060034// Resource dump file path to be deleted once hyperviosr validates the input
35// parameters. Need to re-look in to this name when we support multiple
36// resource dumps.
37static constexpr auto resDumpDirPath = "/var/lib/pldm/resourcedump/1";
38
39int DumpHandler::fd = -1;
40namespace fs = std::filesystem;
41
42std::string DumpHandler::findDumpObjPath(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050043{
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050044 static constexpr auto DUMP_MANAGER_BUSNAME =
45 "xyz.openbmc_project.Dump.Manager";
46 static constexpr auto DUMP_MANAGER_PATH = "/xyz/openbmc_project/dump";
47 static constexpr auto OBJECT_MANAGER_INTERFACE =
48 "org.freedesktop.DBus.ObjectManager";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050049 auto& bus = pldm::utils::DBusHandler::getBus();
50
Jayashankar Padathdb124362021-01-28 21:12:34 -060051 // Stores the current resource dump entry path
52 std::string curResDumpEntryPath{};
53
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050054 dbus::ObjectValueTree objects;
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050055 // Select the dump entry interface for system dump or resource dump
56 DumpEntryInterface dumpEntryIntf = systemDumpEntry;
57 if ((dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP) ||
58 (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS))
59 {
60 dumpEntryIntf = resDumpEntry;
61 }
62
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050063 try
64 {
Archana Kakani040c6182023-02-20 07:01:51 -060065 auto method =
66 bus.new_method_call(DUMP_MANAGER_BUSNAME, DUMP_MANAGER_PATH,
67 OBJECT_MANAGER_INTERFACE, "GetManagedObjects");
68
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050069 auto reply = bus.call(method);
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050070 reply.read(objects);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050071 }
Archana Kakani040c6182023-02-20 07:01:51 -060072 catch (const sdbusplus::exception_t& e)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050073 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -050074 std::cerr << "findDumpObjPath: Error " << e.what()
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050075 << "found with GetManagedObjects call in findDumpObjPath "
76 << "with objPath=" << DUMP_MANAGER_PATH
77 << " and intf=" << dumpEntryIntf << "\n";
78 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050079 }
80
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050081 for (const auto& object : objects)
82 {
83 for (const auto& interface : object.second)
84 {
85 if (interface.first != dumpEntryIntf)
86 {
87 continue;
88 }
89
90 for (auto& propertyMap : interface.second)
91 {
92 if (propertyMap.first == "SourceDumpId")
93 {
94 auto dumpIdPtr = std::get_if<uint32_t>(&propertyMap.second);
95 if (dumpIdPtr != nullptr)
96 {
97 auto dumpId = *dumpIdPtr;
98 if (fileHandle == dumpId)
99 {
100 curResDumpEntryPath = object.first.str;
101 return curResDumpEntryPath;
102 }
103 }
104 else
105 {
106 std::cerr
107 << "Invalid SourceDumpId in curResDumpEntryPath "
108 << curResDumpEntryPath
109 << " but continuing with next entry for a match..."
110 << "\n";
111 }
112 }
113 }
114 }
115 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600116 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500117}
118
Sampa Misra18967162020-01-14 02:31:41 -0600119int DumpHandler::newFileAvailable(uint64_t length)
120{
Sampa Misra18967162020-01-14 02:31:41 -0600121 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -0600122 auto& bus = pldm::utils::DBusHandler::getBus();
123
Jayashankar Padathdb124362021-01-28 21:12:34 -0600124 auto notifyObjPath = dumpObjPath;
125 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
126 {
127 // Setting the Notify path for resource dump
128 notifyObjPath = resDumpObjPath;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600129 }
130
Sampa Misra18967162020-01-14 02:31:41 -0600131 try
132 {
133 auto service =
Jayashankar Padathdb124362021-01-28 21:12:34 -0600134 pldm::utils::DBusHandler().getService(notifyObjPath, dumpInterface);
Sampa Misra18967162020-01-14 02:31:41 -0600135 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600136 auto method = bus.new_method_call(service.c_str(), notifyObjPath,
Sampa Misra18967162020-01-14 02:31:41 -0600137 dumpInterface, "Notify");
Dhruvaraj Subhashchandran41989eb2020-11-27 00:22:42 -0600138 method.append(fileHandle, length);
Sampa Misra18967162020-01-14 02:31:41 -0600139 bus.call_noreply(method);
140 }
141 catch (const std::exception& e)
142 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500143 std::cerr << "newFileAvailable: Error " << e.what()
144 << "found while notifying new dump to dump manager "
145 << "with objPath=" << notifyObjPath
146 << " and intf=" << dumpInterface << "\n";
Sampa Misra18967162020-01-14 02:31:41 -0600147 return PLDM_ERROR;
148 }
149
150 return PLDM_SUCCESS;
151}
152
Jayashankar Padathdb124362021-01-28 21:12:34 -0600153std::string DumpHandler::getOffloadUri(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500154{
155 auto path = findDumpObjPath(fileHandle);
156 if (path.empty())
157 {
158 return {};
159 }
160
Ravi Tejace1c96f2020-10-05 23:13:01 -0500161 std::string socketInterface{};
162
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500163 try
164 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500165 socketInterface =
166 pldm::utils::DBusHandler().getDbusProperty<std::string>(
167 path.c_str(), "OffloadUri", dumpEntry);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500168 }
169 catch (const std::exception& e)
170 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500171 std::cerr << "getOffloadUri: Error " << e.what()
172 << "found while fetching the dump offload URI "
173 << "with objPath=" << path.c_str()
174 << " and intf=" << socketInterface << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500175 }
176
Ravi Tejace1c96f2020-10-05 23:13:01 -0500177 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500178}
179
Jayashankar Padathdb124362021-01-28 21:12:34 -0600180int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500181 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600182{
Sampa Misra18967162020-01-14 02:31:41 -0600183 if (DumpHandler::fd == -1)
184 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500185 auto socketInterface = getOffloadUri(fileHandle);
186 int sock = setupUnixSocket(socketInterface);
187 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600188 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500189 sock = -errno;
190 close(DumpHandler::fd);
191 std::cerr
192 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
193 << std::endl;
194 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600195 return PLDM_ERROR;
196 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500197
Ravi Tejace1c96f2020-10-05 23:13:01 -0500198 DumpHandler::fd = sock;
199 }
200 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600201}
202
Jayashankar Padathdb124362021-01-28 21:12:34 -0600203int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500204 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600205{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500206 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
207 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500208 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500209 rc = -errno;
210 close(DumpHandler::fd);
211 auto socketInterface = getOffloadUri(fileHandle);
212 std::remove(socketInterface.c_str());
213 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
214 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500215 return PLDM_ERROR;
216 }
217
Sampa Misra18967162020-01-14 02:31:41 -0600218 return PLDM_SUCCESS;
219}
220
Jayashankar Padathdb124362021-01-28 21:12:34 -0600221int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600222{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600223 auto path = findDumpObjPath(fileHandle);
224 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600225 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600226 if (fileStatus != PLDM_SUCCESS)
227 {
228 std::cerr << "Failue in resource dump file ack" << std::endl;
229 pldm::utils::reportError(
230 "xyz.openbmc_project.bmc.pldm.InternalFailure");
231
232 PropertyValue value{
233 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
234 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
235 "Status", "string"};
236 try
237 {
238 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
239 }
240 catch (const std::exception& e)
241 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500242 std::cerr << "fileAck: Error " << e.what()
243 << "found while setting the dump progress status as "
244 << "Failed with objPath=" << path.c_str()
245 << " and intf=Common.Progress"
246 << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600247 }
248 }
249
250 if (fs::exists(resDumpDirPath))
251 {
252 fs::remove_all(resDumpDirPath);
253 }
254 return PLDM_SUCCESS;
255 }
256
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500257 if (!path.empty())
Jayashankar Padathdb124362021-01-28 21:12:34 -0600258 {
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500259 if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
260 {
261 uint32_t val = 0xFFFFFFFF;
262 PropertyValue value = static_cast<uint32_t>(val);
263 auto dumpIntf = resDumpEntry;
264
265 if (dumpType == PLDM_FILE_TYPE_DUMP)
266 {
267 dumpIntf = systemDumpEntry;
268 }
269
270 DBusMapping dbusMapping{path.c_str(), dumpIntf, "SourceDumpId",
271 "uint32_t"};
272 try
273 {
274 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
275 }
276 catch (const std::exception& e)
277 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500278 std::cerr << "fileAck: Failed to make a d-bus call to DUMP "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500279 "manager to reset source dump id of "
280 << path.c_str() << ", with ERROR=" << e.what()
281 << "\n";
282 pldm::utils::reportError(
283 "xyz.openbmc_project.bmc.PLDM.fileAck.SourceDumpIdResetFail");
284 return PLDM_ERROR;
285 }
286
287 auto& bus = pldm::utils::DBusHandler::getBus();
288 try
289 {
290 auto method = bus.new_method_call(
291 "xyz.openbmc_project.Dump.Manager", path.c_str(),
292 "xyz.openbmc_project.Object.Delete", "Delete");
293 bus.call(method);
294 }
295 catch (const std::exception& e)
296 {
297 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500298 << "fileAck: Failed to make a d-bus method to delete the dump entry "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500299 << path.c_str() << ", with ERROR=" << e.what() << "\n";
300 pldm::utils::reportError(
301 "xyz.openbmc_project.bmc.PLDM.fileAck.DumpEntryDeleteFail");
302 return PLDM_ERROR;
303 }
304 return PLDM_SUCCESS;
305 }
306
Jayashankar Padathdb124362021-01-28 21:12:34 -0600307 if (dumpType == PLDM_FILE_TYPE_DUMP ||
308 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600309 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500310 PropertyValue value{true};
311 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
312 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600313 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500314 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600315 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500316 catch (const std::exception& e)
317 {
318 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500319 << "fileAck: Failed to make a d-bus method to set the dump "
320 << "offloaded property to true with path=" << path.c_str()
321 << "and with ERROR=" << e.what() << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500322 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500323
Ravi Tejace1c96f2020-10-05 23:13:01 -0500324 auto socketInterface = getOffloadUri(fileHandle);
325 std::remove(socketInterface.c_str());
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500326 if (DumpHandler::fd >= 0)
327 {
328 close(DumpHandler::fd);
329 DumpHandler::fd = -1;
330 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600331 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600332 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600333 }
334
335 return PLDM_ERROR;
336}
337
Jayashankar Padathdb124362021-01-28 21:12:34 -0600338int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
339 uint64_t address,
340 oem_platform::Handler* /*oemPlatformHandler*/)
341{
342 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
343 {
344 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
345 }
346 return transferFileData(resDumpDirPath, true, offset, length, address);
347}
348
349int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
350 oem_platform::Handler* /*oemPlatformHandler*/)
351{
352 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
353 {
354 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
355 }
356 return readFile(resDumpDirPath, offset, length, response);
357}
358
Sampa Misra18967162020-01-14 02:31:41 -0600359} // namespace responder
360} // namespace pldm