From 6f7deaa034b1cfd7640b1c21616c6807900d5609 Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Fri, 30 Jun 2017 19:03:54 +0530 Subject: Add Get SEL Info command Change-Id: I8caa38ee461d6c570a6d7ab73376eb6aea701391 Signed-off-by: Tom Joseph --- selutility.hpp | 18 ++++++++++ storagehandler.cpp | 99 +++++++++++++++++++++++++++++++++++++++--------------- 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>; +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 #include #include +#include "selutility.hpp" #include "storagehandler.h" #include "storageaddsel.h" #include "host-ipmid/ipmid-api.h" +#include +#include +#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 outPayload(sizeof(ipmi::sel::GetSELInfoResponse)); + auto responseData = reinterpret_cast + (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(cache::paths.size()); + + try + { + responseData->addTimeStamp = static_cast( + (ipmi::sel::getEntryTimeStamp(cache::paths.back()) + .count())); + } + catch (InternalFailure& e) + { + } + catch (const std::runtime_error& e) + { + log(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); + // + 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); + // 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); - // - 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); - // 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, -- cgit v1.2.1