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