blob: bdf8ac4794673931cda7622b6a0990ece719dfb1 [file] [log] [blame]
Gunnar Millsb0ce9962018-09-07 13:39:10 -05001#include "config.h"
2
3#include "sync_manager.hpp"
4
Adriana Kobylaka9074342018-05-08 11:52:44 -05005#include <sys/inotify.h>
6#include <sys/wait.h>
7#include <unistd.h>
Gunnar Millsb0ce9962018-09-07 13:39:10 -05008
Gunnar Millsb0ce9962018-09-07 13:39:10 -05009#include <phosphor-logging/log.hpp>
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050010
Adriana Kobylak58aa7502020-06-08 11:12:11 -050011#include <filesystem>
12
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050013namespace phosphor
14{
15namespace software
16{
17namespace manager
18{
19
Adriana Kobylaka9074342018-05-08 11:52:44 -050020using namespace phosphor::logging;
Adriana Kobylakc98d9122020-05-05 10:36:01 -050021namespace fs = std::filesystem;
Adriana Kobylaka9074342018-05-08 11:52:44 -050022
23int Sync::processEntry(int mask, const fs::path& entryPath)
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050024{
Adriana Kobylaka9074342018-05-08 11:52:44 -050025 int status{};
26 pid_t pid = fork();
27
28 if (pid == 0)
29 {
Adriana Kobylakc98d9122020-05-05 10:36:01 -050030 fs::path dst(ALT_RWFS);
31 dst /= entryPath.relative_path();
Adriana Kobylaka9074342018-05-08 11:52:44 -050032
33 // rsync needs an additional --delete argument to handle file deletions
34 // so need to differentiate between the different file events.
35 if (mask & IN_CLOSE_WRITE)
36 {
37 if (!(fs::exists(dst)))
38 {
39 if (fs::is_directory(entryPath))
40 {
41 // Source is a directory, create it at the destination.
42 fs::create_directories(dst);
43 }
44 else
45 {
46 // Source is a file, create the directory where this file
47 // resides at the destination.
48 fs::create_directories(dst.parent_path());
49 }
50 }
51
52 execl("/usr/bin/rsync", "rsync", "-a", entryPath.c_str(),
53 dst.c_str(), nullptr);
54 // execl only returns on fail
55 log<level::ERR>("Error occurred during the rsync call",
56 entry("ERRNO=%d", errno),
57 entry("PATH=%s", entryPath.c_str()));
58 return -1;
59 }
60 else if (mask & IN_DELETE)
61 {
62 execl("/usr/bin/rsync", "rsync", "-a", "--delete",
63 entryPath.c_str(), dst.c_str(), nullptr);
64 // execl only returns on fail
65 log<level::ERR>("Error occurred during the rsync delete call",
66 entry("ERRNO=%d", errno),
67 entry("PATH=%s", entryPath.c_str()));
68 return -1;
69 }
70 }
71 else if (pid > 0)
72 {
73 waitpid(pid, &status, 0);
74 }
75 else
76 {
77 log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", errno));
78 return -1;
79 }
80
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050081 return 0;
82}
83
84} // namespace manager
85} // namespace software
Gunnar Millsfa34e022018-09-04 10:05:45 -050086} // namespace phosphor