summaryrefslogtreecommitdiffstats
path: root/vpnor/test/tmpd.hpp
blob: ae6da9e2a738de0f358823866d33355d062dd54d (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/* SPDX-License-Identifier: Apache-2.0 */
/* Copyright (C) 2018 IBM Corp. */

#include "config.h"

extern "C" {
#include "backend.h"
#include "mboxd.h"
}

#include "vpnor/table.hpp"

#include <cassert>
#include <cstring>
#include <experimental/filesystem>
#include <fstream>
#include <vector>

namespace openpower
{
namespace virtual_pnor
{
namespace test
{

namespace fs = std::experimental::filesystem;

class VpnorRoot
{
  public:
    template <std::size_t N>
    VpnorRoot(struct backend* backend, const std::string (&toc)[N],
              size_t blockSize) :
        backend(backend)
    {
        char tmplt[] = "/tmp/vpnor_root.XXXXXX";
        char* tmpdir = mkdtemp(tmplt);
        root = fs::path{tmpdir};

        for (const auto& attr : attributes)
        {
            fs::create_directory(root / attr);
        }

        fs::path tocFilePath = root / "ro" / PARTITION_TOC_FILE;

        for (const std::string& line : toc)
        {
            pnor_partition part;

            openpower::virtual_pnor::parseTocLine(line, blockSize, part);

            /* Populate the partition in the tree */
            std::vector<char> zeroed(part.data.actual, 0);
            fs::path partitionFilePath = root / "ro" / part.data.name;
            std::ofstream(partitionFilePath)
                .write(zeroed.data(), zeroed.size());

            /* Update the ToC if the partition file was created */
            std::ofstream(tocFilePath, std::ofstream::app) << line << "\n";
        }

        vpnor_partition_paths paths{};

        snprintf(paths.ro_loc, PATH_MAX - 1, "%s/ro", root.c_str());
        paths.ro_loc[PATH_MAX - 1] = '\0';
        snprintf(paths.rw_loc, PATH_MAX - 1, "%s/rw", root.c_str());
        paths.rw_loc[PATH_MAX - 1] = '\0';
        snprintf(paths.prsv_loc, PATH_MAX - 1, "%s/prsv", root.c_str());
        paths.prsv_loc[PATH_MAX - 1] = '\0';
        snprintf(paths.patch_loc, PATH_MAX - 1, "%s/patch", root.c_str());
        paths.patch_loc[PATH_MAX - 1] = '\0';

        if (backend_probe_vpnor(backend, &paths))
        {
            throw std::system_error(errno, std::system_category());
        }
    }

    VpnorRoot(const VpnorRoot&) = delete;
    VpnorRoot& operator=(const VpnorRoot&) = delete;
    VpnorRoot(VpnorRoot&&) = delete;
    VpnorRoot& operator=(VpnorRoot&&) = delete;

    ~VpnorRoot()
    {
        backend_free(backend);
        fs::remove_all(root);
    }
    fs::path ro()
    {
        return fs::path{root} / "ro";
    }
    fs::path rw()
    {
        return fs::path{root} / "rw";
    }
    fs::path prsv()
    {
        return fs::path{root} / "prsv";
    }
    fs::path patch()
    {
        return fs::path{root} / "patch";
    }
    size_t write(const std::string& name, const void* data, size_t len);
    size_t patch(const std::string& name, const void* data, size_t len);

  private:
    struct backend* backend;
    fs::path root;
    const std::string attributes[4] = {"ro", "rw", "prsv", "patch"};
};

} // namespace test
} // namespace virtual_pnor
} // namespace openpower
OpenPOWER on IntegriCloud