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