blob: 8572259a3bb5d69b3bc2f2f81d2e95de301970d2 [file] [log] [blame]
Sampa Misra18967162020-01-14 02:31:41 -06001#include "file_io_type_dump.hpp"
2
3#include "utils.hpp"
4#include "xyz/openbmc_project/Common/error.hpp"
5
6#include <stdint.h>
7#include <systemd/sd-bus.h>
8#include <unistd.h>
9
10#include <exception>
11#include <filesystem>
12#include <iostream>
13#include <sdbusplus/server.hpp>
14#include <xyz/openbmc_project/Dump/NewDump/server.hpp>
15
16#include "libpldm/base.h"
17#include "oem/ibm/libpldm/file_io.h"
18
Deepak Kodihallifd279e12020-02-02 05:20:43 -060019using namespace pldm::utils;
20
Sampa Misra18967162020-01-14 02:31:41 -060021namespace pldm
22{
23namespace responder
24{
25
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050026static constexpr auto nbdInterfaceDefault = "/dev/nbd1";
27static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
28static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump";
Sampa Misra18967162020-01-14 02:31:41 -060029
30int DumpHandler::fd = -1;
31
Deepak Kodihalli8cd60682020-04-02 02:59:22 -050032static std::string findDumpObjPath(uint32_t fileHandle)
33{
34 static constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
35 static constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
36 static constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
37 static constexpr auto systemDumpEntry =
38 "xyz.openbmc_project.Dump.Entry.System";
39 auto& bus = pldm::utils::DBusHandler::getBus();
40
41 try
42 {
43 std::vector<std::string> paths;
44 auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
45 MAPPER_INTERFACE, "GetSubTreePaths");
46 method.append(dumpObjPath);
47 method.append(0);
48 method.append(std::vector<std::string>({systemDumpEntry}));
49 auto reply = bus.call(method);
50 reply.read(paths);
51 for (const auto& path : paths)
52 {
53 auto dumpId = pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
54 path.c_str(), "SourceDumpId", systemDumpEntry);
55 if (dumpId == fileHandle)
56 {
57 return path;
58 }
59 }
60 }
61 catch (const std::exception& e)
62 {
63 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
64 << e.what() << "\n";
65 }
66
67 std::cerr << "failed to find dump object for dump id " << fileHandle
68 << "\n";
69 return {};
70}
71
Sampa Misra18967162020-01-14 02:31:41 -060072int DumpHandler::newFileAvailable(uint64_t length)
73{
Sampa Misra18967162020-01-14 02:31:41 -060074 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
Sampa Misra18967162020-01-14 02:31:41 -060075 auto& bus = pldm::utils::DBusHandler::getBus();
76
77 try
78 {
79 auto service =
80 pldm::utils::DBusHandler().getService(dumpObjPath, dumpInterface);
81 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
82 auto method = bus.new_method_call(service.c_str(), dumpObjPath,
83 dumpInterface, "Notify");
84 method.append(
85 sdbusplus::xyz::openbmc_project::Dump::server::convertForMessage(
86 NewDump::DumpType::System),
87 fileHandle, length);
88 bus.call_noreply(method);
89 }
90 catch (const std::exception& e)
91 {
92 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
93 << e.what() << "\n";
94 return PLDM_ERROR;
95 }
96
97 return PLDM_SUCCESS;
98}
99
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500100static std::string getOffloadUri(uint32_t fileHandle)
101{
102 auto path = findDumpObjPath(fileHandle);
103 if (path.empty())
104 {
105 return {};
106 }
107
108 std::string nbdInterface{};
109 try
110 {
111 nbdInterface = pldm::utils::DBusHandler().getDbusProperty<std::string>(
112 path.c_str(), "OffloadUri", dumpEntry);
113 }
114 catch (const std::exception& e)
115 {
116 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
117 << e.what() << "\n";
118 }
119
120 if (nbdInterface == "")
121 {
122 nbdInterface = nbdInterfaceDefault;
123 }
124
125 return nbdInterface;
126}
127
Sampa Misra18967162020-01-14 02:31:41 -0600128int DumpHandler::writeFromMemory(uint32_t offset, uint32_t length,
129 uint64_t address)
130{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500131 auto nbdInterface = getOffloadUri(fileHandle);
132 if (nbdInterface.empty())
133 {
134 return PLDM_ERROR;
135 }
Sampa Misra18967162020-01-14 02:31:41 -0600136
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500137 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
Sampa Misra18967162020-01-14 02:31:41 -0600138 if (DumpHandler::fd == -1)
139 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500140 DumpHandler::fd = open(nbdInterface.c_str(), flags);
Sampa Misra18967162020-01-14 02:31:41 -0600141 if (DumpHandler::fd == -1)
142 {
143 std::cerr << "NBD file does not exist at " << nbdInterface
144 << " ERROR=" << errno << "\n";
145 return PLDM_ERROR;
146 }
147 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500148
Sampa Misra18967162020-01-14 02:31:41 -0600149 return transferFileData(DumpHandler::fd, false, offset, length, address);
150}
151
152int DumpHandler::write(const char* buffer, uint32_t offset, uint32_t& length)
153{
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500154 auto nbdInterface = getOffloadUri(fileHandle);
155 if (nbdInterface.empty())
156 {
157 return PLDM_ERROR;
158 }
159
Sampa Misra18967162020-01-14 02:31:41 -0600160 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
161 if (DumpHandler::fd == -1)
162 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500163 DumpHandler::fd = open(nbdInterface.c_str(), flags);
Sampa Misra18967162020-01-14 02:31:41 -0600164 if (DumpHandler::fd == -1)
165 {
166 std::cerr << "NBD file does not exist at " << nbdInterface
167 << " ERROR=" << errno << "\n";
168 return PLDM_ERROR;
169 }
170 }
171
172 int rc = lseek(DumpHandler::fd, offset, SEEK_SET);
173 if (rc == -1)
174 {
175 std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
176 << "\n";
177 return PLDM_ERROR;
178 }
179 rc = ::write(DumpHandler::fd, buffer, length);
180 if (rc == -1)
181 {
182 std::cerr << "file write failed, ERROR=" << errno
183 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
184 return PLDM_ERROR;
185 }
186 length = rc;
187
188 return PLDM_SUCCESS;
189}
190
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600191int DumpHandler::fileAck(uint8_t /*fileStatus*/)
192{
193 if (DumpHandler::fd >= 0)
194 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500195 auto path = findDumpObjPath(fileHandle);
196 if (!path.empty())
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600197 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500198 PropertyValue value{true};
199 DBusMapping dbusMapping{path, dumpEntry, "Offloaded", "bool"};
200 try
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600201 {
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500202 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600203 }
Deepak Kodihalli8cd60682020-04-02 02:59:22 -0500204 catch (const std::exception& e)
205 {
206 std::cerr
207 << "failed to make a d-bus call to DUMP manager, ERROR="
208 << e.what() << "\n";
209 }
210 close(DumpHandler::fd);
211 DumpHandler::fd = -1;
212 return PLDM_SUCCESS;
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600213 }
214 }
215
216 return PLDM_ERROR;
217}
218
Sampa Misra18967162020-01-14 02:31:41 -0600219} // namespace responder
220} // namespace pldm