Skip to content

Commit 0a5846d

Browse files
Adding support for asynchronous file transfer
- File transfer between BMC and Host is synchronous mechanism. - File transfer interrupted because of many reasons, so if file transfer interrupted between BMC and Host then PLDM is ending up in the hung state and not able to respond to the upcoming new requests. User has to do work around to restart the PLDM to get work again. - I have added asynchronous file transfer support using eventloop mechanism and non-blocking socket communication, so file transfer will be taken care by event loop and PLDM is free to receive another request from the Host. - If file transfer will be stuck or interrupted during asynchronous transfer then time-out occurs and file transfer will be aborted and same status communicated to the Host. Signed-off-by: Kamalkumar Patel <[email protected]>
1 parent 37f4593 commit 0a5846d

21 files changed

+1396
-503
lines changed

oem/ibm/libpldmresponder/file_io.cpp

+156-105
Large diffs are not rendered by default.

oem/ibm/libpldmresponder/file_io.hpp

+405-51
Large diffs are not rendered by default.

oem/ibm/libpldmresponder/file_io_by_type.cpp

+381-35
Large diffs are not rendered by default.

oem/ibm/libpldmresponder/file_io_by_type.hpp

+87-13
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
#pragma once
22

3+
#include "libpldm/file_io.h"
4+
35
#include "oem_ibm_handler.hpp"
46
#include "pldmd/pldm_resp_interface.hpp"
57

8+
#include <sdbusplus/bus.hpp>
9+
#include <sdbusplus/server.hpp>
10+
#include <sdbusplus/server/object.hpp>
11+
#include <sdbusplus/timer.hpp>
12+
#include <sdeventplus/clock.hpp>
13+
#include <sdeventplus/event.hpp>
14+
#include <sdeventplus/exception.hpp>
15+
#include <sdeventplus/source/io.hpp>
16+
#include <sdeventplus/source/signal.hpp>
17+
#include <sdeventplus/source/time.hpp>
18+
#include <stdplus/signal.hpp>
19+
#include <xyz/openbmc_project/Logging/Entry/server.hpp>
20+
21+
#include <vector>
622
namespace pldm
723
{
824

925
namespace responder
1026
{
27+
using namespace sdeventplus;
28+
using namespace sdeventplus::source;
29+
constexpr auto clockId = sdeventplus::ClockId::RealTime;
30+
using Timer = Time<clockId>;
31+
using Clock = Clock<clockId>;
1132

1233
class FileHandler;
1334
namespace dma
@@ -33,6 +54,34 @@ namespace fs = std::filesystem;
3354
*/
3455
class FileHandler
3556
{
57+
protected:
58+
/** @brief method to send response to host after completion of DMA operation
59+
* @param[in] responseHdr - contain response related data
60+
* @param[in] rStatus - operation status either success/fail/not suppoted.
61+
* @param[in] length - length to be read/write mentioned by Host
62+
*/
63+
virtual void dmaResponseToHost(const ResponseHdr& responseHdr,
64+
const pldm_completion_codes rStatus,
65+
uint32_t length);
66+
67+
/** @brief method to send response to host after completion of DMA operation
68+
* @param[in] responseHdr - contain response related data
69+
* @param[in] rStatus - operation status either success/fail/not suppoted.
70+
* @param[in] length - length to be read/write mentioned by Host
71+
*/
72+
virtual void dmaResponseToHost(const ResponseHdr& responseHdr,
73+
const pldm_fileio_completion_codes rStatus,
74+
uint32_t length);
75+
76+
/** @brief method to delete all shared pointer object
77+
* @param[in] responseHdr - contain response related data
78+
* @param[in] xdmaInterface - interface to transfer data between BMc and
79+
* Host
80+
*/
81+
virtual void
82+
deleteAIOobjects(const std::shared_ptr<dma::DMA>& xdmaInterface,
83+
const ResponseHdr& responseHdr);
84+
3685
public:
3786
/** @brief Method to write an oem file type from host memory. Individual
3887
* file types need to override this method to do the file specific
@@ -44,9 +93,11 @@ class FileHandler
4493
* tasks
4594
* @return PLDM status code
4695
*/
47-
virtual int writeFromMemory(uint32_t offset, uint32_t length,
48-
uint64_t address,
49-
oem_platform::Handler* oemPlatformHandler) = 0;
96+
virtual void writeFromMemory(uint32_t offset, uint32_t length,
97+
uint64_t address,
98+
oem_platform::Handler* oemPlatformHandler,
99+
ResponseHdr& responseHdr,
100+
sdeventplus::Event& event) = 0;
50101

51102
/** @brief Method to read an oem file type into host memory. Individual
52103
* file types need to override this method to do the file specific
@@ -58,9 +109,11 @@ class FileHandler
58109
* tasks
59110
* @return PLDM status code
60111
*/
61-
virtual int readIntoMemory(uint32_t offset, uint32_t& length,
62-
uint64_t address,
63-
oem_platform::Handler* oemPlatformHandler) = 0;
112+
virtual void readIntoMemory(uint32_t offset, uint32_t& length,
113+
uint64_t address,
114+
oem_platform::Handler* oemPlatformHandler,
115+
ResponseHdr& responseHdr,
116+
sdeventplus::Event& event) = 0;
64117

65118
/** @brief Method to read an oem file type's content into the PLDM response.
66119
* @param[in] offset - offset to read
@@ -151,15 +204,28 @@ class FileHandler
151204
*
152205
* @return PLDM status code
153206
*/
154-
virtual int transferFileData(const fs::path& path, bool upstream,
155-
uint32_t offset, uint32_t& length,
156-
uint64_t address);
207+
virtual void transferFileData(const fs::path& path, bool upstream,
208+
uint32_t offset, uint32_t& length,
209+
uint64_t address, ResponseHdr& responseHdr,
210+
sdeventplus::Event& event);
157211

158-
virtual int transferFileData(int fd, bool upstream, uint32_t offset,
159-
uint32_t& length, uint64_t address);
212+
virtual void transferFileData(int fd, bool upstream, uint32_t offset,
213+
uint32_t& length, uint64_t address,
214+
ResponseHdr& responseHdr,
215+
sdeventplus::Event& event);
160216

161-
virtual int transferFileDataToSocket(int fd, uint32_t& length,
162-
uint64_t address);
217+
virtual void transferFileDataToSocket(int fd, uint32_t& length,
218+
uint64_t address,
219+
ResponseHdr& responseHdr,
220+
sdeventplus::Event& event);
221+
222+
/** @brief method to do necessary operation according different
223+
* file type and being call when data transfer completed.
224+
*
225+
* @param[in] IsWriteToMemOp - type of operation to decide what operation
226+
* needs to be done after data transfer.
227+
*/
228+
virtual void postDataTransferCallBack(bool IsWriteToMemOp) = 0;
163229

164230
/** @brief Constructor to create a FileHandler object
165231
*/
@@ -181,5 +247,13 @@ class FileHandler
181247

182248
std::unique_ptr<FileHandler> getHandlerByType(uint16_t fileType,
183249
uint32_t fileHandle);
250+
251+
/** @brief Method to create shared file handler objects based on file type
252+
*
253+
* @param[in] fileType - type of file
254+
* @param[in] fileHandle - file handle
255+
*/
256+
std::shared_ptr<FileHandler> getSharedHandlerByType(uint16_t fileType,
257+
uint32_t fileHandle);
184258
} // namespace responder
185259
} // namespace pldm

oem/ibm/libpldmresponder/file_io_type_cert.cpp

+46-22
Original file line numberDiff line numberDiff line change
@@ -25,51 +25,75 @@ static constexpr auto certFilePath = "/var/lib/ibm/bmcweb/";
2525

2626
CertMap CertHandler::certMap;
2727

28-
int CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
29-
uint64_t address,
30-
oem_platform::Handler* /*oemPlatformHandler*/)
28+
void CertHandler::writeFromMemory(uint32_t offset, uint32_t length,
29+
uint64_t address,
30+
oem_platform::Handler* /*oemPlatformHandler*/,
31+
ResponseHdr& responseHdr,
32+
sdeventplus::Event& event)
3133
{
3234
auto it = certMap.find(certType);
3335
if (it == certMap.end())
3436
{
3537
error(
3638
"CertHandler::writeFromMemory:file for type {CERT_TYP} doesn't exist",
3739
"CERT_TYP", certType);
38-
return PLDM_ERROR;
40+
FileHandler::dmaResponseToHost(responseHdr, PLDM_ERROR, 0);
41+
FileHandler::deleteAIOobjects(nullptr, responseHdr);
42+
return;
3943
}
40-
44+
m_length = length;
4145
auto fd = std::get<0>(it->second);
42-
auto& remSize = std::get<1>(it->second);
43-
auto rc = transferFileData(fd, false, offset, length, address);
44-
if (rc == PLDM_SUCCESS)
46+
transferFileData(fd, false, offset, length, address, responseHdr, event);
47+
48+
return;
49+
}
50+
51+
void CertHandler::postDataTransferCallBack(bool IsWriteToMemOp)
52+
{
53+
if (IsWriteToMemOp)
4554
{
46-
remSize -= length;
55+
auto it = certMap.find(certType);
56+
if (it == certMap.end())
57+
{
58+
error(
59+
"CertHandler::writeFromMemory:file for type {TYPE} doesn't exist",
60+
"TYPE", certType);
61+
return;
62+
}
63+
// auto fd = std::get<0>(it->second);
64+
auto& remSize = std::get<1>(it->second);
65+
remSize -= m_length;
4766
if (!remSize)
4867
{
49-
close(fd);
68+
// close(fd);
5069
certMap.erase(it);
5170
}
5271
}
53-
return rc;
72+
else
73+
{
74+
fs::remove(certfilePath);
75+
}
76+
return;
5477
}
5578

56-
int CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
57-
uint64_t address,
58-
oem_platform::Handler* /*oemPlatformHandler*/)
79+
void CertHandler::readIntoMemory(uint32_t offset, uint32_t& length,
80+
uint64_t address,
81+
oem_platform::Handler* /*oemPlatformHandler*/,
82+
ResponseHdr& responseHdr,
83+
sdeventplus::Event& event)
5984
{
6085
std::string filePath = certFilePath;
6186
filePath += "CSR_" + std::to_string(fileHandle);
6287
if (certType != PLDM_FILE_TYPE_CERT_SIGNING_REQUEST)
6388
{
64-
return PLDM_ERROR_INVALID_DATA;
65-
}
66-
auto rc = transferFileData(filePath.c_str(), true, offset, length, address);
67-
fs::remove(filePath);
68-
if (rc)
69-
{
70-
return PLDM_ERROR;
89+
FileHandler::dmaResponseToHost(responseHdr, PLDM_ERROR_INVALID_DATA,
90+
length);
91+
FileHandler::deleteAIOobjects(nullptr, responseHdr);
92+
return;
7193
}
72-
return PLDM_SUCCESS;
94+
certfilePath = filePath;
95+
transferFileData(filePath.c_str(), true, offset, length, address,
96+
responseHdr, event);
7397
}
7498

7599
int CertHandler::read(uint32_t offset, uint32_t& length, Response& response,

oem/ibm/libpldmresponder/file_io_type_cert.hpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ class CertHandler : public FileHandler
2929
FileHandler(fileHandle), certType(fileType)
3030
{}
3131

32-
virtual int writeFromMemory(uint32_t offset, uint32_t length,
32+
virtual void writeFromMemory(uint32_t offset, uint32_t length,
33+
uint64_t address,
34+
oem_platform::Handler* /*oemPlatformHandler*/,
35+
ResponseHdr& responseHdr,
36+
sdeventplus::Event& event);
37+
virtual void readIntoMemory(uint32_t offset, uint32_t& length,
3338
uint64_t address,
34-
oem_platform::Handler* /*oemPlatformHandler*/);
35-
virtual int readIntoMemory(uint32_t offset, uint32_t& length,
36-
uint64_t address,
37-
oem_platform::Handler* /*oemPlatformHandler*/);
39+
oem_platform::Handler* /*oemPlatformHandler*/,
40+
ResponseHdr& responseHdr,
41+
sdeventplus::Event& event);
3842
virtual int read(uint32_t offset, uint32_t& length, Response& response,
3943
oem_platform::Handler* /*oemPlatformHandler*/);
4044

@@ -60,6 +64,8 @@ class CertHandler : public FileHandler
6064
uint32_t /*metaDataValue3*/,
6165
uint32_t /*metaDataValue4*/);
6266

67+
virtual void postDataTransferCallBack(bool IsWriteToMemOp);
68+
6369
/** @brief CertHandler destructor
6470
*/
6571
~CertHandler() {}
@@ -68,7 +74,8 @@ class CertHandler : public FileHandler
6874
uint16_t certType; //!< type of the certificate
6975
static CertMap certMap; //!< holds the fd and remaining read/write size for
7076
//!< each certificate
71-
77+
uint32_t m_length;
78+
std::string certfilePath;
7279
enum SignedCertStatus
7380
{
7481
PLDM_INVALID_CERT_DATA = 0X03

oem/ibm/libpldmresponder/file_io_type_chap.hpp

+19-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22

3-
#include "file_io_by_type.hpp"
3+
#include "file_io.hpp"
44

55
namespace pldm
66
{
@@ -21,18 +21,26 @@ class ChapHandler : public FileHandler
2121
FileHandler(fileHandle), chapType(fileType)
2222
{}
2323

24-
virtual int writeFromMemory(uint32_t /*offset*/, uint32_t /*length*/,
25-
uint64_t /*address*/,
26-
oem_platform::Handler* /*oemPlatformHandle*/)
24+
virtual void writeFromMemory(uint32_t /*offset*/, uint32_t length,
25+
uint64_t /*address*/,
26+
oem_platform::Handler* /*oemPlatformHandle*/,
27+
ResponseHdr& responseHdr,
28+
sdeventplus::Event& /*event*/)
2729
{
28-
return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
30+
FileHandler::dmaResponseToHost(responseHdr,
31+
PLDM_ERROR_UNSUPPORTED_PLDM_CMD, length);
32+
FileHandler::deleteAIOobjects(nullptr, responseHdr);
2933
}
3034

31-
virtual int readIntoMemory(uint32_t /*offset*/, uint32_t& /*length*/,
32-
uint64_t /*address*/,
33-
oem_platform::Handler* /*oemPlatformHandler*/)
35+
virtual void readIntoMemory(uint32_t /*offset*/, uint32_t& length,
36+
uint64_t /*address*/,
37+
oem_platform::Handler* /*oemPlatformHandler*/,
38+
ResponseHdr& responseHdr,
39+
sdeventplus::Event& /*event*/)
3440
{
35-
return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
41+
FileHandler::dmaResponseToHost(responseHdr,
42+
PLDM_ERROR_UNSUPPORTED_PLDM_CMD, length);
43+
FileHandler::deleteAIOobjects(nullptr, responseHdr);
3644
}
3745

3846
virtual int read(uint32_t offset, uint32_t& length, Response& response,
@@ -70,6 +78,8 @@ class ChapHandler : public FileHandler
7078
return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
7179
}
7280

81+
virtual void postDataTransferCallBack(bool /*IsWriteToMemOp*/) {}
82+
7383
/** @brief ChapHandler destructor
7484
*/
7585
~ChapHandler() {}

0 commit comments

Comments
 (0)