xref: /openbmc/phosphor-bmc-code-mgmt/sync_manager.cpp (revision 44b9fef9bf49eacfa0743e93316c31c6c9645870)
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", "-a", entryPath.c_str(),
55                   dst.c_str(), nullptr);
56             // execl only returns on fail
57             error("Error ({ERRNO}) occurred during the rsync call on {PATH}",
58                   "ERRNO", errno, "PATH", entryPath);
59             return -1;
60         }
61         else if (mask & IN_DELETE)
62         {
63             execl("/usr/bin/rsync", "rsync", "-a", "--delete",
64                   entryPath.c_str(), dst.c_str(), nullptr);
65             // execl only returns on fail
66             error(
67                 "Error ({ERRNO}) occurred during the rsync delete call on {PATH}",
68                 "ERRNO", errno, "PATH", entryPath);
69             return -1;
70         }
71     }
72     else if (pid > 0)
73     {
74         waitpid(pid, &status, 0);
75     }
76     else
77     {
78         error("Error ({ERRNO}) occurred during fork", "ERRNO", errno);
79         return -1;
80     }
81 
82     return 0;
83 }
84 
85 } // namespace manager
86 } // namespace software
87 } // namespace phosphor
88