diff options
-rw-r--r-- | sync_watch.cpp | 88 | ||||
-rw-r--r-- | sync_watch.hpp | 9 |
2 files changed, 60 insertions, 37 deletions
diff --git a/sync_watch.cpp b/sync_watch.cpp index c017716..88ccd89 100644 --- a/sync_watch.cpp +++ b/sync_watch.cpp @@ -19,9 +19,42 @@ namespace manager using namespace phosphor::logging; namespace fs = std::experimental::filesystem; +void SyncWatch::addInotifyWatch(const fs::path& path) +{ + auto fd = inotify_init1(IN_NONBLOCK); + if (-1 == fd) + { + log<level::ERR>("inotify_init1 failed", entry("ERRNO=%d", errno), + entry("FILENAME=%s", path.c_str())); + return; + } + + auto wd = inotify_add_watch(fd, path.c_str(), IN_CLOSE_WRITE | IN_DELETE); + if (-1 == wd) + { + log<level::ERR>("inotify_add_watch failed", entry("ERRNO=%d", errno), + entry("FILENAME=%s", path.c_str())); + close(fd); + return; + } + + auto rc = sd_event_add_io(&loop, nullptr, fd, EPOLLIN, callback, this); + if (0 > rc) + { + log<level::ERR>("failed to add to event loop", entry("RC=%d", rc), + entry("FILENAME=%s", path.c_str())); + inotify_rm_watch(fd, wd); + close(fd); + return; + } + + fileMap[fd].insert(std::make_pair(wd, fs::path(path))); +} + SyncWatch::SyncWatch(sd_event& loop, std::function<int(int, fs::path&)> syncCallback) : - syncCallback(syncCallback) + syncCallback(syncCallback), + loop(loop) { auto syncfile = fs::path(SYNC_LIST_DIR_PATH) / SYNC_LIST_FILE_NAME; if (fs::exists(syncfile)) @@ -30,42 +63,7 @@ SyncWatch::SyncWatch(sd_event& loop, std::ifstream file(syncfile.c_str()); while (std::getline(file, line)) { - auto fd = inotify_init1(IN_NONBLOCK); - if (-1 == fd) - { - log<level::ERR>("inotify_init1 failed", - entry("ERRNO=%d", errno), - entry("FILENAME=%s", line.c_str()), - entry("SYNCFILE=%s", syncfile.c_str())); - continue; - } - - auto wd = - inotify_add_watch(fd, line.c_str(), IN_CLOSE_WRITE | IN_DELETE); - if (-1 == wd) - { - log<level::ERR>("inotify_add_watch failed", - entry("ERRNO=%d", errno), - entry("FILENAME=%s", line.c_str()), - entry("SYNCFILE=%s", syncfile.c_str())); - close(fd); - continue; - } - - auto rc = - sd_event_add_io(&loop, nullptr, fd, EPOLLIN, callback, this); - if (0 > rc) - { - log<level::ERR>("failed to add to event loop", - entry("RC=%d", rc), - entry("FILENAME=%s", line.c_str()), - entry("SYNCFILE=%s", syncfile.c_str())); - inotify_rm_watch(fd, wd); - close(fd); - continue; - } - - fileMap[fd].insert(std::make_pair(wd, fs::path(line))); + addInotifyWatch(line); } } } @@ -109,6 +107,22 @@ int SyncWatch::callback(sd_event_source* s, int fd, uint32_t revents, if (it1 != syncWatch->fileMap.end()) { auto it2 = it1->second.begin(); + + // Watch was removed, re-add it if file still exists. + if (event->mask & IN_IGNORED) + { + if (fs::exists(it2->second)) + { + syncWatch->addInotifyWatch(it2->second); + } + else + { + log<level::INFO>("The inotify watch was removed", + entry("FILENAME=%s", it2->second.c_str())); + } + return 0; + } + auto rc = syncWatch->syncCallback(event->mask, it2->second); if (rc) { diff --git a/sync_watch.hpp b/sync_watch.hpp index 30ea5f7..3ad5afd 100644 --- a/sync_watch.hpp +++ b/sync_watch.hpp @@ -54,6 +54,12 @@ class SyncWatch static int callback(sd_event_source* s, int fd, uint32_t revents, void* userdata); + /** @brief Adds an inotify watch to the specified file or directory path + * + * @param[in] path - The path to the file or directory + */ + void addInotifyWatch(const fs::path& path); + /** @brief Map of file descriptors, watch descriptors, and file paths */ using fd = int; using wd = int; @@ -61,6 +67,9 @@ class SyncWatch /** @brief The callback function for processing the inotify event */ std::function<int(int, fs::path&)> syncCallback; + + /** @brief Persistent sd_event loop */ + sd_event& loop; }; } // namespace manager |