blob: 188fc4a6e95d3fc1ff3f60468f98952ef8b26859 [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
Sampa Misra18967162020-01-14 02:31:41 -06006#include "utils.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
9#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>
Sampa Misra18967162020-01-14 02:31:41 -060019
Deepak Kodihallifd279e12020-02-02 05:20:43 -060020using namespace pldm::utils;
21
Sampa Misra18967162020-01-14 02:31:41 -060022namespace pldm
23{
24namespace responder
25{
26
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050027static constexpr auto nbdInterfaceDefault = "/dev/nbd1";
28static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
29static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump";
Sampa Misra18967162020-01-14 02:31:41 -060030
31int DumpHandler::fd = -1;
32
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050033static std::string findDumpObjPath(uint32_t fileHandle)
34{
35 static constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
36 static constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
37 static constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
38 static constexpr auto systemDumpEntry =
39 "xyz.openbmc_project.Dump.Entry.System";
40 auto& bus = pldm::utils::DBusHandler::getBus();
41
42 try
43 {
44 std::vector<std::string> paths;
45 auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
46 MAPPER_INTERFACE, "GetSubTreePaths");
47 method.append(dumpObjPath);
48 method.append(0);
49 method.append(std::vector<std::string>({systemDumpEntry}));
50 auto reply = bus.call(method);
51 reply.read(paths);
52 for (const auto& path : paths)
53 {
54 auto dumpId = pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
55 path.c_str(), "SourceDumpId", systemDumpEntry);
56 if (dumpId == fileHandle)
57 {
58 return path;
59 }
60 }
61 }
62 catch (const std::exception& e)
63 {
64 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
65 << e.what() << "\n";
66 }
67
68 std::cerr << "failed to find dump object for dump id " << fileHandle
69 << "\n";
70 return {};
71}
72
Sampa Misra18967162020-01-14 02:31:41 -060073int DumpHandler::newFileAvailable(uint64_t length)
74{
Sampa Misra18967162020-01-14 02:31:41 -060075 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -060076 auto& bus = pldm::utils::DBusHandler::getBus();
77
78 try
79 {
80 auto service =
81 pldm::utils::DBusHandler().getService(dumpObjPath, dumpInterface);
82 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
83 auto method = bus.new_method_call(service.c_str(), dumpObjPath,
84 dumpInterface, "Notify");
85 method.append(
86 sdbusplus::xyz::openbmc_project::Dump::server::convertForMessage(
87 NewDump::DumpType::System),
88 fileHandle, length);
89 bus.call_noreply(method);
90 }
91 catch (const std::exception& e)
92 {
93 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
94 << e.what() << "\n";
95 return PLDM_ERROR;
96 }
97
98 return PLDM_SUCCESS;
99}
100
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500101static std::string getOffloadUri(uint32_t fileHandle)
102{
103 auto path = findDumpObjPath(fileHandle);
104 if (path.empty())
105 {
106 return {};
107 }
108
109 std::string nbdInterface{};
110 try
111 {
112 nbdInterface = pldm::utils::DBusHandler().getDbusProperty<std::string>(
113 path.c_str(), "OffloadUri", dumpEntry);
114 }
115 catch (const std::exception& e)
116 {
117 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
118 << e.what() << "\n";
119 }
120
121 if (nbdInterface == "")
122 {
123 nbdInterface = nbdInterfaceDefault;
124 }
125
126 return nbdInterface;
127}
128
Sampa Misra18967162020-01-14 02:31:41 -0600129int DumpHandler::writeFromMemory(uint32_t offset, uint32_t length,
130 uint64_t address)
131{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500132 auto nbdInterface = getOffloadUri(fileHandle);
133 if (nbdInterface.empty())
134 {
135 return PLDM_ERROR;
136 }
Sampa Misra18967162020-01-14 02:31:41 -0600137
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500138 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
Sampa Misra18967162020-01-14 02:31:41 -0600139 if (DumpHandler::fd == -1)
140 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500141 DumpHandler::fd = open(nbdInterface.c_str(), flags);
Sampa Misra18967162020-01-14 02:31:41 -0600142 if (DumpHandler::fd == -1)
143 {
144 std::cerr << "NBD file does not exist at " << nbdInterface
145 << " ERROR=" << errno << "\n";
146 return PLDM_ERROR;
147 }
148 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500149
Sampa Misra18967162020-01-14 02:31:41 -0600150 return transferFileData(DumpHandler::fd, false, offset, length, address);
151}
152
153int DumpHandler::write(const char* buffer, uint32_t offset, uint32_t& length)
154{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500155 auto nbdInterface = getOffloadUri(fileHandle);
156 if (nbdInterface.empty())
157 {
158 return PLDM_ERROR;
159 }
160
Sampa Misra18967162020-01-14 02:31:41 -0600161 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
162 if (DumpHandler::fd == -1)
163 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500164 DumpHandler::fd = open(nbdInterface.c_str(), flags);
Sampa Misra18967162020-01-14 02:31:41 -0600165 if (DumpHandler::fd == -1)
166 {
167 std::cerr << "NBD file does not exist at " << nbdInterface
168 << " ERROR=" << errno << "\n";
169 return PLDM_ERROR;
170 }
171 }
172
173 int rc = lseek(DumpHandler::fd, offset, SEEK_SET);
174 if (rc == -1)
175 {
176 std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
177 << "\n";
178 return PLDM_ERROR;
179 }
180 rc = ::write(DumpHandler::fd, buffer, length);
181 if (rc == -1)
182 {
183 std::cerr << "file write failed, ERROR=" << errno
184 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
185 return PLDM_ERROR;
186 }
187 length = rc;
188
189 return PLDM_SUCCESS;
190}
191
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600192int DumpHandler::fileAck(uint8_t /*fileStatus*/)
193{
194 if (DumpHandler::fd >= 0)
195 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500196 auto path = findDumpObjPath(fileHandle);
197 if (!path.empty())
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600198 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500199 PropertyValue value{true};
200 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
201 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600202 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500203 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600204 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500205 catch (const std::exception& e)
206 {
207 std::cerr
208 << "failed to make a d-bus call to DUMP manager, ERROR="
209 << e.what() << "\n";
210 }
211 close(DumpHandler::fd);
212 DumpHandler::fd = -1;
213 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600214 }
215 }
216
217 return PLDM_ERROR;
218}
219
Sampa Misra18967162020-01-14 02:31:41 -0600220} // namespace responder
221} // namespace pldm