blob: d44a81ba9b32a932c81793da109fb1a417f9fd48 [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
Adriana Kobylakc98d9122020-05-05 10:36:01 -05009#include <filesystem>
Gunnar Millsb0ce9962018-09-07 13:39:10 -050010#include <phosphor-logging/log.hpp>
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050011
12namespace phosphor
13{
14namespace software
15{
16namespace manager
17{
18
Adriana Kobylaka9074342018-05-08 11:52:44 -050019using namespace phosphor::logging;
Adriana Kobylakc98d9122020-05-05 10:36:01 -050020namespace fs = std::filesystem;
Adriana Kobylaka9074342018-05-08 11:52:44 -050021
22int Sync::processEntry(int mask, const fs::path& entryPath)
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050023{
Adriana Kobylaka9074342018-05-08 11:52:44 -050024 int status{};
25 pid_t pid = fork();
26
27 if (pid == 0)
28 {
Adriana Kobylakc98d9122020-05-05 10:36:01 -050029 fs::path dst(ALT_RWFS);
30 dst /= entryPath.relative_path();
Adriana Kobylaka9074342018-05-08 11:52:44 -050031
32 // rsync needs an additional --delete argument to handle file deletions
33 // so need to differentiate between the different file events.
34 if (mask & IN_CLOSE_WRITE)
35 {
36 if (!(fs::exists(dst)))
37 {
38 if (fs::is_directory(entryPath))
39 {
40 // Source is a directory, create it at the destination.
41 fs::create_directories(dst);
42 }
43 else
44 {
45 // Source is a file, create the directory where this file
46 // resides at the destination.
47 fs::create_directories(dst.parent_path());
48 }
49 }
50
51 execl("/usr/bin/rsync", "rsync", "-a", entryPath.c_str(),
52 dst.c_str(), nullptr);
53 // execl only returns on fail
54 log<level::ERR>("Error occurred during the rsync call",
55 entry("ERRNO=%d", errno),
56 entry("PATH=%s", entryPath.c_str()));
57 return -1;
58 }
59 else if (mask & IN_DELETE)
60 {
61 execl("/usr/bin/rsync", "rsync", "-a", "--delete",
62 entryPath.c_str(), dst.c_str(), nullptr);
63 // execl only returns on fail
64 log<level::ERR>("Error occurred during the rsync delete call",
65 entry("ERRNO=%d", errno),
66 entry("PATH=%s", entryPath.c_str()));
67 return -1;
68 }
69 }
70 else if (pid > 0)
71 {
72 waitpid(pid, &status, 0);
73 }
74 else
75 {
76 log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", errno));
77 return -1;
78 }
79
Adriana Kobylakb072d1b2018-04-24 11:37:21 -050080 return 0;
81}
82
83} // namespace manager
84} // namespace software
Gunnar Millsfa34e022018-09-04 10:05:45 -050085} // namespace phosphor