blob: 985a27826ba31924b1ac945227e8f36e55d78658 [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;
118
119 uint32_t sourceDumpId = fileHandle;
120 auto path = findDumpObjPath(fileHandle);
121
122 pldm::utils::PropertyValue propValue{sourceDumpId};
123
124 DBusMapping dbusMapping{path, resDumpEntry, "SourceDumpId", "uint32_t"};
125 try
126 {
127 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue);
128 }
129 catch (const std::exception& e)
130 {
131 std::cerr << "failed to make a d-bus call to DUMP manager to set "
132 "resource dump SourceDumpId, ERROR="
133 << e.what() << "\n";
134 }
135 }
136
Sampa Misra18967162020-01-14 02:31:41 -0600137 try
138 {
139 auto service =
Jayashankar Padathdb124362021-01-28 21:12:34 -0600140 pldm::utils::DBusHandler().getService(notifyObjPath, dumpInterface);
Sampa Misra18967162020-01-14 02:31:41 -0600141 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
Jayashankar Padathdb124362021-01-28 21:12:34 -0600142 auto method = bus.new_method_call(service.c_str(), notifyObjPath,
Sampa Misra18967162020-01-14 02:31:41 -0600143 dumpInterface, "Notify");
Dhruvaraj Subhashchandran41989eb2020-11-27 00:22:42 -0600144 method.append(fileHandle, length);
Sampa Misra18967162020-01-14 02:31:41 -0600145 bus.call_noreply(method);
146 }
147 catch (const std::exception& e)
148 {
149 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
150 << e.what() << "\n";
151 return PLDM_ERROR;
152 }
153
154 return PLDM_SUCCESS;
155}
156
Jayashankar Padathdb124362021-01-28 21:12:34 -0600157std::string DumpHandler::getOffloadUri(uint32_t fileHandle)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500158{
159 auto path = findDumpObjPath(fileHandle);
160 if (path.empty())
161 {
162 return {};
163 }
164
Ravi Tejace1c96f2020-10-05 23:13:01 -0500165 std::string socketInterface{};
166
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500167 try
168 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500169 socketInterface =
170 pldm::utils::DBusHandler().getDbusProperty<std::string>(
171 path.c_str(), "OffloadUri", dumpEntry);
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500172 }
173 catch (const std::exception& e)
174 {
175 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
176 << e.what() << "\n";
177 }
178
Ravi Tejace1c96f2020-10-05 23:13:01 -0500179 return socketInterface;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500180}
181
Jayashankar Padathdb124362021-01-28 21:12:34 -0600182int DumpHandler::writeFromMemory(uint32_t, uint32_t length, uint64_t address,
Sampa Misra69508502020-09-08 00:08:21 -0500183 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600184{
Sampa Misra18967162020-01-14 02:31:41 -0600185 if (DumpHandler::fd == -1)
186 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500187 auto socketInterface = getOffloadUri(fileHandle);
188 int sock = setupUnixSocket(socketInterface);
189 if (sock < 0)
Sampa Misra18967162020-01-14 02:31:41 -0600190 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500191 sock = -errno;
192 close(DumpHandler::fd);
193 std::cerr
194 << "DumpHandler::writeFromMemory: setupUnixSocket() failed"
195 << std::endl;
196 std::remove(socketInterface.c_str());
Sampa Misra18967162020-01-14 02:31:41 -0600197 return PLDM_ERROR;
198 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500199
Ravi Tejace1c96f2020-10-05 23:13:01 -0500200 DumpHandler::fd = sock;
201 }
202 return transferFileDataToSocket(DumpHandler::fd, length, address);
Sampa Misra18967162020-01-14 02:31:41 -0600203}
204
Jayashankar Padathdb124362021-01-28 21:12:34 -0600205int DumpHandler::write(const char* buffer, uint32_t, uint32_t& length,
Sampa Misra69508502020-09-08 00:08:21 -0500206 oem_platform::Handler* /*oemPlatformHandler*/)
Sampa Misra18967162020-01-14 02:31:41 -0600207{
Ravi Tejace1c96f2020-10-05 23:13:01 -0500208 int rc = writeToUnixSocket(DumpHandler::fd, buffer, length);
209 if (rc < 0)
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500210 {
Ravi Tejace1c96f2020-10-05 23:13:01 -0500211 rc = -errno;
212 close(DumpHandler::fd);
213 auto socketInterface = getOffloadUri(fileHandle);
214 std::remove(socketInterface.c_str());
215 std::cerr << "DumpHandler::write: writeToUnixSocket() failed"
216 << std::endl;
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500217 return PLDM_ERROR;
218 }
219
Sampa Misra18967162020-01-14 02:31:41 -0600220 return PLDM_SUCCESS;
221}
222
Jayashankar Padathdb124362021-01-28 21:12:34 -0600223int DumpHandler::fileAck(uint8_t fileStatus)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600224{
Jayashankar Padathdb124362021-01-28 21:12:34 -0600225 auto path = findDumpObjPath(fileHandle);
226 if (dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600227 {
Jayashankar Padathdb124362021-01-28 21:12:34 -0600228 if (fileStatus != PLDM_SUCCESS)
229 {
230 std::cerr << "Failue in resource dump file ack" << std::endl;
231 pldm::utils::reportError(
232 "xyz.openbmc_project.bmc.pldm.InternalFailure");
233
234 PropertyValue value{
235 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed"};
236 DBusMapping dbusMapping{path, "xyz.openbmc_project.Common.Progress",
237 "Status", "string"};
238 try
239 {
240 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
241 }
242 catch (const std::exception& e)
243 {
244 std::cerr << "failed to make a d-bus call to DUMP "
245 "manager, ERROR="
246 << e.what() << "\n";
247 }
248 }
249
250 if (fs::exists(resDumpDirPath))
251 {
252 fs::remove_all(resDumpDirPath);
253 }
254 return PLDM_SUCCESS;
255 }
256
257 if (DumpHandler::fd >= 0 && !path.empty())
258 {
259 if (dumpType == PLDM_FILE_TYPE_DUMP ||
260 dumpType == PLDM_FILE_TYPE_RESOURCE_DUMP)
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600261 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500262 PropertyValue value{true};
263 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
264 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600265 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500266 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600267 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500268 catch (const std::exception& e)
269 {
270 std::cerr
271 << "failed to make a d-bus call to DUMP manager, ERROR="
272 << e.what() << "\n";
273 }
Ravi Tejace1c96f2020-10-05 23:13:01 -0500274
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500275 close(DumpHandler::fd);
Ravi Tejace1c96f2020-10-05 23:13:01 -0500276 auto socketInterface = getOffloadUri(fileHandle);
277 std::remove(socketInterface.c_str());
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500278 DumpHandler::fd = -1;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600279 }
Jayashankar Padathdb124362021-01-28 21:12:34 -0600280 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600281 }
282
283 return PLDM_ERROR;
284}
285
Jayashankar Padathdb124362021-01-28 21:12:34 -0600286int DumpHandler::readIntoMemory(uint32_t offset, uint32_t& length,
287 uint64_t address,
288 oem_platform::Handler* /*oemPlatformHandler*/)
289{
290 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
291 {
292 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
293 }
294 return transferFileData(resDumpDirPath, true, offset, length, address);
295}
296
297int DumpHandler::read(uint32_t offset, uint32_t& length, Response& response,
298 oem_platform::Handler* /*oemPlatformHandler*/)
299{
300 if (dumpType != PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS)
301 {
302 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
303 }
304 return readFile(resDumpDirPath, offset, length, response);
305}
306
Sampa Misra18967162020-01-14 02:31:41 -0600307} // namespace responder
308} // namespace pldm