summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Joseph <tomjoseph@in.ibm.com>2017-06-30 19:03:54 +0530
committerPatrick Williams <patrick@stwcx.xyz>2017-07-19 19:54:41 +0000
commit6f7deaa034b1cfd7640b1c21616c6807900d5609 (patch)
tree6d8b433686f5401d8116d9048da0c3886fa3a420
parent399fd92ec41cd23a9a5cb30f5d41397e5d8c6306 (diff)
downloadphosphor-host-ipmid-6f7deaa034b1cfd7640b1c21616c6807900d5609.tar.gz
phosphor-host-ipmid-6f7deaa034b1cfd7640b1c21616c6807900d5609.zip
Add Get SEL Info command
Change-Id: I8caa38ee461d6c570a6d7ab73376eb6aea701391 Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
-rw-r--r--selutility.hpp18
-rw-r--r--storagehandler.cpp99
2 files changed, 89 insertions, 28 deletions
diff --git a/selutility.hpp b/selutility.hpp
index 09104a3..9c253bd 100644
--- a/selutility.hpp
+++ b/selutility.hpp
@@ -23,6 +23,24 @@ static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
using PropertyType = sdbusplus::message::variant<bool, uint32_t, uint64_t,
std::string, std::vector<std::string>>;
+static constexpr auto selVersion = 0x51;
+static constexpr auto invalidTimeStamp = 0xFFFFFFFF;
+static constexpr auto operationSupport = 0x0A;
+
+/** @struct GetSELInfoResponse
+ *
+ * IPMI payload for Get SEL Info command response.
+ */
+struct GetSELInfoResponse
+{
+ uint8_t selVersion; //!< SEL revision.
+ uint16_t entries; //!< Number of log entries in SEL.
+ uint16_t freeSpace; //!< Free Space in bytes.
+ uint32_t addTimeStamp; //!< Most recent addition timestamp.
+ uint32_t eraseTimeStamp; //!< Most recent erase timestamp.
+ uint8_t operationSupport; //!< Operation support.
+} __attribute__((packed));
+
/** @struct GetSELEntryResponse
*
* IPMI payload for Get SEL Entry command response.
diff --git a/storagehandler.cpp b/storagehandler.cpp
index e02dd19..bbcb441 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -4,9 +4,13 @@
#include <systemd/sd-bus.h>
#include <mapper.h>
#include <chrono>
+#include "selutility.hpp"
#include "storagehandler.h"
#include "storageaddsel.h"
#include "host-ipmid/ipmid-api.h"
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/server.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
void register_netfn_storage_functions() __attribute__((constructor));
@@ -17,6 +21,26 @@ extern unsigned short g_sel_reserve;
constexpr auto time_manager_intf = "org.openbmc.TimeManager";
constexpr auto time_manager_obj = "/org/openbmc/TimeManager";
+namespace cache
+{
+ /*
+ * This cache contains the object paths of the logging entries sorted in the
+ * order of the filename(numeric order). The cache is initialized by
+ * invoking readLoggingObjectPaths with the cache as the parameter. The
+ * cache is invoked in the execution of the Get SEL info and Delete SEL
+ * entry command. The Get SEL Info command is typically invoked before the
+ * Get SEL entry command, so the cache is utilized for responding to Get SEL
+ * entry command. The cache is invalidated by clearing after Delete SEL
+ * entry and Clear SEL command.
+ */
+ ipmi::sel::ObjectPaths paths;
+
+} // namespace objectPathsCache
+
+using InternalFailure =
+ sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+using namespace phosphor::logging;
+
ipmi_ret_t ipmi_storage_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -28,6 +52,48 @@ ipmi_ret_t ipmi_storage_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
+ipmi_ret_t getSELInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request, ipmi_response_t response,
+ ipmi_data_len_t data_len, ipmi_context_t context)
+{
+ std::vector<uint8_t> outPayload(sizeof(ipmi::sel::GetSELInfoResponse));
+ auto responseData = reinterpret_cast<ipmi::sel::GetSELInfoResponse*>
+ (outPayload.data());
+
+ responseData->selVersion = ipmi::sel::selVersion;
+ // Last erase timestamp is not available from log manager.
+ responseData->eraseTimeStamp = ipmi::sel::invalidTimeStamp;
+ responseData->operationSupport = ipmi::sel::operationSupport;
+
+ ipmi::sel::readLoggingObjectPaths(cache::paths);
+ responseData->entries = 0;
+ responseData->addTimeStamp = ipmi::sel::invalidTimeStamp;
+
+ if (!cache::paths.empty())
+ {
+ responseData->entries = static_cast<uint16_t>(cache::paths.size());
+
+ try
+ {
+ responseData->addTimeStamp = static_cast<uint32_t>(
+ (ipmi::sel::getEntryTimeStamp(cache::paths.back())
+ .count()));
+ }
+ catch (InternalFailure& e)
+ {
+ }
+ catch (const std::runtime_error& e)
+ {
+ log<level::ERR>(e.what());
+ }
+ }
+
+ memcpy(response, outPayload.data(), outPayload.size());
+ *data_len = outPayload.size();
+
+ return IPMI_CC_OK;
+}
+
ipmi_ret_t ipmi_storage_get_sel_time(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -162,29 +228,6 @@ finish:
return rc;
}
-ipmi_ret_t ipmi_storage_get_sel_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
- ipmi_request_t request, ipmi_response_t response,
- ipmi_data_len_t data_len, ipmi_context_t context)
-{
-
- ipmi_ret_t rc = IPMI_CC_OK;
- unsigned char buf[] = {0x51,0,0,0xff, 0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0x06};
-
- printf("IPMI Handling GET-SEL-INFO\n");
-
- *data_len = sizeof(buf);
-
- // TODO There is plently of work here. The SEL DB needs to hold a bunch
- // of things in a header. Items like Time Stamp, number of entries, etc
- // This is one place where the dbus object with the SEL information could
- // mimic what IPMI needs.
-
- // Pack the actual response
- memcpy(response, &buf, *data_len);
-
- return rc;
-}
-
ipmi_ret_t ipmi_storage_reserve_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -237,6 +280,11 @@ void register_netfn_storage_functions()
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_WILDCARD, NULL, ipmi_storage_wildcard,
PRIVILEGE_USER);
+ // <Get SEL Info>
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO);
+ ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO, NULL, getSELInfo,
+ PRIVILEGE_USER);
+
// <Get SEL Time>
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_TIME);
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_TIME, NULL, ipmi_storage_get_sel_time,
@@ -247,11 +295,6 @@ void register_netfn_storage_functions()
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_SET_SEL_TIME, NULL, ipmi_storage_set_sel_time,
PRIVILEGE_OPERATOR);
- // <Get SEL Info>
- printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO);
- ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_GET_SEL_INFO, NULL, ipmi_storage_get_sel_info,
- PRIVILEGE_USER);
-
// <Reserve SEL>
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL);
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_RESERVE_SEL, NULL, ipmi_storage_reserve_sel,
OpenPOWER on IntegriCloud