Move to libpldm instance id APIs
libpldm provides APIs for allocating instance IDs directly, which
eliminates the need for remote dbus calls to the pldm daemon. Refactor
the code to use these APIs and eliminate all the dbus operations.
Test: Tested the resource dump download and delete using GUI
and it works as expected.
Change-Id: I9c03de15174f517c182258b88245a58c74f4313f
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Signed-off-by: Eddie James <eajames@linux.ibm.com>
diff --git a/host-transport-extensions/pldm/common/pldm_utils.cpp b/host-transport-extensions/pldm/common/pldm_utils.cpp
index c8cf1d0..39da125 100644
--- a/host-transport-extensions/pldm/common/pldm_utils.cpp
+++ b/host-transport-extensions/pldm/common/pldm_utils.cpp
@@ -5,6 +5,8 @@
#include "dump_utils.hpp"
#include "xyz/openbmc_project/Common/error.hpp"
+#include <libpldm/transport.h>
+
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/lg2.hpp>
@@ -19,6 +21,75 @@
using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
+pldm_instance_db* pldmInstanceIdDb = nullptr;
+
+PLDMInstanceManager::PLDMInstanceManager()
+{
+ initPLDMInstanceIdDb();
+}
+
+PLDMInstanceManager::~PLDMInstanceManager()
+{
+ destroyPLDMInstanceIdDb();
+}
+
+void PLDMInstanceManager::initPLDMInstanceIdDb()
+{
+ auto rc = pldm_instance_db_init_default(&pldmInstanceIdDb);
+ if (rc)
+ {
+ lg2::error("Error calling pldm_instance_db_init_default, rc = {RC}",
+ "RC", rc);
+ elog<NotAllowed>(Reason(
+ "Required host dump action via pldm is not allowed due "
+ "to pldm_open failed"));
+ }
+}
+
+void PLDMInstanceManager::destroyPLDMInstanceIdDb()
+{
+ auto rc = pldm_instance_db_destroy(pldmInstanceIdDb);
+ if (rc)
+ {
+ lg2::error("pldm_instance_db_destroy failed rc = {RC}", "RC", rc);
+ }
+}
+
+pldm_instance_id_t getPLDMInstanceID(uint8_t tid)
+{
+ pldm_instance_id_t instanceID = 0;
+
+ auto rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
+ if (rc == -EAGAIN)
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID);
+ }
+
+ if (rc)
+ {
+ lg2::error("Failed to get instance id, rc = {RC}", "RC", rc);
+ elog<NotAllowed>(Reason(
+ "Failure in communicating with libpldm service, "
+ "service may not be running"));
+ }
+ lg2::info("Got instanceId: {INSTANCE_ID} from PLDM eid: {EID}",
+ "INSTANCE_ID", instanceID, "EID", tid);
+
+ return instanceID;
+}
+
+void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid)
+{
+ auto rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID);
+ if (rc)
+ {
+ lg2::error(
+ "pldm_instance_id_free failed to free id = {ID} of tid = {TID} rc = {RC}",
+ "ID", instanceID, "TID", tid, "RC", rc);
+ }
+}
+
int openPLDM()
{
auto fd = pldm_open();
@@ -34,36 +105,6 @@
return fd;
}
-uint8_t getPLDMInstanceID(uint8_t eid)
-{
- constexpr auto pldmRequester = "xyz.openbmc_project.PLDM.Requester";
- constexpr auto pldm = "/xyz/openbmc_project/pldm";
- uint8_t instanceID = 0;
-
- try
- {
- auto bus = sdbusplus::bus::new_default();
- auto service = phosphor::dump::getService(bus, pldm, pldmRequester);
-
- auto method = bus.new_method_call(service.c_str(), pldm, pldmRequester,
- "GetInstanceId");
- method.append(eid);
- auto reply = bus.call(method);
-
- reply.read(instanceID);
-
- lg2::info("Got instanceId: {INSTANCE_ID} from PLDM eid: {EID}",
- "INSTANCE_ID", instanceID, "EID", eid);
- }
- catch (const sdbusplus::exception::SdBusError& e)
- {
- lg2::error("Failed to get instance id error: {ERROR}", "ERROR", e);
- elog<NotAllowed>(Reason("Failure in communicating with pldm service, "
- "service may not be running"));
- }
- return instanceID;
-}
-
} // namespace pldm
} // namespace dump
} // namespace phosphor
diff --git a/host-transport-extensions/pldm/common/pldm_utils.hpp b/host-transport-extensions/pldm/common/pldm_utils.hpp
index 80a4725..7006f5b 100644
--- a/host-transport-extensions/pldm/common/pldm_utils.hpp
+++ b/host-transport-extensions/pldm/common/pldm_utils.hpp
@@ -2,6 +2,7 @@
#pragma once
+#include <libpldm/instance-id.h>
#include <libpldm/pldm.h>
namespace phosphor
@@ -11,6 +12,31 @@
namespace pldm
{
+class PLDMInstanceManager
+{
+ public:
+ PLDMInstanceManager(const PLDMInstanceManager&) = delete;
+ PLDMInstanceManager& operator=(const PLDMInstanceManager&) = delete;
+
+ PLDMInstanceManager();
+ ~PLDMInstanceManager();
+
+ private:
+ /**
+ * @brief Instantiates an instance ID database object
+ *
+ * @return void
+ **/
+ void initPLDMInstanceIdDb();
+
+ /**
+ * @brief Destroys an instance ID database object
+ *
+ * @return void
+ **/
+ void destroyPLDMInstanceIdDb();
+};
+
/**
* @brief Opens the PLDM file descriptor
*
@@ -23,11 +49,21 @@
/**
* @brief Returns the PLDM instance ID to use for PLDM commands
*
- * @param[in] eid - The PLDM EID
+ * @param[in] tid - the terminus ID the instance ID is associated with
*
- * @return uint8_t - The instance ID
+ * @return pldm_instance_id_t - The instance ID
**/
-uint8_t getPLDMInstanceID(uint8_t eid);
+pldm_instance_id_t getPLDMInstanceID(uint8_t tid);
+
+/**
+ * @brief Free the PLDM instance ID
+ *
+ * @param[in] tid - the terminus ID the instance ID is associated with
+ * @param[in] instanceID - The PLDM instance ID
+ *
+ * @return void
+ **/
+void freePLDMInstanceID(pldm_instance_id_t instanceID, uint8_t tid);
} // namespace pldm
} // namespace dump
diff --git a/host-transport-extensions/pldm/oem/ibm/pldm_oem_cmds.cpp b/host-transport-extensions/pldm/oem/ibm/pldm_oem_cmds.cpp
index 8e7d2ec..34d602e 100644
--- a/host-transport-extensions/pldm/oem/ibm/pldm_oem_cmds.cpp
+++ b/host-transport-extensions/pldm/oem/ibm/pldm_oem_cmds.cpp
@@ -61,6 +61,8 @@
constexpr auto eidPath = "/usr/share/pldm/host_eid";
constexpr mctp_eid_t defaultEIDValue = 9;
+PLDMInstanceManager instanceManager;
+
using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
@@ -119,6 +121,7 @@
if (rc != PLDM_SUCCESS)
{
+ freePLDMInstanceID(instanceID, eid);
lg2::error("Message encode failure. RC: {RC}", "RC", rc);
elog<NotAllowed>(Reason("Host dump offload via pldm is not "
"allowed due to encode failed"));
@@ -132,12 +135,14 @@
rc = pldm_send(eid, fd(), requestMsg.data(), requestMsg.size());
if (rc < 0)
{
+ freePLDMInstanceID(instanceID, eid);
auto e = errno;
lg2::error("pldm_send failed, RC: {RC}, errno: {ERRNO}", "RC", rc,
"ERRNO", e);
elog<NotAllowed>(Reason("Host dump offload via pldm is not "
"allowed due to fileack send failed"));
}
+ freePLDMInstanceID(instanceID, eid);
lg2::info("Done. PLDM message, id: {ID}, RC: {RC}", "ID", id, "RC", rc);
}
@@ -172,6 +177,7 @@
if (retCode != PLDM_SUCCESS)
{
+ freePLDMInstanceID(pldmInstanceId, mctpEndPointId);
lg2::error(
"Failed to encode pldm FileAck to delete host dump, "
"SRC_DUMP_ID: {SRC_DUMP_ID}, PLDM_FILE_IO_TYPE: {PLDM_DUMP_TYPE}, "
@@ -188,6 +194,7 @@
fileAckReqMsg.size());
if (retCode != PLDM_REQUESTER_SUCCESS)
{
+ freePLDMInstanceID(pldmInstanceId, mctpEndPointId);
auto errorNumber = errno;
lg2::error(
"Failed to send pldm FileAck to delete host dump, "
@@ -202,6 +209,7 @@
"allowed due to fileack send failed"));
}
+ freePLDMInstanceID(pldmInstanceId, mctpEndPointId);
lg2::info(
"Sent request to host to delete the dump, SRC_DUMP_ID: {SRC_DUMP_ID}",
"SRC_DUMP_ID", dumpId);