blob: a16f942855d27cd1d847655f38a3c5164fa15ac9 [file] [log] [blame]
Jayanth Othayothd31be2c2020-02-04 02:56:45 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Ramesh Iyyar3af5c322020-12-04 00:38:42 -060016#include "pldm_oem_cmds.hpp"
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060017
18#include "dump_utils.hpp"
Ramesh Iyyar3af5c322020-12-04 00:38:42 -060019#include "pldm_utils.hpp"
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060020#include "xyz/openbmc_project/Common/error.hpp"
21
George Liu858fbb22021-07-01 12:25:44 +080022#include <fmt/core.h>
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060023#include <libpldm/base.h>
Ramesh Iyyar22793862020-12-04 04:03:03 -060024#include <libpldm/file_io.h>
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060025#include <libpldm/platform.h>
26#include <unistd.h>
27
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060028#include <phosphor-logging/elog-errors.hpp>
29#include <phosphor-logging/log.hpp>
30#include <sdbusplus/bus.hpp>
31
Jayanth Othayoth0af74a52021-04-08 03:55:21 -050032#include <fstream>
33
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060034namespace phosphor
35{
36namespace dump
37{
Dhruvaraj Subhashchandran59642e22020-03-19 03:37:44 -050038namespace host
39{
40/**
41 * @brief Initiate offload of the dump with provided id
42 *
43 * @param[in] id - The Dump Source ID.
44 *
45 */
46void requestOffload(uint32_t id)
47{
48 pldm::requestOffload(id);
49}
Ramesh Iyyar22793862020-12-04 04:03:03 -060050
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -060051void requestDelete(uint32_t id, uint32_t dumpType)
Ramesh Iyyar22793862020-12-04 04:03:03 -060052{
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -060053 pldm::requestDelete(id, dumpType);
Ramesh Iyyar22793862020-12-04 04:03:03 -060054}
Dhruvaraj Subhashchandran59642e22020-03-19 03:37:44 -050055} // namespace host
56
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060057namespace pldm
58{
59
60using namespace phosphor::logging;
61
62constexpr auto eidPath = "/usr/share/pldm/host_eid";
63constexpr mctp_eid_t defaultEIDValue = 9;
64
Ramesh Iyyar22793862020-12-04 04:03:03 -060065using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
66using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060067
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060068mctp_eid_t readEID()
69{
70 mctp_eid_t eid = defaultEIDValue;
71
72 std::ifstream eidFile{eidPath};
73 if (!eidFile.good())
74 {
75 log<level::ERR>("Could not open host EID file");
Ramesh Iyyar22793862020-12-04 04:03:03 -060076 elog<NotAllowed>(Reason("Required host dump action via pldm is not "
77 "allowed due to mctp end point read failed"));
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060078 }
79 else
80 {
81 std::string eid;
82 eidFile >> eid;
83 if (!eid.empty())
84 {
85 eid = strtol(eid.c_str(), nullptr, 10);
86 }
87 else
88 {
89 log<level::ERR>("EID file was empty");
Ramesh Iyyar22793862020-12-04 04:03:03 -060090 elog<NotAllowed>(
91 Reason("Required host dump action via pldm is not "
92 "allowed due to mctp end point read failed"));
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060093 }
94 }
95
96 return eid;
97}
98
Jayanth Othayothd31be2c2020-02-04 02:56:45 -060099void requestOffload(uint32_t id)
100{
101 uint16_t effecterId = 0x05; // TODO PhyP temporary Hardcoded value.
102
103 std::array<uint8_t, sizeof(pldm_msg_hdr) + sizeof(effecterId) + sizeof(id) +
104 sizeof(uint8_t)>
105 requestMsg{};
106 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
107
108 std::array<uint8_t, sizeof(id)> effecterValue{};
109
110 memcpy(effecterValue.data(), &id, sizeof(id));
111
112 mctp_eid_t eid = readEID();
113
114 auto instanceID = getPLDMInstanceID(eid);
115
116 auto rc = encode_set_numeric_effecter_value_req(
117 instanceID, effecterId, PLDM_EFFECTER_DATA_SIZE_UINT32,
118 effecterValue.data(), request,
119 requestMsg.size() - sizeof(pldm_msg_hdr));
120
121 if (rc != PLDM_SUCCESS)
122 {
George Liu858fbb22021-07-01 12:25:44 +0800123 log<level::ERR>(
124 fmt::format("Message encode failure. RC({})", rc).c_str());
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600125 elog<NotAllowed>(Reason("Host dump offload via pldm is not "
Ramesh Iyyar22793862020-12-04 04:03:03 -0600126 "allowed due to encode failed"));
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600127 }
128
129 uint8_t* responseMsg = nullptr;
130 size_t responseMsgSize{};
131
Ramesh Iyyar5765b1d2020-12-04 01:29:44 -0600132 CustomFd fd(openPLDM());
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600133
Ramesh Iyyar5765b1d2020-12-04 01:29:44 -0600134 rc = pldm_send_recv(eid, fd(), requestMsg.data(), requestMsg.size(),
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600135 &responseMsg, &responseMsgSize);
136 if (rc < 0)
137 {
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600138 auto e = errno;
George Liu858fbb22021-07-01 12:25:44 +0800139 log<level::ERR>(
140 fmt::format("pldm_send failed, RC({}), errno({})", rc, e).c_str());
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600141 elog<NotAllowed>(Reason("Host dump offload via pldm is not "
Ramesh Iyyar22793862020-12-04 04:03:03 -0600142 "allowed due to fileack send failed"));
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600143 }
144 pldm_msg* response = reinterpret_cast<pldm_msg*>(responseMsg);
George Liu858fbb22021-07-01 12:25:44 +0800145 log<level::INFO>(fmt::format("Done. PLDM message, RC({})",
146 static_cast<uint16_t>(response->payload[0]))
147 .c_str());
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600148}
149
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600150void requestDelete(uint32_t dumpId, uint32_t dumpType)
Ramesh Iyyar22793862020-12-04 04:03:03 -0600151{
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600152 pldm_fileio_file_type pldmDumpType;
153 switch (dumpType)
154 {
155 case PLDM_FILE_TYPE_DUMP:
156 pldmDumpType = PLDM_FILE_TYPE_DUMP;
157 break;
Dhruvaraj Subhashchandran0c782d62021-03-24 13:27:13 -0500158 case PLDM_FILE_TYPE_RESOURCE_DUMP:
159 pldmDumpType = PLDM_FILE_TYPE_RESOURCE_DUMP;
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600160 break;
161 default:
162 throw std::runtime_error("Unknown pldm dump file-io type to delete "
163 "host dump");
164 }
Ramesh Iyyar22793862020-12-04 04:03:03 -0600165 const size_t pldmMsgHdrSize = sizeof(pldm_msg_hdr);
166 std::array<uint8_t, pldmMsgHdrSize + PLDM_FILE_ACK_REQ_BYTES> fileAckReqMsg;
167
168 mctp_eid_t mctpEndPointId = readEID();
169
170 auto pldmInstanceId = getPLDMInstanceID(mctpEndPointId);
171
Ramesh Iyyar22793862020-12-04 04:03:03 -0600172 // - PLDM_SUCCESS - To indicate dump was readed (offloaded) or user decided,
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600173 // no longer host dump is not required so, initiate deletion from
Ramesh Iyyar22793862020-12-04 04:03:03 -0600174 // host memory
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600175 int retCode =
176 encode_file_ack_req(pldmInstanceId, pldmDumpType, dumpId, PLDM_SUCCESS,
177 reinterpret_cast<pldm_msg*>(fileAckReqMsg.data()));
Ramesh Iyyar22793862020-12-04 04:03:03 -0600178
179 if (retCode != PLDM_SUCCESS)
180 {
George Liu858fbb22021-07-01 12:25:44 +0800181 log<level::ERR>(
182 fmt::format("Failed to encode pldm FileAck to delete host "
183 "dump,SRC_DUMP_ID({}), "
184 "PLDM_FILE_IO_TYPE({}),PLDM_RETURN_CODE({})",
185 dumpId, pldmDumpType, retCode)
186 .c_str());
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600187 elog<NotAllowed>(Reason("Host dump deletion via pldm is not "
Ramesh Iyyar22793862020-12-04 04:03:03 -0600188 "allowed due to encode fileack failed"));
189 }
190
191 uint8_t* pldmRespMsg = nullptr;
192 size_t pldmRespMsgSize;
193
194 CustomFd pldmFd(openPLDM());
195
196 retCode =
197 pldm_send_recv(mctpEndPointId, pldmFd(), fileAckReqMsg.data(),
198 fileAckReqMsg.size(), &pldmRespMsg, &pldmRespMsgSize);
199
200 std::unique_ptr<uint8_t, decltype(std::free)*> pldmRespMsgPtr{pldmRespMsg,
201 std::free};
202 if (retCode != PLDM_REQUESTER_SUCCESS)
203 {
204 auto errorNumber = errno;
George Liu858fbb22021-07-01 12:25:44 +0800205 log<level::ERR>(
206 fmt::format("Failed to send pldm FileAck to delete host dump, "
207 "SRC_DUMP_ID({}), PLDM_FILE_IO_TYPE({}), "
208 "PLDM_RETURN_CODE({}), ERRNO({}), ERRMSG({})",
209 dumpId, pldmDumpType, retCode, errorNumber,
210 strerror(errorNumber))
211 .c_str());
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600212 elog<NotAllowed>(Reason("Host dump deletion via pldm is not "
Ramesh Iyyar22793862020-12-04 04:03:03 -0600213 "allowed due to fileack send failed"));
214 }
215
216 uint8_t completionCode;
217
218 retCode =
219 decode_file_ack_resp(reinterpret_cast<pldm_msg*>(pldmRespMsgPtr.get()),
220 pldmRespMsgSize - pldmMsgHdrSize, &completionCode);
221
222 if (retCode || completionCode)
223 {
George Liu858fbb22021-07-01 12:25:44 +0800224 log<level::ERR>(
225 fmt::format("Failed to delete host dump, SRC_DUMP_ID({}), "
226 "PLDM_FILE_IO_TYPE({}), PLDM_RETURN_CODE({}), "
227 "PLDM_COMPLETION_CODE({})",
228 dumpId, pldmDumpType, retCode, completionCode)
229 .c_str());
Dhruvaraj Subhashchandran4c63ce52020-12-18 02:07:22 -0600230 elog<NotAllowed>(Reason("Host dump deletion via pldm is "
Ramesh Iyyar22793862020-12-04 04:03:03 -0600231 "failed"));
232 }
233
George Liu858fbb22021-07-01 12:25:44 +0800234 log<level::INFO>(
235 fmt::format("Deleted host dump, SRC_DUMP_ID({})", dumpId).c_str());
Ramesh Iyyar22793862020-12-04 04:03:03 -0600236}
Jayanth Othayothd31be2c2020-02-04 02:56:45 -0600237} // namespace pldm
238} // namespace dump
239} // namespace phosphor