Implement GetFileHandle in dump entry interface
Certain applications need to offload the dump in various
ways, for example, performing DMA transfer of the dump to
the host memory. These applications require direct access
to the file to read from the BMC storage.
This commit introduces the GetFileHandle method in the
dump entry interface. This method provides direct access
to the Unix file handle of the dump entry, facilitating
more direct read operations on the dump file.
The returned file descriptor is read-only, which ensures
the integrity of the dump file.
The definition of the file handle is moved from the
specific 'bmc_dump_entry' class to the parent 'dump_entry'
class. This allows all dump types inheriting from
'dump_entry' to use this new method, thus increasing
its utility across various dump types.
The introduction of this method primarily benefits PLDM
for offloading the dump to the host, and bmcweb for
offloading the dump to Redfish clients. By providing
a file handle instead of exposing the file path,
it resolves potential access issues for applications
running in non-root contexts.
Test:
Created a dump and made sure it reached host
successfully
Executed with additional traces
Jun 21 10:56:09 pldmd[1856]: Requesting file handle
Jun 21 10:56:09 pldmd[1856]: File handle received fd=9
Jun 21 10:56:09 pldmd[1856]: Transfer data rc= 0
Jun 21 10:56:09 phosphor-dump-manager[480]: File handle \
request
Jun 21 10:56:09 phosphor-dump-manager[480]: returning fd=11
Jun 21 10:56:09 pldmd[1856]: File handle received fd=9
Jun 21 10:56:09 pldmd[1856]: File read rc=15
In th host:
Service Processor Dump:
Maximum file size: 0 (0x00000000) bytes (0 MBs)
Dumps this PHYP IPL: 1
Pending Dump:
Dump ID: 00000009
File size: 3749662 \
(0x000000000039371E) bytes (3 MBs)
SP dump sub type: 0x000000000000000F BMC
File name: \
BMCDUMP.1392A20.00000009.20230621105510
Dump create time: 06/21/2023 10:55:10.00
PHYP notify time: 06/21/2023 10:56:00.5918570000
LP recipient: 1
LP notify time: 06/21/2023 10:56:00.5918580000
Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: If398940b655b4d90688273f0c76a20d4ead61992
diff --git a/bmc_dump_entry.hpp b/bmc_dump_entry.hpp
index 267a0ef..7c230ab 100644
--- a/bmc_dump_entry.hpp
+++ b/bmc_dump_entry.hpp
@@ -50,7 +50,7 @@
* @param[in] timeStamp - Dump creation timestamp
* since the epoch.
* @param[in] fileSize - Dump file size in bytes.
- * @param[in] file - Name of dump file.
+ * @param[in] file - Absolute path to the dump file.
* @param[in] status - status of the dump.
* @param[in] originatorId - Id of the originator of the dump
* @param[in] originatorType - Originator type
@@ -63,8 +63,8 @@
originatorTypes originatorType, phosphor::dump::Manager& parent) :
EntryIfaces(bus, objPath.c_str(), EntryIfaces::action::defer_emit),
phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, fileSize,
- status, originatorId, originatorType, parent),
- file(file)
+ file, status, originatorId, originatorType,
+ parent)
{
// Emit deferred signal.
this->phosphor::dump::bmc::EntryIfaces::emit_object_added();
@@ -98,10 +98,6 @@
// #ibm-openbmc/2597
completedTime(timeStamp);
}
-
- private:
- /** @Dump file name */
- std::filesystem::path file;
};
} // namespace bmc
diff --git a/dump-extensions/openpower-dumps/resource_dump_entry.hpp b/dump-extensions/openpower-dumps/resource_dump_entry.hpp
index 0338399..517f6ca 100644
--- a/dump-extensions/openpower-dumps/resource_dump_entry.hpp
+++ b/dump-extensions/openpower-dumps/resource_dump_entry.hpp
@@ -63,7 +63,8 @@
originatorTypes originatorType, phosphor::dump::Manager& parent) :
EntryIfaces(bus, objPath.c_str(), EntryIfaces::action::defer_emit),
phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, dumpSize,
- status, originatorId, originatorType, parent)
+ std::string(), status, originatorId,
+ originatorType, parent)
{
sourceDumpId(sourceId);
vspString(vspStr);
diff --git a/dump-extensions/openpower-dumps/system_dump_entry.hpp b/dump-extensions/openpower-dumps/system_dump_entry.hpp
index 1e83bbf..36855c4 100644
--- a/dump-extensions/openpower-dumps/system_dump_entry.hpp
+++ b/dump-extensions/openpower-dumps/system_dump_entry.hpp
@@ -57,7 +57,8 @@
originatorTypes originatorType, phosphor::dump::Manager& parent) :
EntryIfaces(bus, objPath.c_str(), EntryIfaces::action::defer_emit),
phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, dumpSize,
- status, originatorId, originatorType, parent)
+ std::string(), status, originatorId,
+ originatorType, parent)
{
sourceDumpId(sourceId);
// Emit deferred signal.
diff --git a/dump_entry.cpp b/dump_entry.cpp
index 0ecb9cb..b37a914 100644
--- a/dump_entry.cpp
+++ b/dump_entry.cpp
@@ -2,16 +2,66 @@
#include "dump_manager.hpp"
+#include <fcntl.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/event.hpp>
+#include <xyz/openbmc_project/Common/File/error.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <cstring>
+
namespace phosphor
{
namespace dump
{
+using namespace phosphor::logging;
+
void Entry::delete_()
{
// Remove Dump entry D-bus object
parent.erase(id);
}
+sdbusplus::message::unix_fd Entry::getFileHandle()
+{
+ using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
+ using metadata = xyz::openbmc_project::Common::File::Open;
+ if (file.empty())
+ {
+ lg2::error("Failed to get file handle: File path is empty.");
+ elog<sdbusplus::xyz::openbmc_project::Common::Error::Unavailable>();
+ }
+
+ if (fdCloseEventSource)
+ {
+ // Return the existing file descriptor
+ return fdCloseEventSource->first;
+ }
+
+ int fd = open(file.c_str(), O_RDONLY | O_NONBLOCK);
+ if (fd == -1)
+ {
+ auto err = errno;
+ lg2::error("Failed to open dump file: id: {ID} error: {ERRNO}", "ID",
+ id, "ERRNO", std::strerror(errno));
+ elog<Open>(metadata::ERRNO(err), metadata::PATH(file.c_str()));
+ }
+
+ // Create a new Defer event source for closing this fd
+ sdeventplus::Event event = sdeventplus::Event::get_default();
+ auto eventSource = std::make_unique<sdeventplus::source::Defer>(
+ event, [this](auto& /*source*/) { closeFD(); });
+
+ // Store the file descriptor and event source in the optional pair
+ fdCloseEventSource = std::make_pair(fd, std::move(eventSource));
+
+ return fd;
+}
+
} // namespace dump
} // namespace phosphor
diff --git a/dump_entry.hpp b/dump_entry.hpp
index 9f4c2a6..8f6cf2f 100644
--- a/dump_entry.hpp
+++ b/dump_entry.hpp
@@ -8,6 +8,8 @@
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server/object.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/event.hpp>
#include <filesystem>
@@ -65,10 +67,11 @@
* @param[in] parent - The dump entry's parent.
*/
Entry(sdbusplus::bus_t& bus, const std::string& objPath, uint32_t dumpId,
- uint64_t timeStamp, uint64_t dumpSize, OperationStatus dumpStatus,
+ uint64_t timeStamp, uint64_t dumpSize,
+ const std::filesystem::path& file, OperationStatus dumpStatus,
std::string originId, originatorTypes originType, Manager& parent) :
EntryIfaces(bus, objPath.c_str(), EntryIfaces::action::emit_no_signals),
- parent(parent), id(dumpId)
+ parent(parent), id(dumpId), file(file)
{
originatorId(originId);
originatorType(originType);
@@ -115,12 +118,42 @@
return id;
}
+ /** @brief Method to get the file handle of the dump
+ * @returns A Unix file descriptor to the dump file
+ * @throws sdbusplus::xyz::openbmc_project::Common::File::Error::Open on
+ * failure to open the file
+ * @throws sdbusplus::xyz::openbmc_project::Common::Error::Unavailable if
+ * the file string is empty
+ */
+ sdbusplus::message::unix_fd getFileHandle() override;
+
protected:
/** @brief This entry's parent */
Manager& parent;
/** @brief This entry's id */
uint32_t id;
+
+ /** @Dump file name */
+ std::filesystem::path file;
+
+ private:
+ /** @brief Closes the file descriptor and removes the corresponding event
+ * source.
+ *
+ */
+ void closeFD()
+ {
+ if (fdCloseEventSource)
+ {
+ close(fdCloseEventSource->first);
+ fdCloseEventSource.reset();
+ }
+ }
+
+ /* @brief A pair of file descriptor and corresponding event source. */
+ std::optional<std::pair<int, std::unique_ptr<sdeventplus::source::Defer>>>
+ fdCloseEventSource;
};
} // namespace dump
diff --git a/faultlog_dump_entry.hpp b/faultlog_dump_entry.hpp
index 60f5bd1..3e5b53a 100644
--- a/faultlog_dump_entry.hpp
+++ b/faultlog_dump_entry.hpp
@@ -52,17 +52,13 @@
phosphor::dump::OperationStatus status, std::string originatorId,
originatorTypes originatorType, phosphor::dump::Manager& parent) :
phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, fileSize,
- status, originatorId, originatorType, parent),
- file(file)
+ file, status, originatorId, originatorType,
+ parent)
{}
/** @brief Delete this d-bus object.
*/
void delete_() override;
-
- private:
- /** @Dump file path */
- std::filesystem::path file;
};
} // namespace faultlog