blob: ffb1d886c998cce4d28187cecc043fe71e81a699 [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"
4#include "oem/ibm/libpldm/file_io.h"
5
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{
29
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050030static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
Deepak Kodihalli14b54a32020-09-29 05:20:02 -050031static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump/system";
Jayashankar Padathdb124362021-01-28 21:12:34 -060032static constexpr auto systemDumpEntry = "xyz.openbmc_project.Dump.Entry.System";
33static constexpr auto resDumpObjPath = "/xyz/openbmc_project/dump/resource";
34static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
Sampa Misra18967162020-01-14 02:31:41 -060035
Jayashankar Padathdb124362021-01-28 21:12:34 -060036// Resource dump file path to be deleted once hyperviosr validates the input
37// parameters. Need to re-look in to this name when we support multiple
38// resource dumps.
39static constexpr auto resDumpDirPath = "/var/lib/pldm/resourcedump/1";
40
41int DumpHandler::fd = -1;
42namespace fs = std::filesystem;
43
44std::string DumpHandler::findDumpObjPath(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050045{
46 static constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
47 static constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
48 static constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
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
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050054 try
55 {
56 std::vector<std::string> paths;
57 auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
58 MAPPER_INTERFACE, "GetSubTreePaths");
Jayashankar Padathdb124362021-01-28 21:12:34 -060059 if (dumpType == PLDM_FILE_TYPE_DUMP)
60 {
61 method.append(dumpObjPath);
62 method.append(0);
63 method.append(std::vector<std::string>({systemDumpEntry}));
64 }
65 else if ((dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP) ||
66 (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS))
67 {
68 method.append(resDumpObjPath);
69 method.append(0);
70 method.append(std::vector<std::string>({resDumpEntry}));
71 }
72
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050073 auto reply = bus.call(method);
74 reply.read(paths);
Jayashankar Padathdb124362021-01-28 21:12:34 -060075
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050076 for (const auto& path : paths)
77 {
Jayashankar Padathdb124362021-01-28 21:12:34 -060078 uint32_t dumpId = 0;
79 curResDumpEntryPath = path;
80 if (dumpType == PLDM_FILE_TYPE_DUMP)
81 {
82 dumpId = pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
83 path.c_str(), "SourceDumpId", systemDumpEntry);
84 }
85 else if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP ||
86 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
87 {
88 dumpId = pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
89 path.c_str(), "SourceDumpId", resDumpEntry);
90 }
91
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050092 if (dumpId == fileHandle)
93 {
Jayashankar Padathdb124362021-01-28 21:12:34 -060094 curResDumpEntryPath = path;
95 break;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050096 }
97 }
98 }
99 catch (const std::exception& e)
100 {
101 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
102 << e.what() << "\n";
103 }
104
Jayashankar Padathdb124362021-01-28 21:12:34 -0600105 return curResDumpEntryPath;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500106}
107
Sampa Misra18967162020-01-14 02:31:41 -0600108int DumpHandler::newFileAvailable(uint64_t length)
109{
Sampa Misra18967162020-01-14 02:31:41 -0600110 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -0600111 auto& bus = pldm::utils::DBusHandler::getBus();
112
Jayashankar Padathdb124362021-01-28 21:12:34 -0600113 auto notifyObjPath = dumpObjPath;
114 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
115 {
116 // Setting the Notify path for resource dump
117 notifyObjPath = resDumpObjPath;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600118 }
119
Sampa Misra18967162020-01-14 02:31:41 -0600120 try
121 {
122 auto service =
Jayashankar Padathdb124362021-01-28 21:12:34 -0600123 pldm::utils::DBusHandler().getService(notifyObjPath, dumpInterface);
Sampa Misra18967162020-01-14 02:31:41 -0600124 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600125 auto method = bus.new_method_call(service.c_str(), notifyObjPath,
Sampa Misra18967162020-01-14 02:31:41 -0600126 dumpInterface, "Notify");
Dhruvaraj Subhashchandran41989eb2020-11-27 00:22:42 -0600127 method.append(fileHandle, length);
Sampa Misra18967162020-01-14 02:31:41 -0600128 bus.call_noreply(method);
129 }
130 catch (const std::exception& e)
131 {
132 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
133 << e.what() << "\n";
134 return PLDM_ERROR;
135 }
136
137 return PLDM_SUCCESS;
138}
139
Jayashankar Padathdb124362021-01-28 21:12:34 -0600140std::string DumpHandler::getOffloadUri(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500141{
142 auto path = findDumpObjPath(fileHandle);
143 if (path.empty())
144 {
145 return {};
146 }
147
Ravi Tejace1c96f2020-10-05 23:13:01 -0500148 std::string socketInterface{};
149
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500150 try
151 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500152 socketInterface =
153 pldm::utils::DBusHandler().getDbusProperty<std::string>(
154 path.c_str(), "OffloadUri", dumpEntry);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500155 }
156 catch (const std::exception& e)
157 {
158 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
159 << e.what() << "\n";
160 }
161
Ravi Tejace1c96f2020-10-05 23:13:01 -0500162 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500163}
164
Jayashankar Padathdb124362021-01-28 21:12:34 -0600165int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500166 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600167{
Sampa Misra18967162020-01-14 02:31:41 -0600168 if (DumpHandler::fd == -1)
169 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500170 auto socketInterface = getOffloadUri(fileHandle);
171 int sock = setupUnixSocket(socketInterface);
172 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600173 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500174 sock = -errno;
175 close(DumpHandler::fd);
176 std::cerr
177 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
178 << std::endl;
179 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600180 return PLDM_ERROR;
181 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500182
Ravi Tejace1c96f2020-10-05 23:13:01 -0500183 DumpHandler::fd = sock;
184 }
185 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600186}
187
Jayashankar Padathdb124362021-01-28 21:12:34 -0600188int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500189 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600190{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500191 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
192 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500193 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500194 rc = -errno;
195 close(DumpHandler::fd);
196 auto socketInterface = getOffloadUri(fileHandle);
197 std::remove(socketInterface.c_str());
198 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
199 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500200 return PLDM_ERROR;
201 }
202
Sampa Misra18967162020-01-14 02:31:41 -0600203 return PLDM_SUCCESS;
204}
205
Jayashankar Padathdb124362021-01-28 21:12:34 -0600206int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600207{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600208 auto path = findDumpObjPath(fileHandle);
209 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600210 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600211 if (fileStatus != PLDM_SUCCESS)
212 {
213 std::cerr << "Failue in resource dump file ack" << std::endl;
214 pldm::utils::reportError(
215 "xyz.openbmc_project.bmc.pldm.InternalFailure");
216
217 PropertyValue value{
218 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
219 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
220 "Status", "string"};
221 try
222 {
223 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
224 }
225 catch (const std::exception& e)
226 {
227 std::cerr << "failed to make a d-bus call to DUMP "
228 "manager, ERROR="
229 << e.what() << "\n";
230 }
231 }
232
233 if (fs::exists(resDumpDirPath))
234 {
235 fs::remove_all(resDumpDirPath);
236 }
237 return PLDM_SUCCESS;
238 }
239
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500240 if (!path.empty())
Jayashankar Padathdb124362021-01-28 21:12:34 -0600241 {
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500242 if (fileStatus == PLDM_ERROR_FILE_DISCARDED)
243 {
244 uint32_t val = 0xFFFFFFFF;
245 PropertyValue value = static_cast<uint32_t>(val);
246 auto dumpIntf = resDumpEntry;
247
248 if (dumpType == PLDM_FILE_TYPE_DUMP)
249 {
250 dumpIntf = systemDumpEntry;
251 }
252
253 DBusMapping dbusMapping{path.c_str(), dumpIntf, "SourceDumpId",
254 "uint32_t"};
255 try
256 {
257 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
258 }
259 catch (const std::exception& e)
260 {
261 std::cerr << "Failed to make a d-bus call to DUMP "
262 "manager to reset source dump id of "
263 << path.c_str() << ", with ERROR=" << e.what()
264 << "\n";
265 pldm::utils::reportError(
266 "xyz.openbmc_project.bmc.PLDM.fileAck.SourceDumpIdResetFail");
267 return PLDM_ERROR;
268 }
269
270 auto& bus = pldm::utils::DBusHandler::getBus();
271 try
272 {
273 auto method = bus.new_method_call(
274 "xyz.openbmc_project.Dump.Manager", path.c_str(),
275 "xyz.openbmc_project.Object.Delete", "Delete");
276 bus.call(method);
277 }
278 catch (const std::exception& e)
279 {
280 std::cerr
281 << "Failed to make a d-bus method to delete the dump entry "
282 << path.c_str() << ", with ERROR=" << e.what() << "\n";
283 pldm::utils::reportError(
284 "xyz.openbmc_project.bmc.PLDM.fileAck.DumpEntryDeleteFail");
285 return PLDM_ERROR;
286 }
287 return PLDM_SUCCESS;
288 }
289
Jayashankar Padathdb124362021-01-28 21:12:34 -0600290 if (dumpType == PLDM_FILE_TYPE_DUMP ||
291 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600292 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500293 PropertyValue value{true};
294 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
295 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600296 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500297 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600298 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500299 catch (const std::exception& e)
300 {
301 std::cerr
302 << "failed to make a d-bus call to DUMP manager, ERROR="
303 << e.what() << "\n";
304 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500305
Ravi Tejace1c96f2020-10-05 23:13:01 -0500306 auto socketInterface = getOffloadUri(fileHandle);
307 std::remove(socketInterface.c_str());
Jayashankar Padath6289ea12022-06-13 12:33:10 -0500308 if (DumpHandler::fd >= 0)
309 {
310 close(DumpHandler::fd);
311 DumpHandler::fd = -1;
312 }
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600313 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600314 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600315 }
316
317 return PLDM_ERROR;
318}
319
Jayashankar Padathdb124362021-01-28 21:12:34 -0600320int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
321 uint64_t address,
322 oem_platform::Handler* /*oemPlatformHandler*/)
323{
324 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
325 {
326 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
327 }
328 return transferFileData(resDumpDirPath, true, offset, length, address);
329}
330
331int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
332 oem_platform::Handler* /*oemPlatformHandler*/)
333{
334 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
335 {
336 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
337 }
338 return readFile(resDumpDirPath, offset, length, response);
339}
340
Sampa Misra18967162020-01-14 02:31:41 -0600341} // namespace responder
342} // namespace pldm