blob: 3f031bc8c47359e2f47762313925218745deb79d [file] [log] [blame]
Jayashankar Padathdb124362021-01-28 21:12:34 -06001#include "dbus_to_file_handler.hpp"
2
Andrew Jeffery27a022c2022-08-10 23:12:49 +09303#include "libpldm/file_io.h"
4#include "libpldm/pldm.h"
Jayashankar Padathdb124362021-01-28 21:12:34 -06005
6#include "common/utils.hpp"
7
8namespace pldm
9{
10namespace requester
11{
12namespace oem_ibm
13{
Jayashankar Padathdb124362021-01-28 21:12:34 -060014using namespace pldm::utils;
15using namespace sdbusplus::bus::match::rules;
16
17static constexpr auto resDumpObjPath =
18 "/xyz/openbmc_project/dump/resource/entry";
19static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
20static constexpr auto resDumpProgressIntf =
21 "xyz.openbmc_project.Common.Progress";
22static constexpr auto resDumpStatus =
23 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
24
25DbusToFileHandler::DbusToFileHandler(
26 int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
Sampa Misrac0c79482021-06-02 08:01:54 -050027 sdbusplus::message::object_path resDumpCurrentObjPath,
28 pldm::requester::Handler<pldm::requester::Request>* handler) :
Jayashankar Padathdb124362021-01-28 21:12:34 -060029 mctp_fd(mctp_fd),
30 mctp_eid(mctp_eid), requester(requester),
Sampa Misrac0c79482021-06-02 08:01:54 -050031 resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
Jayashankar Padathdb124362021-01-28 21:12:34 -060032{}
33
34void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
35{
36 if (requester == NULL)
37 {
38 std::cerr << "Failed to send resource dump parameters as requester is "
39 "not set";
40 pldm::utils::reportError(
41 "xyz.openbmc_project.bmc.pldm.InternalFailure");
42 return;
43 }
44 auto instanceId = requester->getInstanceId(mctp_eid);
45 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
Jayashankar Padath79612312022-06-13 12:47:05 -050046 PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060047 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
48 // Need to revisit this logic at the time of multiple resource dump support
49 uint32_t fileHandle = 1;
50
51 auto rc =
52 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
53 fileHandle, fileSize, request);
54 if (rc != PLDM_SUCCESS)
55 {
56 requester->markFree(mctp_eid, instanceId);
57 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
58 return;
59 }
60
Sampa Misrac0c79482021-06-02 08:01:54 -050061 auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
62 const pldm_msg* response,
63 size_t respMsgLen) {
64 if (response == nullptr || !respMsgLen)
65 {
66 std::cerr
67 << "Failed to receive response for NewFileAvailable command \n";
68 return;
69 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060070 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050071 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
72 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060073 {
Sampa Misrac0c79482021-06-02 08:01:54 -050074 std::cerr << "Failed to decode_new_file_resp or"
75 << " Host returned error for new_file_available"
76 << " rc=" << rc
Jayashankar Padathdb124362021-01-28 21:12:34 -060077 << ", cc=" << static_cast<unsigned>(completionCode)
Sampa Misrac0c79482021-06-02 08:01:54 -050078 << "\n";
79 reportResourceDumpFailure();
Jayashankar Padathdb124362021-01-28 21:12:34 -060080 }
Sampa Misrac0c79482021-06-02 08:01:54 -050081 };
82 rc = handler->registerRequest(
83 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
84 std::move(requestMsg), std::move(newFileAvailableRespHandler));
85 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060086 {
Sampa Misrac0c79482021-06-02 08:01:54 -050087 std::cerr << "Failed to send NewFileAvailable Request to Host \n";
88 reportResourceDumpFailure();
89 }
90}
Jayashankar Padathdb124362021-01-28 21:12:34 -060091
Sampa Misrac0c79482021-06-02 08:01:54 -050092void DbusToFileHandler::reportResourceDumpFailure()
93{
Sampa Misrac0c79482021-06-02 08:01:54 -050094 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
95
96 PropertyValue value{resDumpStatus};
97 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
98 "Status", "string"};
99 try
100 {
101 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
102 }
103 catch (const std::exception& e)
104 {
105 std::cerr << "failed to set resource dump operation status, "
106 "ERROR="
107 << e.what() << "\n";
Jayashankar Padathdb124362021-01-28 21:12:34 -0600108 }
109}
110
111void DbusToFileHandler::processNewResourceDump(
112 const std::string& vspString, const std::string& resDumpReqPass)
113{
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600114 try
115 {
116 std::string objPath = resDumpCurrentObjPath;
117 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
118 objPath.c_str(), "Status", resDumpProgressIntf);
119 const auto& curResDumpStatus = std::get<ResDumpStatus>(propVal);
120
121 if (curResDumpStatus !=
122 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress")
123 {
124 return;
125 }
126 }
127 catch (const sdbusplus::exception_t& e)
128 {
129 std::cerr << "Error " << e.what()
130 << " found in getting current resource dump status while "
131 "initiating a new resource dump with objPath="
132 << resDumpCurrentObjPath.str.c_str()
133 << " and intf=" << resDumpProgressIntf << "\n";
134 }
135
Jayashankar Padathdb124362021-01-28 21:12:34 -0600136 namespace fs = std::filesystem;
137 const fs::path resDumpDirPath = "/var/lib/pldm/resourcedump";
138
139 if (!fs::exists(resDumpDirPath))
140 {
141 fs::create_directories(resDumpDirPath);
142 }
143
144 // Need to reconsider this logic to set the value as "1" when we have the
145 // support to handle multiple resource dumps
146 fs::path resDumpFilePath = resDumpDirPath / "1";
147
148 std::ofstream fileHandle;
149 fileHandle.open(resDumpFilePath, std::ios::out | std::ofstream::binary);
150
151 if (!fileHandle)
152 {
153 std::cerr << "resource dump file open error: " << resDumpFilePath
154 << "\n";
155 PropertyValue value{resDumpStatus};
156 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
157 "Status", "string"};
158 try
159 {
160 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
161 }
162 catch (const std::exception& e)
163 {
164 std::cerr << "failed to set resource dump operation status, "
165 "ERROR="
166 << e.what() << "\n";
167 }
168 return;
169 }
170
171 // Fill up the file with resource dump parameters and respective sizes
172 auto fileFunc = [&fileHandle](auto& paramBuf) {
173 uint32_t paramSize = paramBuf.size();
174 fileHandle.write((char*)&paramSize, sizeof(paramSize));
175 fileHandle << paramBuf;
176 };
177 fileFunc(vspString);
178 fileFunc(resDumpReqPass);
179
Pavithra Barithayac047f802021-11-30 01:55:03 -0600180 std::string str;
181 if (!resDumpReqPass.empty())
182 {
183 str = getAcfFileContent();
184 }
185
186 fileFunc(str);
187
Jayashankar Padathdb124362021-01-28 21:12:34 -0600188 fileHandle.close();
189 size_t fileSize = fs::file_size(resDumpFilePath);
190
191 sendNewFileAvailableCmd(fileSize);
192}
193
Pavithra Barithayac047f802021-11-30 01:55:03 -0600194std::string DbusToFileHandler::getAcfFileContent()
195{
196 std::string str;
197 static constexpr auto acfDirPath = "/etc/acf/service.acf";
198 if (fs::exists(acfDirPath))
199 {
200 std::ifstream file;
201 file.open(acfDirPath);
202 std::stringstream acfBuf;
203 acfBuf << file.rdbuf();
204 str = acfBuf.str();
205 file.close();
206 }
207 return str;
208}
209
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500210void DbusToFileHandler::newCsrFileAvailable(const std::string& csr,
211 const std::string fileHandle)
212{
213 namespace fs = std::filesystem;
214 std::string dirPath = "/var/lib/ibm/bmcweb";
215 const fs::path certDirPath = dirPath;
216
217 if (!fs::exists(certDirPath))
218 {
219 fs::create_directories(certDirPath);
220 fs::permissions(certDirPath,
221 fs::perms::others_read | fs::perms::owner_write);
222 }
223
224 fs::path certFilePath = certDirPath / ("CSR_" + fileHandle);
225 std::ofstream certFile;
226
227 certFile.open(certFilePath, std::ios::out | std::ofstream::binary);
228
229 if (!certFile)
230 {
231 std::cerr << "cert file open error: " << certFilePath << "\n";
232 return;
233 }
234
235 // Add csr to file
236 certFile << csr << std::endl;
237
238 certFile.close();
239 uint32_t fileSize = fs::file_size(certFilePath);
240
241 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
242 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
243}
244
245void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
246 const uint32_t fileHandle,
247 const uint16_t type)
248{
249 if (requester == NULL)
250 {
251 std::cerr << "Failed to send csr to host.";
252 pldm::utils::reportError(
253 "xyz.openbmc_project.bmc.pldm.InternalFailure");
254 return;
255 }
256 auto instanceId = requester->getInstanceId(mctp_eid);
257 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
258 PLDM_NEW_FILE_REQ_BYTES);
259 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
260
261 auto rc =
262 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
263 if (rc != PLDM_SUCCESS)
264 {
265 requester->markFree(mctp_eid, instanceId);
266 std::cerr << "Failed to encode_new_file_req, rc = " << rc << std::endl;
267 return;
268 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500269 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
270 const pldm_msg* response,
271 size_t respMsgLen) {
272 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500273 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500274 std::cerr << "Failed to receive response for NewFileAvailable "
275 "command for vmi \n";
276 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500277 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500278 uint8_t completionCode{};
279 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
280 if (rc || completionCode)
281 {
282 std::cerr << "Failed to decode_new_file_resp for vmi, or"
283 << " Host returned error for new_file_available"
284 << " rc=" << rc
285 << ", cc=" << static_cast<unsigned>(completionCode)
286 << "\n";
287 pldm::utils::reportError(
288 "xyz.openbmc_project.bmc.pldm.InternalFailure");
289 }
290 };
291 rc = handler->registerRequest(
292 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
293 std::move(requestMsg), std::move(newFileAvailableRespHandler));
294 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500295 {
Sampa Misrac0c79482021-06-02 08:01:54 -0500296 std::cerr
297 << "Failed to send NewFileAvailable Request to Host for vmi \n";
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500298 pldm::utils::reportError(
299 "xyz.openbmc_project.bmc.pldm.InternalFailure");
300 }
301}
302
Jayashankar Padathdb124362021-01-28 21:12:34 -0600303} // namespace oem_ibm
304} // namespace requester
305} // namespace pldm