summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdriana Kobylak <anoo@us.ibm.com>2018-11-09 11:39:46 -0600
committerAdriana Kobylak <anoo@us.ibm.com>2018-11-26 11:29:58 -0600
commit3a19e62a59f317e5fae70054f6d8dafe985d8105 (patch)
treed2456897d486f69412ca3ccb0643b7f51f403c7e
parent43699ca702068934add136309f28fa427c0d88e6 (diff)
downloadphosphor-bmc-code-mgmt-3a19e62a59f317e5fae70054f6d8dafe985d8105.zip
phosphor-bmc-code-mgmt-3a19e62a59f317e5fae70054f6d8dafe985d8105.tar.gz
sync_watch: Handle IN_IGNORED
When the hostname is updated via systemd, it modifies the /etc/hostname file in a way that triggers a IN_CLOSE_NOWRITE and IN_IGNORED signal. * When IN_IGNORED is received, re-subscribe the file, since it means that the inotify watch was removed. * A subsequent IN_CLOSE_WRITE signal is received after the re-subscribe which takes care of syncing the hostname file. Tested: The hostname was synced when changed multiple times in a row using the REST API. Change-Id: I30abfcdc8b33f77adc6349d345cc957b07898018 Signed-off-by: Adriana Kobylak <anoo@us.ibm.com>
-rw-r--r--sync_watch.cpp88
-rw-r--r--sync_watch.hpp9
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
OpenPOWER on IntegriCloud