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;
 }