summaryrefslogtreecommitdiffstats
path: root/sync_manager.cpp
blob: 48d773bbb073219e803f3df9b5e6d2c52ffd7201 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include "config.h"

#include "sync_manager.hpp"

#include <sys/inotify.h>
#include <sys/wait.h>
#include <unistd.h>

#include <experimental/filesystem>
#include <phosphor-logging/log.hpp>

namespace phosphor
{
namespace software
{
namespace manager
{

using namespace phosphor::logging;
namespace fs = std::experimental::filesystem;

int Sync::processEntry(int mask, const fs::path& entryPath)
{
    int status{};
    pid_t pid = fork();

    if (pid == 0)
    {
        fs::path dst(ALT_RWFS / entryPath);

        // rsync needs an additional --delete argument to handle file deletions
        // so need to differentiate between the different file events.
        if (mask & IN_CLOSE_WRITE)
        {
            if (!(fs::exists(dst)))
            {
                if (fs::is_directory(entryPath))
                {
                    // Source is a directory, create it at the destination.
                    fs::create_directories(dst);
                }
                else
                {
                    // Source is a file, create the directory where this file
                    // resides at the destination.
                    fs::create_directories(dst.parent_path());
                }
            }

            execl("/usr/bin/rsync", "rsync", "-a", entryPath.c_str(),
                  dst.c_str(), nullptr);
            // execl only returns on fail
            log<level::ERR>("Error occurred during the rsync call",
                            entry("ERRNO=%d", errno),
                            entry("PATH=%s", entryPath.c_str()));
            return -1;
        }
        else if (mask & IN_DELETE)
        {
            execl("/usr/bin/rsync", "rsync", "-a", "--delete",
                  entryPath.c_str(), dst.c_str(), nullptr);
            // execl only returns on fail
            log<level::ERR>("Error occurred during the rsync delete call",
                            entry("ERRNO=%d", errno),
                            entry("PATH=%s", entryPath.c_str()));
            return -1;
        }
    }
    else if (pid > 0)
    {
        waitpid(pid, &status, 0);
    }
    else
    {
        log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", errno));
        return -1;
    }

    return 0;
}

} // namespace manager
} // namespace software
} // namespace phosphor
OpenPOWER on IntegriCloud