Track the SEL erase time
It is useful to know the last time SEL Clear was called, so
save the timestamp in a file and return it in the Get SEL Info
response.
Tested:
Ran 'ipmitool sel info' and noted the time.
Ran 'ipmitool sel clear'
Ran 'ipmitool sel info' and confirmed time had updated.
Change-Id: I81626a3bc78ffe06316a14422fab4f42a9f18217
Signed-off-by: Jason M. Bills <jason.m.bills@linux.intel.com>
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index 1d294f9..b8bfd56 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -29,6 +29,50 @@
#include <storagecommands.hpp>
#include <string_view>
+namespace intel_oem::ipmi::sel::erase_time
+{
+static constexpr const char* selEraseTimestamp = "/var/lib/ipmi/sel_erase_time";
+
+void save()
+{
+ // open the file, creating it if necessary
+ int fd = open(selEraseTimestamp, O_WRONLY | O_CREAT | O_CLOEXEC, 0644);
+ if (fd < 0)
+ {
+ std::cerr << "Failed to open file\n";
+ return;
+ }
+
+ // update the file timestamp to the current time
+ if (futimens(fd, NULL) < 0)
+ {
+ std::cerr << "Failed to update timestamp: "
+ << std::string(strerror(errno));
+ }
+ close(fd);
+}
+
+int get()
+{
+ struct stat st;
+ // default to an invalid timestamp
+ int timestamp = ::ipmi::sel::invalidTimeStamp;
+
+ int fd = open(selEraseTimestamp, O_RDWR | O_CLOEXEC, 0644);
+ if (fd < 0)
+ {
+ return timestamp;
+ }
+
+ if (fstat(fd, &st) >= 0)
+ {
+ timestamp = st.st_mtime;
+ }
+
+ return timestamp;
+}
+} // namespace intel_oem::ipmi::sel::erase_time
+
namespace ipmi
{
@@ -519,12 +563,13 @@
static_cast<ipmi::sel::GetSELInfoResponse*>(response);
responseData->selVersion = ipmi::sel::selVersion;
- // Last erase timestamp is not available from log manager.
- responseData->eraseTimeStamp = ipmi::sel::invalidTimeStamp;
responseData->addTimeStamp = ipmi::sel::invalidTimeStamp;
responseData->operationSupport = intel_oem::ipmi::sel::selOperationSupport;
responseData->entries = 0;
+ // Fill in the last erase time
+ responseData->eraseTimeStamp = intel_oem::ipmi::sel::erase_time::get();
+
// Open the journal
sd_journal* journalTmp = nullptr;
if (int ret = sd_journal_open(&journalTmp, SD_JOURNAL_LOCAL_ONLY); ret < 0)
@@ -1039,6 +1084,9 @@
// Per the IPMI spec, need to cancel any reservation when the SEL is cleared
cancelSELReservation();
+ // Save the erase time
+ intel_oem::ipmi::sel::erase_time::save();
+
// Clear the SEL by by rotating the journal to start a new file then
// vacuuming to keep only the new file
if (boost::process::system("/bin/journalctl", "--rotate") != 0)