blob: 9fe270ac66f7c0df8ad5fc5ec485d5062e83f9c0 [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
26static constexpr auto nbdInterface = "/dev/nbd1";
27
28int DumpHandler::fd = -1;
29
30int DumpHandler::newFileAvailable(uint64_t length)
31{
32 static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump";
33 static constexpr auto dumpInterface = "xyz.openbmc_project.Dump.NewDump";
34
35 auto& bus = pldm::utils::DBusHandler::getBus();
36
37 try
38 {
39 auto service =
40 pldm::utils::DBusHandler().getService(dumpObjPath, dumpInterface);
41 using namespace sdbusplus::xyz::openbmc_project::Dump::server;
42 auto method = bus.new_method_call(service.c_str(), dumpObjPath,
43 dumpInterface, "Notify");
44 method.append(
45 sdbusplus::xyz::openbmc_project::Dump::server::convertForMessage(
46 NewDump::DumpType::System),
47 fileHandle, length);
48 bus.call_noreply(method);
49 }
50 catch (const std::exception& e)
51 {
52 std::cerr << "failed to make a d-bus call to DUMP manager, ERROR="
53 << e.what() << "\n";
54 return PLDM_ERROR;
55 }
56
57 return PLDM_SUCCESS;
58}
59
60int DumpHandler::writeFromMemory(uint32_t offset, uint32_t length,
61 uint64_t address)
62{
63 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
64
65 if (DumpHandler::fd == -1)
66 {
67 DumpHandler::fd = open(nbdInterface, flags);
68 if (DumpHandler::fd == -1)
69 {
70 std::cerr << "NBD file does not exist at " << nbdInterface
71 << " ERROR=" << errno << "\n";
72 return PLDM_ERROR;
73 }
74 }
75 return transferFileData(DumpHandler::fd, false, offset, length, address);
76}
77
78int DumpHandler::write(const char* buffer, uint32_t offset, uint32_t& length)
79{
80 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE;
81 if (DumpHandler::fd == -1)
82 {
83 DumpHandler::fd = open(nbdInterface, flags);
84 if (DumpHandler::fd == -1)
85 {
86 std::cerr << "NBD file does not exist at " << nbdInterface
87 << " ERROR=" << errno << "\n";
88 return PLDM_ERROR;
89 }
90 }
91
92 int rc = lseek(DumpHandler::fd, offset, SEEK_SET);
93 if (rc == -1)
94 {
95 std::cerr << "lseek failed, ERROR=" << errno << ", OFFSET=" << offset
96 << "\n";
97 return PLDM_ERROR;
98 }
99 rc = ::write(DumpHandler::fd, buffer, length);
100 if (rc == -1)
101 {
102 std::cerr << "file write failed, ERROR=" << errno
103 << ", LENGTH=" << length << ", OFFSET=" << offset << "\n";
104 return PLDM_ERROR;
105 }
106 length = rc;
107
108 return PLDM_SUCCESS;
109}
110
Deepak Kodihallifd279e12020-02-02 05:20:43 -0600111int DumpHandler::fileAck(uint8_t /*fileStatus*/)
112{
113 if (DumpHandler::fd >= 0)
114 {
115 static constexpr auto dumpObjPath = "/xyz/openbmc_project/dump";
116 static constexpr auto MAPPER_BUSNAME =
117 "xyz.openbmc_project.ObjectMapper";
118 static constexpr auto MAPPER_PATH =
119 "/xyz/openbmc_project/object_mapper";
120 static constexpr auto MAPPER_INTERFACE =
121 "xyz.openbmc_project.ObjectMapper";
122 static constexpr auto systemDumpEntry =
123 "xyz.openbmc_project.Dump.Entry.System";
124 static constexpr auto dumpEntry = "xyz.openbmc_project.Dump.Entry";
125 auto& bus = pldm::utils::DBusHandler::getBus();
126
127 try
128 {
129 std::vector<std::string> paths;
130 auto method =
131 bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
132 MAPPER_INTERFACE, "GetSubTreePaths");
133 method.append(dumpObjPath);
134 method.append(0);
135 method.append(std::vector<std::string>({systemDumpEntry}));
136 auto reply = bus.call(method);
137 reply.read(paths);
138 for (auto path : paths)
139 {
140 uint32_t dumpId =
141 pldm::utils::DBusHandler().getDbusProperty<uint32_t>(
142 path.c_str(), "SourceDumpId", systemDumpEntry);
143 if (dumpId == fileHandle)
144 {
145 PropertyValue value{true};
146 DBusMapping dbusMapping{path, dumpEntry, "Offloaded",
147 "bool"};
148 pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
149 value);
150 close(DumpHandler::fd);
151 DumpHandler::fd = -1;
152 return PLDM_SUCCESS;
153 }
154 }
155 }
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 }
162
163 return PLDM_ERROR;
164}
165
Sampa Misra18967162020-01-14 02:31:41 -0600166} // namespace responder
167} // namespace pldm