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