Add Clear method
There was an issue where the first SEL records share Record ID 1 if
they are generated around the same time. The cause was determined to
be that several records get assigned Record ID 1 because the
/var/log/ipmi_sel was checked and missing. The file was removed by
the IPMI handlers that use this file to store the SEL. This does not
apply to IPMI handlers that use phosphor-logging to store SEL entries.
Although, a future iteration could add support for removing SEL
entries in phosphor-logging.
This change adds a method to clear the IPMI SEL that removes the
/var/log/ipmi_sel and refreshes rsyslog. The IPMI handlers that use
this file would no longer be responsible for directly clearing SEL.
Now that phosphor-sel-logger can handle the clear of SEL, the logic
for Record ID is simplified.
The Clear method is put behind an optional flag for systems
experiencing the issue with Record ID 1 and use ipmi_sel. This
implementation is alternative to the efforts in
https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-sel-logger/+/44533
making it obsolete.
Note:
- https://gerrit.openbmc-project.xyz/c/openbmc/phosphor-dbus-interfaces
/+/45402 is required.
- Do not use send-to-logger option with clears-sel
Tested with clears-sel:
- The Clear method will remove the /var/log/ipmi_sel files and refresh
rsyslog and Record ID count.
- Each record has its own unique Record ID.
- New records added after restarting xyz.openbmc_project.Logging.IPMI
will continue Record ID count where it left off.
Signed-off-by: Charles Boyer <Charles.Boyer@fii-usa.com>
Change-Id: I9037aba409eaf99fa06fd8ea84ef888669966eea
diff --git a/meson.build b/meson.build
index 225fd47..dc663d2 100644
--- a/meson.build
+++ b/meson.build
@@ -35,6 +35,9 @@
'phosphor-logging',
fallback: ['phosphor-logging', 'phosphor_logging_dep'])
endif
+if get_option('clears-sel')
+ cpp_args += '-DSEL_LOGGER_CLEARS_SEL'
+endif
executable(
'sel-logger',
diff --git a/meson_options.txt b/meson_options.txt
index f1449a0..1a1cd51 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -8,3 +8,5 @@
description: 'Monitor threshold alarm signals and log SEL records for threshold sensor events')
option('send-to-logger', type: 'boolean',
description: 'Automatically log events to Redfish for pulse type assert-deassert sensor events')
+option('clears-sel', type: 'boolean',
+ description: 'Expose method for SEL Logger to clear the SEL records stored in ipmi_sel')
diff --git a/src/sel_logger.cpp b/src/sel_logger.cpp
index c3271f7..afbbaee 100644
--- a/src/sel_logger.cpp
+++ b/src/sel_logger.cpp
@@ -114,8 +114,45 @@
return std::stoul(newestEntryFields[1]);
}
+#ifdef SEL_LOGGER_CLEARS_SEL
+static unsigned int recordId = initializeRecordId();
+
+void clearSelLogFiles()
+{
+ // Clear the SEL by deleting the log files
+ std::vector<std::filesystem::path> selLogFiles;
+ if (getSELLogFiles(selLogFiles))
+ {
+ for (const std::filesystem::path& file : selLogFiles)
+ {
+ std::error_code ec;
+ std::filesystem::remove(file, ec);
+ }
+ }
+
+ recordId = selInvalidRecID;
+
+ // Reload rsyslog so it knows to start new log files
+ boost::asio::io_service io;
+ auto dbus = std::make_shared<sdbusplus::asio::connection>(io);
+ sdbusplus::message::message rsyslogReload = dbus->new_method_call(
+ "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager", "ReloadUnit");
+ rsyslogReload.append("rsyslog.service", "replace");
+ try
+ {
+ sdbusplus::message::message reloadResponse = dbus->call(rsyslogReload);
+ }
+ catch (sdbusplus::exception_t& e)
+ {
+ std::cerr << e.what() << "\n";
+ }
+}
+#endif
+
static unsigned int getNewRecordId(void)
{
+#ifndef SEL_LOGGER_CLEARS_SEL
static unsigned int recordId = initializeRecordId();
// If the log has been cleared, also clear the current ID
@@ -124,6 +161,7 @@
{
recordId = selInvalidRecID;
}
+#endif
if (++recordId >= selInvalidRecID)
{
@@ -236,6 +274,13 @@
const uint8_t& recordType) {
return selAddOemRecord(message, selData, recordType);
});
+
+#ifdef SEL_LOGGER_CLEARS_SEL
+#ifndef SEL_LOGGER_SEND_TO_LOGGING_SERVICE
+ // Clear SEL entries
+ ifaceAddSel->register_method("Clear", []() { clearSelLogFiles(); });
+#endif
+#endif
ifaceAddSel->initialize();
#ifdef SEL_LOGGER_MONITOR_THRESHOLD_EVENTS