blob: 37cbb56e3810be42e4658dc2c0a9d52301f4c064 [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
240 if (DumpHandler::fd >= 0 && !path.empty())
241 {
242 if (dumpType == PLDM_FILE_TYPE_DUMP ||
243 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600244 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500245 PropertyValue value{true};
246 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
247 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600248 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500249 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600250 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500251 catch (const std::exception& e)
252 {
253 std::cerr
254 << "failed to make a d-bus call to DUMP manager, ERROR="
255 << e.what() << "\n";
256 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500257
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500258 close(DumpHandler::fd);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500259 auto socketInterface = getOffloadUri(fileHandle);
260 std::remove(socketInterface.c_str());
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500261 DumpHandler::fd = -1;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600262 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600263 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600264 }
265
266 return PLDM_ERROR;
267}
268
Jayashankar Padathdb124362021-01-28 21:12:34 -0600269int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
270 uint64_t address,
271 oem_platform::Handler* /*oemPlatformHandler*/)
272{
273 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
274 {
275 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
276 }
277 return transferFileData(resDumpDirPath, true, offset, length, address);
278}
279
280int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
281 oem_platform::Handler* /*oemPlatformHandler*/)
282{
283 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
284 {
285 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
286 }
287 return readFile(resDumpDirPath, offset, length, response);
288}
289
Sampa Misra18967162020-01-14 02:31:41 -0600290} // namespace responder
291} // namespace pldm