xref: /openbmc/phosphor-bmc-code-mgmt/sync_manager.cpp (revision e80b5bcb42d3d6ed094b52840543299ffb45be01)
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 
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