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