blob: ff632b955708d5fe103567c2b86aef76d305e817 [file] [log] [blame]
Jayashankar Padathdb124362021-01-28 21:12:34 -06001#include "dbus_to_file_handler.hpp"
2
Jayashankar Padathdb124362021-01-28 21:12:34 -06003#include "common/utils.hpp"
4
George Liuc453e162022-12-21 17:16:23 +08005#include <libpldm/file_io.h>
6#include <libpldm/pldm.h>
7
Riya Dixit49cfb132023-03-02 04:26:53 -06008#include <phosphor-logging/lg2.hpp>
9
10PHOSPHOR_LOG2_USING;
11
Jayashankar Padathdb124362021-01-28 21:12:34 -060012namespace pldm
13{
14namespace requester
15{
16namespace oem_ibm
17{
Jayashankar Padathdb124362021-01-28 21:12:34 -060018using namespace pldm::utils;
19using namespace sdbusplus::bus::match::rules;
20
21static constexpr auto resDumpObjPath =
22 "/xyz/openbmc_project/dump/resource/entry";
23static constexpr auto resDumpEntry = "com.ibm.Dump.Entry.Resource";
24static constexpr auto resDumpProgressIntf =
25 "xyz.openbmc_project.Common.Progress";
26static constexpr auto resDumpStatus =
27 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed";
28
29DbusToFileHandler::DbusToFileHandler(
30 int mctp_fd, uint8_t mctp_eid, dbus_api::Requester* requester,
Sampa Misrac0c79482021-06-02 08:01:54 -050031 sdbusplus::message::object_path resDumpCurrentObjPath,
32 pldm::requester::Handler<pldm::requester::Request>* handler) :
Jayashankar Padathdb124362021-01-28 21:12:34 -060033 mctp_fd(mctp_fd),
34 mctp_eid(mctp_eid), requester(requester),
Sampa Misrac0c79482021-06-02 08:01:54 -050035 resDumpCurrentObjPath(resDumpCurrentObjPath), handler(handler)
Jayashankar Padathdb124362021-01-28 21:12:34 -060036{}
37
38void DbusToFileHandler::sendNewFileAvailableCmd(uint64_t fileSize)
39{
40 if (requester == NULL)
41 {
Riya Dixit49cfb132023-03-02 04:26:53 -060042 error(
43 "Failed to send resource dump parameters as requester is not set");
Jayashankar Padathdb124362021-01-28 21:12:34 -060044 pldm::utils::reportError(
45 "xyz.openbmc_project.bmc.pldm.InternalFailure");
46 return;
47 }
48 auto instanceId = requester->getInstanceId(mctp_eid);
49 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
Jayashankar Padath79612312022-06-13 12:47:05 -050050 PLDM_NEW_FILE_REQ_BYTES);
Jayashankar Padathdb124362021-01-28 21:12:34 -060051 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
52 // Need to revisit this logic at the time of multiple resource dump support
53 uint32_t fileHandle = 1;
54
55 auto rc =
56 encode_new_file_req(instanceId, PLDM_FILE_TYPE_RESOURCE_DUMP_PARMS,
57 fileHandle, fileSize, request);
58 if (rc != PLDM_SUCCESS)
59 {
60 requester->markFree(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -060061 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Jayashankar Padathdb124362021-01-28 21:12:34 -060062 return;
63 }
64
Sampa Misrac0c79482021-06-02 08:01:54 -050065 auto newFileAvailableRespHandler = [this](mctp_eid_t /*eid*/,
66 const pldm_msg* response,
67 size_t respMsgLen) {
68 if (response == nullptr || !respMsgLen)
69 {
Riya Dixit49cfb132023-03-02 04:26:53 -060070 error("Failed to receive response for NewFileAvailable command");
Sampa Misrac0c79482021-06-02 08:01:54 -050071 return;
72 }
Jayashankar Padathdb124362021-01-28 21:12:34 -060073 uint8_t completionCode{};
Sampa Misrac0c79482021-06-02 08:01:54 -050074 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
75 if (rc || completionCode)
Jayashankar Padathdb124362021-01-28 21:12:34 -060076 {
Riya Dixit49cfb132023-03-02 04:26:53 -060077 error(
78 "Failed to decode_new_file_resp or Host returned error for new_file_available rc={RC}, cc = {CC}",
79 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -050080 reportResourceDumpFailure();
Jayashankar Padathdb124362021-01-28 21:12:34 -060081 }
Sampa Misrac0c79482021-06-02 08:01:54 -050082 };
83 rc = handler->registerRequest(
84 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
85 std::move(requestMsg), std::move(newFileAvailableRespHandler));
86 if (rc)
Jayashankar Padathdb124362021-01-28 21:12:34 -060087 {
Riya Dixit49cfb132023-03-02 04:26:53 -060088 error("Failed to send NewFileAvailable Request to Host");
Sampa Misrac0c79482021-06-02 08:01:54 -050089 reportResourceDumpFailure();
90 }
91}
Jayashankar Padathdb124362021-01-28 21:12:34 -060092
Sampa Misrac0c79482021-06-02 08:01:54 -050093void DbusToFileHandler::reportResourceDumpFailure()
94{
Sampa Misrac0c79482021-06-02 08:01:54 -050095 pldm::utils::reportError("xyz.openbmc_project.bmc.pldm.InternalFailure");
96
97 PropertyValue value{resDumpStatus};
98 DBusMapping dbusMapping{resDumpCurrentObjPath, resDumpProgressIntf,
99 "Status", "string"};
100 try
101 {
102 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, value);
103 }
104 catch (const std::exception& e)
105 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600106 error("failed to set resource dump operation status, ERROR={ERR_EXCEP}",
107 "ERR_EXCEP", e.what());
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600129 error(
130 "Error {ERR_EXCEP} found in getting current resource dump status while initiating a new resource dump with objPath={DUMP_OBJ_PATH} and intf={DUMP_PROG_INTF}",
131 "ERR_EXCEP", e.what(), "DUMP_OBJ_PATH",
132 resDumpCurrentObjPath.str.c_str(), "DUMP_PROG_INTF",
133 resDumpProgressIntf);
Jayashankar Padath99fa1862021-11-10 09:45:06 -0600134 }
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600153 error("resource dump file open error:{RES_DUMP_PATH}", "RES_DUMP_PATH",
154 resDumpFilePath);
Jayashankar Padathdb124362021-01-28 21:12:34 -0600155 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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600164 error(
165 "failed to set resource dump operation status, ERROR={ERR_EXCEP}",
166 "ERR_EXCEP", e.what());
Jayashankar Padathdb124362021-01-28 21:12:34 -0600167 }
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 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600231 error("cert file open error: {CERT_PATH}", "CERT_PATH",
232 certFilePath.c_str());
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500233 return;
234 }
235
236 // Add csr to file
237 certFile << csr << std::endl;
238
239 certFile.close();
240 uint32_t fileSize = fs::file_size(certFilePath);
241
242 newFileAvailableSendToHost(fileSize, (uint32_t)stoi(fileHandle),
243 PLDM_FILE_TYPE_CERT_SIGNING_REQUEST);
244}
245
246void DbusToFileHandler::newFileAvailableSendToHost(const uint32_t fileSize,
247 const uint32_t fileHandle,
248 const uint16_t type)
249{
250 if (requester == NULL)
251 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600252 error("Failed to send csr to host.");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500253 pldm::utils::reportError(
254 "xyz.openbmc_project.bmc.pldm.InternalFailure");
255 return;
256 }
257 auto instanceId = requester->getInstanceId(mctp_eid);
258 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
259 PLDM_NEW_FILE_REQ_BYTES);
260 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
261
262 auto rc =
263 encode_new_file_req(instanceId, type, fileHandle, fileSize, request);
264 if (rc != PLDM_SUCCESS)
265 {
266 requester->markFree(mctp_eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600267 error("Failed to encode_new_file_req, rc = {RC}", "RC", rc);
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500268 return;
269 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500270 auto newFileAvailableRespHandler = [](mctp_eid_t /*eid*/,
271 const pldm_msg* response,
272 size_t respMsgLen) {
273 if (response == nullptr || !respMsgLen)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500274 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600275 error(
276 "Failed to receive response for NewFileAvailable command for vmi");
Sampa Misrac0c79482021-06-02 08:01:54 -0500277 return;
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500278 }
Sampa Misrac0c79482021-06-02 08:01:54 -0500279 uint8_t completionCode{};
280 auto rc = decode_new_file_resp(response, respMsgLen, &completionCode);
281 if (rc || completionCode)
282 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600283 error(
284 "Failed to decode_new_file_resp for vmi, or Host returned error for new_file_available rc = {RC}, cc = {CC}",
285 "RC", rc, "CC", static_cast<unsigned>(completionCode));
Sampa Misrac0c79482021-06-02 08:01:54 -0500286 pldm::utils::reportError(
287 "xyz.openbmc_project.bmc.pldm.InternalFailure");
288 }
289 };
290 rc = handler->registerRequest(
291 mctp_eid, instanceId, PLDM_OEM, PLDM_NEW_FILE_AVAILABLE,
292 std::move(requestMsg), std::move(newFileAvailableRespHandler));
293 if (rc)
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500294 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600295 error("Failed to send NewFileAvailable Request to Host for vmi");
Varsha Kaverappa219ace92021-04-01 02:50:11 -0500296 pldm::utils::reportError(
297 "xyz.openbmc_project.bmc.pldm.InternalFailure");
298 }
299}
300
Jayashankar Padathdb124362021-01-28 21:12:34 -0600301} // namespace oem_ibm
302} // namespace requester
303} // namespace pldm