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