blob: 708dd87f97f5f5584ddb64fbafb89427df899110 [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;
55 auto method =
56 bus.new_method_call(DUMP_MANAGER_BUSNAME, DUMP_MANAGER_PATH,
57 OBJECT_MANAGER_INTERFACE, "GetManagedObjects");
58
59 // Select the dump entry interface for system dump or resource dump
60 DumpEntryInterface dumpEntryIntf = systemDumpEntry;
61 if ((dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP) ||
62 (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS))
63 {
64 dumpEntryIntf = resDumpEntry;
65 }
66
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050067 try
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 }
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050072
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050073 catch (const std::exception& e)
74 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -050075 std::cerr << "findDumpObjPath: Error " << e.what()
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050076 << "found with GetManagedObjects call in findDumpObjPath "
77 << "with objPath=" << DUMP_MANAGER_PATH
78 << " and intf=" << dumpEntryIntf << "\n";
79 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050080 }
81
Jayashankar Padathe7cc8692022-09-06 13:26:22 -050082 for (const auto& object : objects)
83 {
84 for (const auto& interface : object.second)
85 {
86 if (interface.first != dumpEntryIntf)
87 {
88 continue;
89 }
90
91 for (auto& propertyMap : interface.second)
92 {
93 if (propertyMap.first == "SourceDumpId")
94 {
95 auto dumpIdPtr = std::get_if<uint32_t>(&propertyMap.second);
96 if (dumpIdPtr != nullptr)
97 {
98 auto dumpId = *dumpIdPtr;
99 if (fileHandle == dumpId)
100 {
101 curResDumpEntryPath = object.first.str;
102 return curResDumpEntryPath;
103 }
104 }
105 else
106 {
107 std::cerr
108 << "Invalid SourceDumpId in curResDumpEntryPath "
109 << curResDumpEntryPath
110 << " but continuing with next entry for a match..."
111 << "\n";
112 }
113 }
114 }
115 }
116 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600117 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500118}
119
Sampa Misra18967162020-01-14 02:31:41 -0600120int DumpHandler::newFileAvailable(uint64_t length)
121{
Sampa Misra18967162020-01-14 02:31:41 -0600122 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -0600123 auto& bus = pldm::utils::DBusHandler::getBus();
124
Jayashankar Padathdb124362021-01-28 21:12:34 -0600125 auto notifyObjPath = dumpObjPath;
126 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
127 {
128 // Setting the Notify path for resource dump
129 notifyObjPath = resDumpObjPath;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600130 }
131
Sampa Misra18967162020-01-14 02:31:41 -0600132 try
133 {
134 auto service =
Jayashankar Padathdb124362021-01-28 21:12:34 -0600135 pldm::utils::DBusHandler().getService(notifyObjPath, dumpInterface);
Sampa Misra18967162020-01-14 02:31:41 -0600136 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600137 auto method = bus.new_method_call(service.c_str(), notifyObjPath,
Sampa Misra18967162020-01-14 02:31:41 -0600138 dumpInterface, "Notify");
Dhruvaraj Subhashchandran41989eb2020-11-27 00:22:42 -0600139 method.append(fileHandle, length);
Sampa Misra18967162020-01-14 02:31:41 -0600140 bus.call_noreply(method);
141 }
142 catch (const std::exception& e)
143 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500144 std::cerr << "newFileAvailable: Error " << e.what()
145 << "found while notifying new dump to dump manager "
146 << "with objPath=" << notifyObjPath
147 << " and intf=" << dumpInterface << "\n";
Sampa Misra18967162020-01-14 02:31:41 -0600148 return PLDM_ERROR;
149 }
150
151 return PLDM_SUCCESS;
152}
153
Jayashankar Padathdb124362021-01-28 21:12:34 -0600154std::string DumpHandler::getOffloadUri(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500155{
156 auto path = findDumpObjPath(fileHandle);
157 if (path.empty())
158 {
159 return {};
160 }
161
Ravi Tejace1c96f2020-10-05 23:13:01 -0500162 std::string socketInterface{};
163
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500164 try
165 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500166 socketInterface =
167 pldm::utils::DBusHandler().getDbusProperty<std::string>(
168 path.c_str(), "OffloadUri", dumpEntry);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500169 }
170 catch (const std::exception& e)
171 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500172 std::cerr << "getOffloadUri: Error " << e.what()
173 << "found while fetching the dump offload URI "
174 << "with objPath=" << path.c_str()
175 << " and intf=" << socketInterface << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500176 }
177
Ravi Tejace1c96f2020-10-05 23:13:01 -0500178 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500179}
180
Jayashankar Padathdb124362021-01-28 21:12:34 -0600181int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500182 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600183{
Sampa Misra18967162020-01-14 02:31:41 -0600184 if (DumpHandler::fd == -1)
185 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500186 auto socketInterface = getOffloadUri(fileHandle);
187 int sock = setupUnixSocket(socketInterface);
188 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600189 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500190 sock = -errno;
191 close(DumpHandler::fd);
192 std::cerr
193 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
194 << std::endl;
195 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600196 return PLDM_ERROR;
197 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500198
Ravi Tejace1c96f2020-10-05 23:13:01 -0500199 DumpHandler::fd = sock;
200 }
201 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600202}
203
Jayashankar Padathdb124362021-01-28 21:12:34 -0600204int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500205 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600206{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500207 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
208 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500209 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500210 rc = -errno;
211 close(DumpHandler::fd);
212 auto socketInterface = getOffloadUri(fileHandle);
213 std::remove(socketInterface.c_str());
214 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
215 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500216 return PLDM_ERROR;
217 }
218
Sampa Misra18967162020-01-14 02:31:41 -0600219 return PLDM_SUCCESS;
220}
221
Jayashankar Padathdb124362021-01-28 21:12:34 -0600222int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600223{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600224 auto path = findDumpObjPath(fileHandle);
225 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600226 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600227 if (fileStatus != PLDM_SUCCESS)
228 {
229 std::cerr << "Failue in resource dump file ack" << std::endl;
230 pldm::utils::reportError(
231 "xyz.openbmc_project.bmc.pldm.InternalFailure");
232
233 PropertyValue value{
234 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
235 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
236 "Status", "string"};
237 try
238 {
239 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
240 }
241 catch (const std::exception& e)
242 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500243 std::cerr << "fileAck: Error " << e.what()
244 << "found while setting the dump progress status as "
245 << "Failed with objPath=" << path.c_str()
246 << " and intf=Common.Progress"
247 << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600248 }
249 }
250
251 if (fs::exists(resDumpDirPath))
252 {
253 fs::remove_all(resDumpDirPath);
254 }
255 return PLDM_SUCCESS;
256 }
257
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500258 if (!path.empty())
Jayashankar Padathdb124362021-01-28 21:12:34 -0600259 {
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500260 if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
261 {
262 uint32_t val = 0xFFFFFFFF;
263 PropertyValue value = static_cast<uint32_t>(val);
264 auto dumpIntf = resDumpEntry;
265
266 if (dumpType == PLDM_FILE_TYPE_DUMP)
267 {
268 dumpIntf = systemDumpEntry;
269 }
270
271 DBusMapping dbusMapping{path.c_str(), dumpIntf, "SourceDumpId",
272 "uint32_t"};
273 try
274 {
275 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
276 }
277 catch (const std::exception& e)
278 {
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500279 std::cerr << "fileAck: Failed to make a d-bus call to DUMP "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500280 "manager to reset source dump id of "
281 << path.c_str() << ", with ERROR=" << e.what()
282 << "\n";
283 pldm::utils::reportError(
284 "xyz.openbmc_project.bmc.PLDM.fileAck.SourceDumpIdResetFail");
285 return PLDM_ERROR;
286 }
287
288 auto& bus = pldm::utils::DBusHandler::getBus();
289 try
290 {
291 auto method = bus.new_method_call(
292 "xyz.openbmc_project.Dump.Manager", path.c_str(),
293 "xyz.openbmc_project.Object.Delete", "Delete");
294 bus.call(method);
295 }
296 catch (const std::exception& e)
297 {
298 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500299 << "fileAck: Failed to make a d-bus method to delete the dump entry "
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500300 << path.c_str() << ", with ERROR=" << e.what() << "\n";
301 pldm::utils::reportError(
302 "xyz.openbmc_project.bmc.PLDM.fileAck.DumpEntryDeleteFail");
303 return PLDM_ERROR;
304 }
305 return PLDM_SUCCESS;
306 }
307
Jayashankar Padathdb124362021-01-28 21:12:34 -0600308 if (dumpType == PLDM_FILE_TYPE_DUMP ||
309 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600310 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500311 PropertyValue value{true};
312 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
313 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600314 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500315 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600316 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500317 catch (const std::exception& e)
318 {
319 std::cerr
Jayashankar Padathe64f5522022-09-28 21:30:24 -0500320 << "fileAck: Failed to make a d-bus method to set the dump "
321 << "offloaded property to true with path=" << path.c_str()
322 << "and with ERROR=" << e.what() << "\n";
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500323 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500324
Ravi Tejace1c96f2020-10-05 23:13:01 -0500325 auto socketInterface = getOffloadUri(fileHandle);
326 std::remove(socketInterface.c_str());
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500327 if (DumpHandler::fd >= 0)
328 {
329 close(DumpHandler::fd);
330 DumpHandler::fd = -1;
331 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600332 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600333 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600334 }
335
336 return PLDM_ERROR;
337}
338
Jayashankar Padathdb124362021-01-28 21:12:34 -0600339int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
340 uint64_t address,
341 oem_platform::Handler* /*oemPlatformHandler*/)
342{
343 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
344 {
345 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
346 }
347 return transferFileData(resDumpDirPath, true, offset, length, address);
348}
349
350int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
351 oem_platform::Handler* /*oemPlatformHandler*/)
352{
353 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
354 {
355 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
356 }
357 return readFile(resDumpDirPath, offset, length, response);
358}
359
Sampa Misra18967162020-01-14 02:31:41 -0600360} // namespace responder
361} // namespace pldm