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