Move journal sync function to util.cpp
Move it out of log_manager.cpp so other code will be able to call it.
The code itself wasn't changed, though a comment was modified, as it is
now a utility function it may no longer just be called when an error log
is created.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I33a20c1a68059fd50678464776e88168ce93d030
diff --git a/log_manager.cpp b/log_manager.cpp
index f2d1ef6..23e7bd6 100644
--- a/log_manager.cpp
+++ b/log_manager.cpp
@@ -8,8 +8,6 @@
#include "extensions.hpp"
#include "util.hpp"
-#include <poll.h>
-#include <sys/inotify.h>
#include <systemd/sd-bus.h>
#include <systemd/sd-journal.h>
#include <unistd.h>
@@ -100,7 +98,7 @@
static constexpr auto transactionIdVarOffset = transactionIdVarSize + 1;
// Flush all the pending log messages into the journal
- journalSync();
+ util::journalSync();
sd_journal* j = nullptr;
int rc = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
@@ -609,150 +607,6 @@
}
}
-void Manager::journalSync()
-{
- bool syncRequested = false;
- auto fd = -1;
- auto rc = -1;
- auto wd = -1;
- auto bus = sdbusplus::bus::new_default();
-
- auto start =
- duration_cast<microseconds>(steady_clock::now().time_since_epoch())
- .count();
-
- // Each time an error log is committed, a request to sync the journal
- // must occur and block that error log commit until it completes. A 5sec
- // block is done to allow sufficient time for the journal to be synced.
- //
- // Number of loop iterations = 3 for the following reasons:
- // Iteration #1: Requests a journal sync by killing the journald service.
- // Iteration #2: Setup an inotify watch to monitor the synced file that
- // journald updates with the timestamp the last time the
- // journal was flushed.
- // Iteration #3: Poll to wait until inotify reports an event which blocks
- // the error log from being commited until the sync completes.
- constexpr auto maxRetry = 3;
- for (int i = 0; i < maxRetry; i++)
- {
- // Read timestamp from synced file
- constexpr auto syncedPath = "/run/systemd/journal/synced";
- std::ifstream syncedFile(syncedPath);
- if (syncedFile.fail())
- {
- // If the synced file doesn't exist, a sync request will create it.
- if (errno != ENOENT)
- {
- lg2::error(
- "Failed to open journal synced file {FILENAME}: {ERROR}",
- "FILENAME", syncedPath, "ERROR", strerror(errno));
- return;
- }
- }
- else
- {
- // Only read the synced file if it exists.
- // See if a sync happened by now
- std::string timestampStr;
- std::getline(syncedFile, timestampStr);
- auto timestamp = std::stoll(timestampStr);
- if (timestamp >= start)
- {
- break;
- }
- }
-
- // Let's ask for a sync, but only once
- if (!syncRequested)
- {
- syncRequested = true;
-
- constexpr auto JOURNAL_UNIT = "systemd-journald.service";
- auto signal = SIGRTMIN + 1;
-
- auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH,
- SYSTEMD_INTERFACE, "KillUnit");
- method.append(JOURNAL_UNIT, "main", signal);
- bus.call(method);
- if (method.is_method_error())
- {
- lg2::error("Failed to kill journal service");
- break;
- }
-
- continue;
- }
-
- // Let's install the inotify watch, if we didn't do that yet. This watch
- // monitors the syncedFile for when journald updates it with a newer
- // timestamp. This means the journal has been flushed.
- if (fd < 0)
- {
- fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
- if (fd < 0)
- {
- lg2::error("Failed to create inotify watch: {ERROR}", "ERROR",
- strerror(errno));
- return;
- }
-
- constexpr auto JOURNAL_RUN_PATH = "/run/systemd/journal";
- wd = inotify_add_watch(fd, JOURNAL_RUN_PATH,
- IN_MOVED_TO | IN_DONT_FOLLOW | IN_ONLYDIR);
- if (wd < 0)
- {
- lg2::error("Failed to watch journal directory: {PATH}: {ERROR}",
- "PATH", JOURNAL_RUN_PATH, "ERROR", strerror(errno));
- close(fd);
- return;
- }
- continue;
- }
-
- // Let's wait until inotify reports an event
- struct pollfd fds = {
- fd,
- POLLIN,
- 0,
- };
- constexpr auto pollTimeout = 5; // 5 seconds
- rc = poll(&fds, 1, pollTimeout * 1000);
- if (rc < 0)
- {
- lg2::error("Failed to add event: {ERROR}", "ERROR",
- strerror(errno));
- inotify_rm_watch(fd, wd);
- close(fd);
- return;
- }
- else if (rc == 0)
- {
- lg2::info("Poll timeout ({TIMEOUT}), no new journal synced data",
- "TIMEOUT", pollTimeout);
- break;
- }
-
- // Read from the specified file descriptor until there is no new data,
- // throwing away everything read since the timestamp will be read at the
- // beginning of the loop.
- constexpr auto maxBytes = 64;
- uint8_t buffer[maxBytes];
- while (read(fd, buffer, maxBytes) > 0)
- ;
- }
-
- if (fd != -1)
- {
- if (wd != -1)
- {
- inotify_rm_watch(fd, wd);
- }
- close(fd);
- }
-
- return;
-}
-
std::string Manager::readFWVersion()
{
auto version = util::getOSReleaseValue("VERSION_ID");