summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--selutility.hpp17
-rw-r--r--storagehandler.cpp104
-rw-r--r--storagehandler.h1
3 files changed, 122 insertions, 0 deletions
diff --git a/selutility.hpp b/selutility.hpp
index 50babca..2cae8c3 100644
--- a/selutility.hpp
+++ b/selutility.hpp
@@ -88,6 +88,23 @@ struct DeleteSELEntryRequest
uint16_t selRecordID; //!< SEL Record ID.
} __attribute__((packed));
+static constexpr auto initiateErase = 0xAA;
+static constexpr auto getEraseStatus = 0x00;
+static constexpr auto eraseComplete = 0x01;
+
+/** @struct ClearSELRequest
+ *
+ * IPMI payload for Clear SEL command request.
+ */
+struct ClearSELRequest
+{
+ uint16_t reservationID; //!< Reservation ID.
+ uint8_t charC; //!< Char 'C'(0x43h).
+ uint8_t charL; //!< Char 'L'(0x4Ch).
+ uint8_t charR; //!< Char 'R'(0x52h).
+ uint8_t eraseOperation; //!< Erase operation.
+} __attribute__((packed));
+
/** @brief Convert logging entry to SEL
*
* @param[in] objPath - DBUS object path of the logging entry.
diff --git a/storagehandler.cpp b/storagehandler.cpp
index cd6f10c..5ded63e 100644
--- a/storagehandler.cpp
+++ b/storagehandler.cpp
@@ -296,6 +296,105 @@ ipmi_ret_t deleteSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return IPMI_CC_OK;
}
+ipmi_ret_t clearSEL(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)
+{
+ auto requestData = reinterpret_cast<const ipmi::sel::ClearSELRequest*>
+ (request);
+
+ if (g_sel_reserve != requestData->reservationID)
+ {
+ *data_len = 0;
+ return IPMI_CC_INVALID_RESERVATION_ID;
+ }
+
+ if (requestData->charC != 'C' ||
+ requestData->charL != 'L' ||
+ requestData->charR != 'R')
+ {
+ *data_len = 0;
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ uint8_t eraseProgress = ipmi::sel::eraseComplete;
+
+ /*
+ * Erasure status cannot be fetched from DBUS, so always return erasure
+ * status as `erase completed`.
+ */
+ if (requestData->eraseOperation == ipmi::sel::getEraseStatus)
+ {
+ memcpy(response, &eraseProgress, sizeof(eraseProgress));
+ *data_len = sizeof(eraseProgress);
+ return IPMI_CC_OK;
+ }
+
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ auto depth = 0;
+
+ auto mapperCall = bus.new_method_call(ipmi::sel::mapperBusName,
+ ipmi::sel::mapperObjPath,
+ ipmi::sel::mapperIntf,
+ "GetSubTreePaths");
+ mapperCall.append(ipmi::sel::logBasePath);
+ mapperCall.append(depth);
+ mapperCall.append(ipmi::sel::ObjectPaths({ipmi::sel::logEntryIntf}));
+
+ auto reply = bus.call(mapperCall);
+ if (reply.is_method_error())
+ {
+ memcpy(response, &eraseProgress, sizeof(eraseProgress));
+ *data_len = sizeof(eraseProgress);
+ return IPMI_CC_OK;
+ }
+
+ ipmi::sel::ObjectPaths objectPaths;
+ reply.read(objectPaths);
+ if (objectPaths.empty())
+ {
+ memcpy(response, &eraseProgress, sizeof(eraseProgress));
+ *data_len = sizeof(eraseProgress);
+ return IPMI_CC_OK;
+ }
+
+ std::string service;
+
+ try
+ {
+ service = ipmi::getService(bus,
+ ipmi::sel::logDeleteIntf,
+ objectPaths.front());
+ }
+ catch (const std::runtime_error& e)
+ {
+ log<level::ERR>(e.what());
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ for (const auto& iter : objectPaths)
+ {
+ auto methodCall = bus.new_method_call(service.c_str(),
+ iter.c_str(),
+ ipmi::sel::logDeleteIntf,
+ "Delete");
+
+ auto reply = bus.call(methodCall);
+ if (reply.is_method_error())
+ {
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ }
+
+ // Invalidate the cache of dbus entry objects.
+ cache::paths.clear();
+ memcpy(response, &eraseProgress, sizeof(eraseProgress));
+ *data_len = sizeof(eraseProgress);
+ 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)
@@ -516,6 +615,11 @@ void register_netfn_storage_functions()
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_ADD_SEL);
ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_ADD_SEL, NULL, ipmi_storage_add_sel,
PRIVILEGE_OPERATOR);
+
+ // <Clear SEL>
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_CLEAR_SEL);
+ ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_CLEAR_SEL, NULL, clearSEL,
+ PRIVILEGE_OPERATOR);
return;
}
diff --git a/storagehandler.h b/storagehandler.h
index e39d676..9973d14 100644
--- a/storagehandler.h
+++ b/storagehandler.h
@@ -10,6 +10,7 @@ enum ipmi_netfn_storage_cmds
IPMI_CMD_GET_SEL_ENTRY = 0x43,
IPMI_CMD_ADD_SEL = 0x44,
IPMI_CMD_DELETE_SEL = 0x46,
+ IPMI_CMD_CLEAR_SEL = 0x47,
IPMI_CMD_GET_SEL_TIME = 0x48,
IPMI_CMD_SET_SEL_TIME = 0x49,
OpenPOWER on IntegriCloud