blob: 94821b4af1c49948a8f4c5fc7ff5be9257b3418b [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 Padathe7cc8692022-09-06 13:26:22 -050076 std::cerr << "Error " << e.what()
77 << "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 {
145 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
146 << e.what() << "\n";
147 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 {
171 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
172 << e.what() << "\n";
173 }
174
Ravi Tejace1c96f2020-10-05 23:13:01 -0500175 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500176}
177
Jayashankar Padathdb124362021-01-28 21:12:34 -0600178int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500179 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600180{
Sampa Misra18967162020-01-14 02:31:41 -0600181 if (DumpHandler::fd == -1)
182 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500183 auto socketInterface = getOffloadUri(fileHandle);
184 int sock = setupUnixSocket(socketInterface);
185 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600186 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500187 sock = -errno;
188 close(DumpHandler::fd);
189 std::cerr
190 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
191 << std::endl;
192 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600193 return PLDM_ERROR;
194 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500195
Ravi Tejace1c96f2020-10-05 23:13:01 -0500196 DumpHandler::fd = sock;
197 }
198 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600199}
200
Jayashankar Padathdb124362021-01-28 21:12:34 -0600201int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500202 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600203{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500204 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
205 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500206 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500207 rc = -errno;
208 close(DumpHandler::fd);
209 auto socketInterface = getOffloadUri(fileHandle);
210 std::remove(socketInterface.c_str());
211 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
212 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500213 return PLDM_ERROR;
214 }
215
Sampa Misra18967162020-01-14 02:31:41 -0600216 return PLDM_SUCCESS;
217}
218
Jayashankar Padathdb124362021-01-28 21:12:34 -0600219int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600220{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600221 auto path = findDumpObjPath(fileHandle);
222 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600223 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600224 if (fileStatus != PLDM_SUCCESS)
225 {
226 std::cerr << "Failue in resource dump file ack" << std::endl;
227 pldm::utils::reportError(
228 "xyz.openbmc_project.bmc.pldm.InternalFailure");
229
230 PropertyValue value{
231 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
232 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
233 "Status", "string"};
234 try
235 {
236 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
237 }
238 catch (const std::exception& e)
239 {
240 std::cerr << "failed to make a d-bus call to DUMP "
241 "manager, ERROR="
242 << e.what() << "\n";
243 }
244 }
245
246 if (fs::exists(resDumpDirPath))
247 {
248 fs::remove_all(resDumpDirPath);
249 }
250 return PLDM_SUCCESS;
251 }
252
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500253 if (!path.empty())
Jayashankar Padathdb124362021-01-28 21:12:34 -0600254 {
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500255 if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
256 {
257 uint32_t val = 0xFFFFFFFF;
258 PropertyValue value = static_cast<uint32_t>(val);
259 auto dumpIntf = resDumpEntry;
260
261 if (dumpType == PLDM_FILE_TYPE_DUMP)
262 {
263 dumpIntf = systemDumpEntry;
264 }
265
266 DBusMapping dbusMapping{path.c_str(), dumpIntf, "SourceDumpId",
267 "uint32_t"};
268 try
269 {
270 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
271 }
272 catch (const std::exception& e)
273 {
274 std::cerr << "Failed to make a d-bus call to DUMP "
275 "manager to reset source dump id of "
276 << path.c_str() << ", with ERROR=" << e.what()
277 << "\n";
278 pldm::utils::reportError(
279 "xyz.openbmc_project.bmc.PLDM.fileAck.SourceDumpIdResetFail");
280 return PLDM_ERROR;
281 }
282
283 auto& bus = pldm::utils::DBusHandler::getBus();
284 try
285 {
286 auto method = bus.new_method_call(
287 "xyz.openbmc_project.Dump.Manager", path.c_str(),
288 "xyz.openbmc_project.Object.Delete", "Delete");
289 bus.call(method);
290 }
291 catch (const std::exception& e)
292 {
293 std::cerr
294 << "Failed to make a d-bus method to delete the dump entry "
295 << path.c_str() << ", with ERROR=" << e.what() << "\n";
296 pldm::utils::reportError(
297 "xyz.openbmc_project.bmc.PLDM.fileAck.DumpEntryDeleteFail");
298 return PLDM_ERROR;
299 }
300 return PLDM_SUCCESS;
301 }
302
Jayashankar Padathdb124362021-01-28 21:12:34 -0600303 if (dumpType == PLDM_FILE_TYPE_DUMP ||
304 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600305 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500306 PropertyValue value{true};
307 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
308 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600309 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500310 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600311 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500312 catch (const std::exception& e)
313 {
314 std::cerr
315 << "failed to make a d-bus call to DUMP manager, ERROR="
316 << e.what() << "\n";
317 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500318
Ravi Tejace1c96f2020-10-05 23:13:01 -0500319 auto socketInterface = getOffloadUri(fileHandle);
320 std::remove(socketInterface.c_str());
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500321 if (DumpHandler::fd >= 0)
322 {
323 close(DumpHandler::fd);
324 DumpHandler::fd = -1;
325 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600326 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600327 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600328 }
329
330 return PLDM_ERROR;
331}
332
Jayashankar Padathdb124362021-01-28 21:12:34 -0600333int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
334 uint64_t address,
335 oem_platform::Handler* /*oemPlatformHandler*/)
336{
337 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
338 {
339 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
340 }
341 return transferFileData(resDumpDirPath, true, offset, length, address);
342}
343
344int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
345 oem_platform::Handler* /*oemPlatformHandler*/)
346{
347 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
348 {
349 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
350 }
351 return readFile(resDumpDirPath, offset, length, response);
352}
353
Sampa Misra18967162020-01-14 02:31:41 -0600354} // namespace responder
355} // namespace pldm