xref: /openbmc/hiomapd/vpnor/test/tmpd.hpp (revision 81365bf820abcf2b411522b1dac09b8274dee663)
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /* Copyright (C) 2018 IBM Corp. */
3 
4 #include "config.h"
5 
6 extern "C" {
7 #include "backend.h"
8 #include "mboxd.h"
9 }
10 
11 #include "vpnor/table.hpp"
12 
13 #include <cassert>
14 #include <cstring>
15 #include <filesystem>
16 #include <fstream>
17 #include <vector>
18 
19 namespace openpower
20 {
21 namespace virtual_pnor
22 {
23 namespace test
24 {
25 
26 namespace fs = std::filesystem;
27 
28 class VpnorRoot
29 {
30   public:
31     template <std::size_t N>
VpnorRoot(struct backend * backend,const std::string (& toc)[N],size_t blockSize)32     VpnorRoot(struct backend* backend, const std::string (&toc)[N],
33               size_t blockSize) : backend(backend)
34     {
35         char tmplt[] = "/tmp/vpnor_root.XXXXXX";
36         char* tmpdir = mkdtemp(tmplt);
37         root = fs::path{tmpdir};
38 
39         for (const auto& attr : attributes)
40         {
41             fs::create_directory(root / attr);
42         }
43 
44         fs::path tocFilePath = root / "ro" / PARTITION_TOC_FILE;
45 
46         for (const std::string& line : toc)
47         {
48             pnor_partition part;
49 
50             openpower::virtual_pnor::parseTocLine(line, blockSize, part);
51 
52             /* Populate the partition in the tree */
53             std::vector<char> zeroed(part.data.actual, 0);
54             fs::path partitionFilePath = root / "ro" / part.data.name;
55             std::ofstream(partitionFilePath)
56                 .write(zeroed.data(), zeroed.size());
57 
58             /* Update the ToC if the partition file was created */
59             std::ofstream(tocFilePath, std::ofstream::app) << line << "\n";
60         }
61 
62         vpnor_partition_paths paths{};
63 
64         snprintf(paths.ro_loc, PATH_MAX - 1, "%s/ro", root.c_str());
65         paths.ro_loc[PATH_MAX - 1] = '\0';
66         snprintf(paths.rw_loc, PATH_MAX - 1, "%s/rw", root.c_str());
67         paths.rw_loc[PATH_MAX - 1] = '\0';
68         snprintf(paths.prsv_loc, PATH_MAX - 1, "%s/prsv", root.c_str());
69         paths.prsv_loc[PATH_MAX - 1] = '\0';
70         snprintf(paths.patch_loc, PATH_MAX - 1, "%s/patch", root.c_str());
71         paths.patch_loc[PATH_MAX - 1] = '\0';
72 
73         if (backend_probe_vpnor(backend, &paths))
74         {
75             throw std::system_error(errno, std::system_category());
76         }
77     }
78 
79     VpnorRoot(const VpnorRoot&) = delete;
80     VpnorRoot& operator=(const VpnorRoot&) = delete;
81     VpnorRoot(VpnorRoot&&) = delete;
82     VpnorRoot& operator=(VpnorRoot&&) = delete;
83 
~VpnorRoot()84     ~VpnorRoot()
85     {
86         backend_free(backend);
87         fs::remove_all(root);
88     }
ro()89     fs::path ro()
90     {
91         return fs::path{root} / "ro";
92     }
rw()93     fs::path rw()
94     {
95         return fs::path{root} / "rw";
96     }
prsv()97     fs::path prsv()
98     {
99         return fs::path{root} / "prsv";
100     }
patch()101     fs::path patch()
102     {
103         return fs::path{root} / "patch";
104     }
105     size_t write(const std::string& name, const void* data, size_t len);
106     size_t patch(const std::string& name, const void* data, size_t len);
107 
108   private:
109     struct backend* backend;
110     fs::path root;
111     const std::string attributes[4] = {"ro", "rw", "prsv", "patch"};
112 };
113 
114 } // namespace test
115 } // namespace virtual_pnor
116 } // namespace openpower
117