Break out filesystem watcher into separate file
EventServiceManager is very large. Break out two of the functions, and
the global variables into a separate compile unit.
Code is copied as-is, with no improvements made in this patch.
Tested: At end of series.
Change-Id: I89a3605885e5bafa86a6083f1ff8c5db3bb8daf9
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/meson.build b/meson.build
index 86b0ed4..6fa3aa5 100644
--- a/meson.build
+++ b/meson.build
@@ -343,6 +343,7 @@
'http/mutual_tls.cpp',
'redfish-core/src/error_messages.cpp',
'redfish-core/src/event_log.cpp',
+ 'redfish-core/src/filesystem_log_watcher.cpp',
'redfish-core/src/filter_expr_executor.cpp',
'redfish-core/src/filter_expr_printer.cpp',
'redfish-core/src/redfish.cpp',
diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp
index a50c0d7..a0d70a7 100644
--- a/redfish-core/include/event_service_manager.hpp
+++ b/redfish-core/include/event_service_manager.hpp
@@ -19,6 +19,7 @@
#include "event_log.hpp"
#include "event_matches_filter.hpp"
#include "event_service_store.hpp"
+#include "filesystem_log_watcher.hpp"
#include "metric_report.hpp"
#include "ossl_random.hpp"
#include "persistent_data.hpp"
@@ -53,18 +54,7 @@
static constexpr const char* eventServiceFile =
"/var/lib/bmcweb/eventservice_config.json";
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-static std::optional<boost::asio::posix::stream_descriptor> inotifyConn;
-static constexpr const char* redfishEventLogDir = "/var/log";
static constexpr const char* redfishEventLogFile = "/var/log/redfish";
-static constexpr const size_t iEventSize = sizeof(inotify_event);
-
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-static int inotifyFd = -1;
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-static int dirWatchDesc = -1;
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-static int fileWatchDesc = -1;
class EventServiceManager
{
@@ -697,155 +687,6 @@
}
}
- static void watchRedfishEventLogFile()
- {
- if (!inotifyConn)
- {
- BMCWEB_LOG_ERROR("inotify Connection is not present");
- return;
- }
-
- static std::array<char, 1024> readBuffer;
-
- inotifyConn->async_read_some(
- boost::asio::buffer(readBuffer),
- [&](const boost::system::error_code& ec,
- const std::size_t& bytesTransferred) {
- if (ec == boost::asio::error::operation_aborted)
- {
- BMCWEB_LOG_DEBUG("Inotify was canceled (shutdown?)");
- return;
- }
- if (ec)
- {
- BMCWEB_LOG_ERROR("Callback Error: {}", ec.message());
- return;
- }
-
- BMCWEB_LOG_DEBUG("reading {} via inotify", bytesTransferred);
-
- std::size_t index = 0;
- while ((index + iEventSize) <= bytesTransferred)
- {
- struct inotify_event event
- {};
- std::memcpy(&event, &readBuffer[index], iEventSize);
- if (event.wd == dirWatchDesc)
- {
- if ((event.len == 0) ||
- (index + iEventSize + event.len > bytesTransferred))
- {
- index += (iEventSize + event.len);
- continue;
- }
-
- std::string fileName(&readBuffer[index + iEventSize]);
- if (fileName != "redfish")
- {
- index += (iEventSize + event.len);
- continue;
- }
-
- BMCWEB_LOG_DEBUG(
- "Redfish log file created/deleted. event.name: {}",
- fileName);
- if (event.mask == IN_CREATE)
- {
- if (fileWatchDesc != -1)
- {
- BMCWEB_LOG_DEBUG(
- "Remove and Add inotify watcher on "
- "redfish event log file");
- // Remove existing inotify watcher and add
- // with new redfish event log file.
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
- }
-
- fileWatchDesc = inotify_add_watch(
- inotifyFd, redfishEventLogFile, IN_MODIFY);
- if (fileWatchDesc == -1)
- {
- BMCWEB_LOG_ERROR("inotify_add_watch failed for "
- "redfish log file.");
- return;
- }
-
- EventServiceManager::getInstance()
- .resetRedfishFilePosition();
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
- }
- else if ((event.mask == IN_DELETE) ||
- (event.mask == IN_MOVED_TO))
- {
- if (fileWatchDesc != -1)
- {
- inotify_rm_watch(inotifyFd, fileWatchDesc);
- fileWatchDesc = -1;
- }
- }
- }
- else if (event.wd == fileWatchDesc)
- {
- if (event.mask == IN_MODIFY)
- {
- EventServiceManager::getInstance()
- .readEventLogsFromFile();
- }
- }
- index += (iEventSize + event.len);
- }
-
- watchRedfishEventLogFile();
- });
- }
-
- static int startEventLogMonitor(boost::asio::io_context& ioc)
- {
- BMCWEB_LOG_DEBUG("starting Event Log Monitor");
-
- inotifyConn.emplace(ioc);
- inotifyFd = inotify_init1(IN_NONBLOCK);
- if (inotifyFd == -1)
- {
- BMCWEB_LOG_ERROR("inotify_init1 failed.");
- return -1;
- }
-
- // Add watch on directory to handle redfish event log file
- // create/delete.
- dirWatchDesc = inotify_add_watch(inotifyFd, redfishEventLogDir,
- IN_CREATE | IN_MOVED_TO | IN_DELETE);
- if (dirWatchDesc == -1)
- {
- BMCWEB_LOG_ERROR(
- "inotify_add_watch failed for event log directory.");
- return -1;
- }
-
- // Watch redfish event log file for modifications.
- fileWatchDesc =
- inotify_add_watch(inotifyFd, redfishEventLogFile, IN_MODIFY);
- if (fileWatchDesc == -1)
- {
- BMCWEB_LOG_ERROR("inotify_add_watch failed for redfish log file.");
- // Don't return error if file not exist.
- // Watch on directory will handle create/delete of file.
- }
-
- // monitor redfish event log file
- inotifyConn->assign(inotifyFd);
- watchRedfishEventLogFile();
-
- return 0;
- }
-
- static void stopEventLogMonitor()
- {
- inotifyConn.reset();
- }
-
static void getReadingsForReport(sdbusplus::message_t& msg)
{
if (msg.is_method_error())
diff --git a/redfish-core/include/filesystem_log_watcher.hpp b/redfish-core/include/filesystem_log_watcher.hpp
new file mode 100644
index 0000000..d12af50
--- /dev/null
+++ b/redfish-core/include/filesystem_log_watcher.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <boost/asio/io_context.hpp>
+
+namespace redfish
+{
+int startEventLogMonitor(boost::asio::io_context& ioc);
+void stopEventLogMonitor();
+} // namespace redfish
diff --git a/redfish-core/src/filesystem_log_watcher.cpp b/redfish-core/src/filesystem_log_watcher.cpp
new file mode 100644
index 0000000..699700a
--- /dev/null
+++ b/redfish-core/src/filesystem_log_watcher.cpp
@@ -0,0 +1,181 @@
+#include "filesystem_log_watcher.hpp"
+
+#include "event_service_manager.hpp"
+#include "logging.hpp"
+
+#include <sys/inotify.h>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/posix/stream_descriptor.hpp>
+
+#include <array>
+#include <cstddef>
+#include <cstring>
+#include <optional>
+#include <string>
+
+namespace redfish
+{
+
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static std::optional<boost::asio::posix::stream_descriptor> inotifyConn;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static int inotifyFd = -1;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static int dirWatchDesc = -1;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static int fileWatchDesc = -1;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static std::array<char, 1024> readBuffer{};
+
+static constexpr const char* redfishEventLogDir = "/var/log";
+static constexpr const size_t iEventSize = sizeof(inotify_event);
+
+static void watchRedfishEventLogFile()
+{
+ if (!inotifyConn)
+ {
+ BMCWEB_LOG_ERROR("inotify Connection is not present");
+ return;
+ }
+
+ inotifyConn->async_read_some(
+ boost::asio::buffer(readBuffer),
+ [&](const boost::system::error_code& ec,
+ const std::size_t& bytesTransferred) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ BMCWEB_LOG_DEBUG("Inotify was canceled (shutdown?)");
+ return;
+ }
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR("Callback Error: {}", ec.message());
+ return;
+ }
+
+ BMCWEB_LOG_DEBUG("reading {} via inotify", bytesTransferred);
+
+ std::size_t index = 0;
+ while ((index + iEventSize) <= bytesTransferred)
+ {
+ struct inotify_event event
+ {};
+ std::memcpy(&event, &readBuffer[index], iEventSize);
+ if (event.wd == dirWatchDesc)
+ {
+ if ((event.len == 0) ||
+ (index + iEventSize + event.len > bytesTransferred))
+ {
+ index += (iEventSize + event.len);
+ continue;
+ }
+
+ std::string fileName(&readBuffer[index + iEventSize]);
+ if (fileName != "redfish")
+ {
+ index += (iEventSize + event.len);
+ continue;
+ }
+
+ BMCWEB_LOG_DEBUG(
+ "Redfish log file created/deleted. event.name: {}",
+ fileName);
+ if (event.mask == IN_CREATE)
+ {
+ if (fileWatchDesc != -1)
+ {
+ BMCWEB_LOG_DEBUG(
+ "Remove and Add inotify watcher on "
+ "redfish event log file");
+ // Remove existing inotify watcher and add
+ // with new redfish event log file.
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
+
+ fileWatchDesc = inotify_add_watch(
+ inotifyFd, redfishEventLogFile, IN_MODIFY);
+ if (fileWatchDesc == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_add_watch failed for "
+ "redfish log file.");
+ return;
+ }
+
+ EventServiceManager::getInstance()
+ .resetRedfishFilePosition();
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
+ else if ((event.mask == IN_DELETE) ||
+ (event.mask == IN_MOVED_TO))
+ {
+ if (fileWatchDesc != -1)
+ {
+ inotify_rm_watch(inotifyFd, fileWatchDesc);
+ fileWatchDesc = -1;
+ }
+ }
+ }
+ else if (event.wd == fileWatchDesc)
+ {
+ if (event.mask == IN_MODIFY)
+ {
+ EventServiceManager::getInstance()
+ .readEventLogsFromFile();
+ }
+ }
+ index += (iEventSize + event.len);
+ }
+
+ watchRedfishEventLogFile();
+ });
+}
+
+int startEventLogMonitor(boost::asio::io_context& ioc)
+{
+ BMCWEB_LOG_DEBUG("starting Event Log Monitor");
+
+ inotifyConn.emplace(ioc);
+ inotifyFd = inotify_init1(IN_NONBLOCK);
+ if (inotifyFd == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_init1 failed.");
+ return -1;
+ }
+
+ // Add watch on directory to handle redfish event log file
+ // create/delete.
+ dirWatchDesc = inotify_add_watch(inotifyFd, redfishEventLogDir,
+ IN_CREATE | IN_MOVED_TO | IN_DELETE);
+ if (dirWatchDesc == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_add_watch failed for event log directory.");
+ return -1;
+ }
+
+ // Watch redfish event log file for modifications.
+ fileWatchDesc =
+ inotify_add_watch(inotifyFd, redfishEventLogFile, IN_MODIFY);
+ if (fileWatchDesc == -1)
+ {
+ BMCWEB_LOG_ERROR("inotify_add_watch failed for redfish log file.");
+ // Don't return error if file not exist.
+ // Watch on directory will handle create/delete of file.
+ }
+
+ // monitor redfish event log file
+ inotifyConn->assign(inotifyFd);
+ watchRedfishEventLogFile();
+
+ return 0;
+}
+
+void stopEventLogMonitor()
+{
+ inotifyConn.reset();
+}
+} // namespace redfish
diff --git a/src/webserver_run.cpp b/src/webserver_run.cpp
index b037860..dfed2b7 100644
--- a/src/webserver_run.cpp
+++ b/src/webserver_run.cpp
@@ -6,6 +6,7 @@
#include "dbus_monitor.hpp"
#include "dbus_singleton.hpp"
#include "event_service_manager.hpp"
+#include "filesystem_log_watcher.hpp"
#include "google/google_service_root.hpp"
#include "hostname_monitor.hpp"
#include "ibm/management_console_rest.hpp"
@@ -117,7 +118,7 @@
if constexpr (!BMCWEB_REDFISH_DBUS_LOG)
{
- int rc = redfish::EventServiceManager::startEventLogMonitor(*io);
+ int rc = redfish::startEventLogMonitor(*io);
if (rc != 0)
{
BMCWEB_LOG_ERROR("Redfish event handler setup failed...");
@@ -142,7 +143,7 @@
crow::connections::systemBus = nullptr;
// TODO(ed) Make event log monitor an RAII object instead of global vars
- redfish::EventServiceManager::stopEventLogMonitor();
+ redfish::stopEventLogMonitor();
return 0;
}