1 #include "config.h"
2
3 #include "sync_manager.hpp"
4
5 #include <sys/inotify.h>
6 #include <sys/wait.h>
7 #include <unistd.h>
8
9 #include <phosphor-logging/lg2.hpp>
10
11 #include <filesystem>
12 #include <system_error>
13
14 namespace phosphor
15 {
16 namespace software
17 {
18 namespace manager
19 {
20
21 PHOSPHOR_LOG2_USING;
22 namespace fs = std::filesystem;
23
processEntry(int mask,const fs::path & entryPath)24 int Sync::processEntry(int mask, const fs::path& entryPath)
25 {
26 int status{};
27 pid_t pid = fork();
28
29 if (pid == 0)
30 {
31 fs::path dst(ALT_RWFS);
32 dst /= entryPath.relative_path();
33
34 // rsync needs an additional --delete argument to handle file deletions
35 // so need to differentiate between the different file events.
36 if (mask & IN_CLOSE_WRITE)
37 {
38 std::error_code ec;
39 if (!(fs::exists(dst, ec)))
40 {
41 if (fs::is_directory(entryPath, ec))
42 {
43 // Source is a directory, create it at the destination.
44 fs::create_directories(dst, ec);
45 }
46 else
47 {
48 // Source is a file, create the directory where this file
49 // resides at the destination.
50 fs::create_directories(dst.parent_path(), ec);
51 }
52 }
53
54 execl("/usr/bin/rsync", "rsync", "-aI", entryPath.c_str(),
55 dst.c_str(), nullptr);
56
57 // execl only returns on fail
58 error("Error ({ERRNO}) occurred during the rsync call on {PATH}",
59 "ERRNO", errno, "PATH", entryPath);
60 return -1;
61 }
62 else if (mask & IN_DELETE)
63 {
64 execl("/usr/bin/rsync", "rsync", "-a", "--delete",
65 entryPath.c_str(), dst.c_str(), nullptr);
66 // execl only returns on fail
67 error(
68 "Error ({ERRNO}) occurred during the rsync delete call on {PATH}",
69 "ERRNO", errno, "PATH", entryPath);
70 return -1;
71 }
72 }
73 else if (pid > 0)
74 {
75 waitpid(pid, &status, 0);
76 }
77 else
78 {
79 error("Error ({ERRNO}) occurred during fork", "ERRNO", errno);
80 return -1;
81 }
82
83 return 0;
84 }
85
86 } // namespace manager
87 } // namespace software
88 } // namespace phosphor
89