diff options
author | Jason M. Bills <jason.m.bills@linux.intel.com> | 2018-09-10 14:12:16 -0700 |
---|---|---|
committer | Jason M. Bills <jason.m.bills@linux.intel.com> | 2018-10-05 12:51:24 -0700 |
commit | 13e67c8d43064d58fb8c4cc7757abb823e3ac51e (patch) | |
tree | 7968046289cc1e2b87dd69c423efa291d257e39d /storagehandler.cpp | |
parent | 1cd85963972719312a0017b59e29d90e1baa4ce5 (diff) | |
download | phosphor-host-ipmid-13e67c8d43064d58fb8c4cc7757abb823e3ac51e.tar.gz phosphor-host-ipmid-13e67c8d43064d58fb8c4cc7757abb823e3ac51e.zip |
Fix IPMI SEL reservations and cancellations
Per the IPMI Spec, the SEL must be reserved to
Delete an entry
Clear the SEL
Get a partial entry
Add a partial entry
The current SEL reservation must be cancelled when
A SEL entry is added
A SEL entry is deleted
The SEL is cleared
The device is reset
A new reservation is requested
This change adds a reservation status to track when a reservation
is active and a method to cancel the current reservation, and it
uses that to cancel the reservation in the Delete, Clear, and Add
SEL methods.
Change-Id: Ifd72e6d06ecc622855bd9ce8cc3928cbd0f2c34b
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
Diffstat (limited to 'storagehandler.cpp')
-rw-r--r-- | storagehandler.cpp | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/storagehandler.cpp b/storagehandler.cpp index 65497b2..0a46b83 100644 --- a/storagehandler.cpp +++ b/storagehandler.cpp @@ -38,7 +38,6 @@ namespace filesystem = std::experimental::filesystem; void register_netfn_storage_functions() __attribute__((constructor)); unsigned int g_sel_time = 0xFFFFFFFF; -extern unsigned short g_sel_reserve; extern const ipmi::sensor::IdInfoMap sensors; extern const FruMap frus; @@ -161,7 +160,7 @@ ipmi_ret_t getSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd, if (requestData->reservationID != 0) { - if (g_sel_reserve != requestData->reservationID) + if (!checkSELReservation(requestData->reservationID)) { *data_len = 0; return IPMI_CC_INVALID_RESERVATION_ID; @@ -275,12 +274,16 @@ ipmi_ret_t deleteSELEntry(ipmi_netfn_t netfn, ipmi_cmd_t cmd, auto requestData = reinterpret_cast<const ipmi::sel::DeleteSELEntryRequest*>(request); - if (g_sel_reserve != requestData->reservationID) + if (!checkSELReservation(requestData->reservationID)) { *data_len = 0; return IPMI_CC_INVALID_RESERVATION_ID; } + // Per the IPMI spec, need to cancel the reservation when a SEL entry is + // deleted + cancelSELReservation(); + try { ipmi::sel::readLoggingObjectPaths(cache::paths); @@ -368,7 +371,7 @@ ipmi_ret_t clearSEL(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, auto requestData = reinterpret_cast<const ipmi::sel::ClearSELRequest*>(request); - if (g_sel_reserve != requestData->reservationID) + if (!checkSELReservation(requestData->reservationID)) { *data_len = 0; return IPMI_CC_INVALID_RESERVATION_ID; @@ -394,6 +397,9 @@ ipmi_ret_t clearSEL(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, return IPMI_CC_OK; } + // Per the IPMI spec, need to cancel any reservation when the SEL is cleared + cancelSELReservation(); + sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()}; ipmi::sel::ObjectPaths objectPaths; auto depth = 0; @@ -581,16 +587,12 @@ ipmi_ret_t ipmi_storage_reserve_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_context_t context) { ipmi_ret_t rc = IPMI_CC_OK; + unsigned short selResID = reserveSel(); - // IPMI spec, Reservation ID, the value simply increases against each - // execution of reserve_sel command. - if (++g_sel_reserve == 0) - g_sel_reserve = 1; - - *data_len = sizeof(g_sel_reserve); + *data_len = sizeof(selResID); // Pack the actual response - std::memcpy(response, &g_sel_reserve, *data_len); + std::memcpy(response, &selResID, *data_len); return rc; } @@ -606,9 +608,13 @@ ipmi_ret_t ipmi_storage_add_sel(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_add_sel_request_t* p = (ipmi_add_sel_request_t*)request; uint16_t recordid; + // Per the IPMI spec, need to cancel the reservation when a SEL entry is + // added + cancelSELReservation(); + recordid = ((uint16_t)p->eventdata[1] << 8) | p->eventdata[2]; - *data_len = sizeof(g_sel_reserve); + *data_len = sizeof(recordid); // Pack the actual response std::memcpy(response, &p->eventdata[1], 2); |