diff options
author | Abhilash Raju <abhilash.kollam@gmail.com> | 2023-11-09 07:32:44 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2024-01-22 22:15:20 +0300 |
commit | b5f288d294e17719f30e32acc40e07681baf04b9 (patch) | |
tree | 7ccfd67ef408e0fc5d508ac9266040d3d4a879fe /redfish-core | |
parent | ee192c065cc658b2489d04c791e2fb956a331699 (diff) | |
download | bmcweb-b5f288d294e17719f30e32acc40e07681baf04b9.tar.xz |
Make use of filebody for dump offload
Logservice has been rewritten to use file_body to offload dump files
from BMC.
There are two kind of dump files, BMC dump and System dump.While BMC
dump just requires default support from beast::file_body, System dump
requires base64 encoding support from beast. But beast::file_body do not
have ready-made support for base64 encoding. So a custom file_body has
been written for the base64 encoding.
The openFile apis in crow::Response do not have support for unix file
descriptor. Since dump files are accesses via descriptors, added new
openFile api that accepts descriptors.
Tested:
Functionality test have been executed to verify the bmc dump offload.
Did sanity test by invoking bmcweb pages via browser.
Change-Id: I24192657c03d8b2f0394d31e7424c6796ba3227a
Signed-off-by: Abhilash Raju <abhilash.kollam@gmail.com>
Diffstat (limited to 'redfish-core')
-rw-r--r-- | redfish-core/lib/log_services.hpp | 81 |
1 files changed, 40 insertions, 41 deletions
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp index 371ae44867..24f0251ee1 100644 --- a/redfish-core/lib/log_services.hpp +++ b/redfish-core/lib/log_services.hpp @@ -45,6 +45,7 @@ #include <array> #include <charconv> +#include <cstddef> #include <filesystem> #include <iterator> #include <optional> @@ -745,7 +746,35 @@ inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::format("{}/entry/{}", getDumpPath(dumpType), entryID), "xyz.openbmc_project.Object.Delete", "Delete"); } +inline bool checkSizeLimit(int fd, crow::Response& res) +{ + long long int size = lseek(fd, 0, SEEK_END); + if (size <= 0) + { + BMCWEB_LOG_ERROR("Failed to get size of file, lseek() returned {}", + size); + messages::internalError(res); + return false; + } + // Arbitrary max size of 20MB to accommodate BMC dumps + constexpr long long int maxFileSize = 20LL * 1024LL * 1024LL; + if (size > maxFileSize) + { + BMCWEB_LOG_ERROR("File size {} exceeds maximum allowed size of {}", + size, maxFileSize); + messages::internalError(res); + return false; + } + off_t rc = lseek(fd, 0, SEEK_SET); + if (rc < 0) + { + BMCWEB_LOG_ERROR("Failed to reset file offset to 0"); + messages::internalError(res); + return false; + } + return true; +} inline void downloadEntryCallback(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& entryID, @@ -781,59 +810,29 @@ inline void messages::internalError(asyncResp->res); return; } - - long long int size = lseek(fd, 0, SEEK_END); - if (size <= 0) + if (!checkSizeLimit(fd, asyncResp->res)) { - BMCWEB_LOG_ERROR("Failed to get size of file, lseek() returned {}", - size); - messages::internalError(asyncResp->res); close(fd); return; } - - // Arbitrary max size of 20MB to accommodate BMC dumps - constexpr int maxFileSize = 20 * 1024 * 1024; - if (size > maxFileSize) - { - BMCWEB_LOG_ERROR("File size {} exceeds maximum allowed size of {}", - size, maxFileSize); - messages::internalError(asyncResp->res); - close(fd); - return; - } - long long int rc = lseek(fd, 0, SEEK_SET); - if (rc < 0) + if (downloadEntryType == "System") { - BMCWEB_LOG_ERROR("Failed to reset file offset to 0"); - messages::internalError(asyncResp->res); - close(fd); + if (!asyncResp->res.openFd(fd, bmcweb::EncodingType::Base64)) + { + messages::internalError(asyncResp->res); + close(fd); + return; + } + asyncResp->res.addHeader( + boost::beast::http::field::content_transfer_encoding, "Base64"); return; } - - std::string body; - body.resize(static_cast<size_t>(size), '\0'); - rc = read(fd, body.data(), body.size()); - if ((rc == -1) || (rc != size)) + if (!asyncResp->res.openFd(fd)) { - BMCWEB_LOG_ERROR("Failed to read in file"); messages::internalError(asyncResp->res); close(fd); return; } - close(fd); - if (downloadEntryType == "System") - { - // Base64 encode response. - asyncResp->res.write(crow::utility::base64encode(body)); - asyncResp->res.addHeader( - boost::beast::http::field::content_transfer_encoding, "Base64"); - } - else - { - asyncResp->res.write(std::move(body)); - } - asyncResp->res.addHeader(boost::beast::http::field::content_type, "application/octet-stream"); } |