summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure.ac2
-rw-r--r--sync_manager.cpp66
-rw-r--r--sync_manager.hpp8
-rw-r--r--sync_manager_main.cpp3
-rw-r--r--sync_watch.cpp39
-rw-r--r--sync_watch.hpp4
6 files changed, 115 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index 1155cfe..0165e08 100755
--- a/configure.ac
+++ b/configure.ac
@@ -96,6 +96,8 @@ AC_DEFINE(MEDIA_DIR, "/media/",
[The base dir where all RO partitions are mounted])
AC_DEFINE(BMC_ROFS_PREFIX, "/media/rofs-",
[The prefix path for the versioned read-only bmc partitions])
+AC_DEFINE(ALT_RWFS, "/media/alt/var/persist",
+ [The path of the alt rwfs overlay])
AC_DEFINE(PERSIST_DIR, "/var/lib/obmc/phosphor-bmc-code-mgmt/",
[The dir where activation data is stored in files])
AC_DEFINE(SYSTEMD_BUSNAME, "org.freedesktop.systemd1",
diff --git a/sync_manager.cpp b/sync_manager.cpp
index 6a50711..f83aebd 100644
--- a/sync_manager.cpp
+++ b/sync_manager.cpp
@@ -1,3 +1,9 @@
+#include <experimental/filesystem>
+#include <phosphor-logging/log.hpp>
+#include <sys/inotify.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include "config.h"
#include "sync_manager.hpp"
namespace phosphor
@@ -7,8 +13,66 @@ namespace software
namespace manager
{
-int Sync::processEntry()
+using namespace phosphor::logging;
+namespace fs = std::experimental::filesystem;
+
+int Sync::processEntry(int mask, const fs::path& entryPath)
{
+ int status{};
+ pid_t pid = fork();
+
+ if (pid == 0)
+ {
+ fs::path dst(ALT_RWFS / entryPath);
+
+ // rsync needs an additional --delete argument to handle file deletions
+ // so need to differentiate between the different file events.
+ if (mask & IN_CLOSE_WRITE)
+ {
+ if (!(fs::exists(dst)))
+ {
+ if (fs::is_directory(entryPath))
+ {
+ // Source is a directory, create it at the destination.
+ fs::create_directories(dst);
+ }
+ else
+ {
+ // Source is a file, create the directory where this file
+ // resides at the destination.
+ fs::create_directories(dst.parent_path());
+ }
+ }
+
+ execl("/usr/bin/rsync", "rsync", "-a", entryPath.c_str(),
+ dst.c_str(), nullptr);
+ // execl only returns on fail
+ log<level::ERR>("Error occurred during the rsync call",
+ entry("ERRNO=%d", errno),
+ entry("PATH=%s", entryPath.c_str()));
+ return -1;
+ }
+ else if (mask & IN_DELETE)
+ {
+ execl("/usr/bin/rsync", "rsync", "-a", "--delete",
+ entryPath.c_str(), dst.c_str(), nullptr);
+ // execl only returns on fail
+ log<level::ERR>("Error occurred during the rsync delete call",
+ entry("ERRNO=%d", errno),
+ entry("PATH=%s", entryPath.c_str()));
+ return -1;
+ }
+ }
+ else if (pid > 0)
+ {
+ waitpid(pid, &status, 0);
+ }
+ else
+ {
+ log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", errno));
+ return -1;
+ }
+
return 0;
}
diff --git a/sync_manager.hpp b/sync_manager.hpp
index a940461..45bfca4 100644
--- a/sync_manager.hpp
+++ b/sync_manager.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include <experimental/filesystem>
+
namespace phosphor
{
namespace software
@@ -7,6 +9,8 @@ namespace software
namespace manager
{
+namespace fs = std::experimental::filesystem;
+
/** @class Sync
* @brief Contains filesystem sync functions.
* @details The software manager class that contains functions to perform
@@ -24,9 +28,11 @@ class Sync
/**
* @brief Process requested file or directory.
+ * @param[in] mask - The inotify mask.
+ * @param[in] entryPath - The file or directory to process.
* @param[out] result - 0 if successful.
*/
- int processEntry();
+ int processEntry(int mask, const fs::path& entryPath);
};
} // namespace manager
diff --git a/sync_manager_main.cpp b/sync_manager_main.cpp
index 46a2d95..e1834b5 100644
--- a/sync_manager_main.cpp
+++ b/sync_manager_main.cpp
@@ -23,7 +23,8 @@ int main(int argc, char* argv[])
using namespace phosphor::software::manager;
phosphor::software::manager::SyncWatch watch(
- *loop, std::bind(std::mem_fn(&Sync::processEntry), &syncManager));
+ *loop, std::bind(std::mem_fn(&Sync::processEntry), &syncManager,
+ std::placeholders::_1, std::placeholders::_2));
bus.attach_event(loop, SD_EVENT_PRIORITY_NORMAL);
sd_event_loop(loop);
}
diff --git a/sync_watch.cpp b/sync_watch.cpp
index 0fc61d8..a8b4eeb 100644
--- a/sync_watch.cpp
+++ b/sync_watch.cpp
@@ -17,7 +17,7 @@ using namespace phosphor::logging;
namespace fs = std::experimental::filesystem;
SyncWatch::SyncWatch(sd_event& loop,
- std::function<int(fs::path&)> syncCallback) :
+ std::function<int(int, fs::path&)> syncCallback) :
syncCallback(syncCallback)
{
auto syncfile = fs::path(SYNC_LIST_DIR_PATH) / SYNC_LIST_FILE_NAME;
@@ -37,7 +37,8 @@ SyncWatch::SyncWatch(sd_event& loop,
continue;
}
- auto wd = inotify_add_watch(fd, line.c_str(), IN_CLOSE_WRITE);
+ auto wd =
+ inotify_add_watch(fd, line.c_str(), IN_CLOSE_WRITE | IN_DELETE);
if (-1 == wd)
{
log<level::ERR>("inotify_add_watch failed",
@@ -81,6 +82,40 @@ SyncWatch::~SyncWatch()
int SyncWatch::callback(sd_event_source* s, int fd, uint32_t revents,
void* userdata)
{
+ if (!(revents & EPOLLIN))
+ {
+ return 0;
+ }
+
+ constexpr auto maxBytes = 1024;
+ uint8_t buffer[maxBytes];
+ auto bytes = read(fd, buffer, maxBytes);
+ if (0 > bytes)
+ {
+ return 0;
+ }
+
+ auto syncWatch = static_cast<SyncWatch*>(userdata);
+ auto offset = 0;
+ while (offset < bytes)
+ {
+ auto event = reinterpret_cast<inotify_event*>(&buffer[offset]);
+
+ // fileMap<fd, std::map<wd, path>>
+ auto it1 = syncWatch->fileMap.find(fd);
+ if (it1 != syncWatch->fileMap.end())
+ {
+ auto it2 = it1->second.begin();
+ auto rc = syncWatch->syncCallback(event->mask, it2->second);
+ if (rc)
+ {
+ return rc;
+ }
+ }
+
+ offset += offsetof(inotify_event, name) + event->len;
+ }
+
return 0;
}
diff --git a/sync_watch.hpp b/sync_watch.hpp
index a7f8557..4303671 100644
--- a/sync_watch.hpp
+++ b/sync_watch.hpp
@@ -29,7 +29,7 @@ class SyncWatch
* @param[in] syncCallback - The callback function for processing
* files
*/
- SyncWatch(sd_event& loop, std::function<int(fs::path&)> syncCallback);
+ SyncWatch(sd_event& loop, std::function<int(int, fs::path&)> syncCallback);
SyncWatch(const SyncWatch&) = delete;
SyncWatch& operator=(const SyncWatch&) = delete;
@@ -58,7 +58,7 @@ class SyncWatch
std::map<fd, std::map<wd, fs::path>> fileMap;
/** @brief The callback function for processing the inotify event */
- std::function<int(fs::path&)> syncCallback;
+ std::function<int(int, fs::path&)> syncCallback;
};
} // namespace manager
OpenPOWER on IntegriCloud