130bcf84cSAndrew Jeffery /* SPDX-License-Identifier: Apache-2.0 */ 230bcf84cSAndrew Jeffery /* Copyright (C) 2018 IBM Corp. */ 330bcf84cSAndrew Jeffery 4d5f1d40fSWilliam A. Kennington III #include "config.h" 5d5f1d40fSWilliam A. Kennington III 6261f61a1SAndrew Jeffery extern "C" { 7*f1e547c7SEvan Lojewski #include "backend.h" 8261f61a1SAndrew Jeffery #include "mboxd.h" 9261f61a1SAndrew Jeffery } 10261f61a1SAndrew Jeffery 11d5f1d40fSWilliam A. Kennington III #include "vpnor/pnor_partition_table.hpp" 12d5f1d40fSWilliam A. Kennington III 13261f61a1SAndrew Jeffery #include <cassert> 14261f61a1SAndrew Jeffery #include <cstring> 15d5f1d40fSWilliam A. Kennington III #include <experimental/filesystem> 16d5f1d40fSWilliam A. Kennington III #include <fstream> 17d5f1d40fSWilliam A. Kennington III #include <vector> 18d5f1d40fSWilliam A. Kennington III 1930bcf84cSAndrew Jeffery namespace openpower 2030bcf84cSAndrew Jeffery { 2130bcf84cSAndrew Jeffery namespace virtual_pnor 2230bcf84cSAndrew Jeffery { 2330bcf84cSAndrew Jeffery namespace test 2430bcf84cSAndrew Jeffery { 2530bcf84cSAndrew Jeffery 2630bcf84cSAndrew Jeffery namespace fs = std::experimental::filesystem; 2730bcf84cSAndrew Jeffery 2830bcf84cSAndrew Jeffery class VpnorRoot 2930bcf84cSAndrew Jeffery { 3030bcf84cSAndrew Jeffery public: 3130bcf84cSAndrew Jeffery template <std::size_t N> 32*f1e547c7SEvan Lojewski VpnorRoot(struct backend* backend, const std::string (&toc)[N], 33*f1e547c7SEvan Lojewski size_t blockSize) : 34*f1e547c7SEvan Lojewski backend(backend) 3530bcf84cSAndrew Jeffery { 3630bcf84cSAndrew Jeffery char tmplt[] = "/tmp/vpnor_root.XXXXXX"; 3730bcf84cSAndrew Jeffery char* tmpdir = mkdtemp(tmplt); 3830bcf84cSAndrew Jeffery root = fs::path{tmpdir}; 3930bcf84cSAndrew Jeffery 4030bcf84cSAndrew Jeffery for (const auto& attr : attributes) 4130bcf84cSAndrew Jeffery { 4230bcf84cSAndrew Jeffery fs::create_directory(root / attr); 4330bcf84cSAndrew Jeffery } 4430bcf84cSAndrew Jeffery 4530bcf84cSAndrew Jeffery fs::path tocFilePath = root / "ro" / PARTITION_TOC_FILE; 4630bcf84cSAndrew Jeffery 4730bcf84cSAndrew Jeffery for (const std::string& line : toc) 4830bcf84cSAndrew Jeffery { 4930bcf84cSAndrew Jeffery pnor_partition part; 5030bcf84cSAndrew Jeffery 5130bcf84cSAndrew Jeffery openpower::virtual_pnor::parseTocLine(line, blockSize, part); 5230bcf84cSAndrew Jeffery 5330bcf84cSAndrew Jeffery /* Populate the partition in the tree */ 5430bcf84cSAndrew Jeffery std::vector<char> zeroed(part.data.actual, 0); 5530bcf84cSAndrew Jeffery fs::path partitionFilePath = root / "ro" / part.data.name; 5630bcf84cSAndrew Jeffery std::ofstream(partitionFilePath) 5730bcf84cSAndrew Jeffery .write(zeroed.data(), zeroed.size()); 5830bcf84cSAndrew Jeffery 5930bcf84cSAndrew Jeffery /* Update the ToC if the partition file was created */ 6030bcf84cSAndrew Jeffery std::ofstream(tocFilePath, std::ofstream::app) << line << "\n"; 6130bcf84cSAndrew Jeffery } 6230bcf84cSAndrew Jeffery 63*f1e547c7SEvan Lojewski vpnor_partition_paths paths{}; 64*f1e547c7SEvan Lojewski 65*f1e547c7SEvan Lojewski snprintf(paths.ro_loc, PATH_MAX - 1, "%s/ro", root.c_str()); 66*f1e547c7SEvan Lojewski paths.ro_loc[PATH_MAX - 1] = '\0'; 67*f1e547c7SEvan Lojewski snprintf(paths.rw_loc, PATH_MAX - 1, "%s/rw", root.c_str()); 68*f1e547c7SEvan Lojewski paths.rw_loc[PATH_MAX - 1] = '\0'; 69*f1e547c7SEvan Lojewski snprintf(paths.prsv_loc, PATH_MAX - 1, "%s/prsv", root.c_str()); 70*f1e547c7SEvan Lojewski paths.prsv_loc[PATH_MAX - 1] = '\0'; 71*f1e547c7SEvan Lojewski snprintf(paths.patch_loc, PATH_MAX - 1, "%s/patch", root.c_str()); 72*f1e547c7SEvan Lojewski paths.patch_loc[PATH_MAX - 1] = '\0'; 73*f1e547c7SEvan Lojewski 74*f1e547c7SEvan Lojewski if (backend_probe_vpnor(backend, &paths)) 75*f1e547c7SEvan Lojewski { 76*f1e547c7SEvan Lojewski throw std::system_error(errno, std::system_category()); 77*f1e547c7SEvan Lojewski } 7830bcf84cSAndrew Jeffery } 7930bcf84cSAndrew Jeffery 8030bcf84cSAndrew Jeffery VpnorRoot(const VpnorRoot&) = delete; 8130bcf84cSAndrew Jeffery VpnorRoot& operator=(const VpnorRoot&) = delete; 8230bcf84cSAndrew Jeffery VpnorRoot(VpnorRoot&&) = delete; 8330bcf84cSAndrew Jeffery VpnorRoot& operator=(VpnorRoot&&) = delete; 8430bcf84cSAndrew Jeffery 8530bcf84cSAndrew Jeffery ~VpnorRoot() 8630bcf84cSAndrew Jeffery { 87*f1e547c7SEvan Lojewski backend_free(backend); 8830bcf84cSAndrew Jeffery fs::remove_all(root); 8930bcf84cSAndrew Jeffery } 9030bcf84cSAndrew Jeffery fs::path ro() 9130bcf84cSAndrew Jeffery { 9230bcf84cSAndrew Jeffery return fs::path{root} / "ro"; 9330bcf84cSAndrew Jeffery } 9430bcf84cSAndrew Jeffery fs::path rw() 9530bcf84cSAndrew Jeffery { 9630bcf84cSAndrew Jeffery return fs::path{root} / "rw"; 9730bcf84cSAndrew Jeffery } 9830bcf84cSAndrew Jeffery fs::path prsv() 9930bcf84cSAndrew Jeffery { 10030bcf84cSAndrew Jeffery return fs::path{root} / "prsv"; 10130bcf84cSAndrew Jeffery } 10230bcf84cSAndrew Jeffery fs::path patch() 10330bcf84cSAndrew Jeffery { 10430bcf84cSAndrew Jeffery return fs::path{root} / "patch"; 10530bcf84cSAndrew Jeffery } 10630bcf84cSAndrew Jeffery size_t write(const std::string& name, const void* data, size_t len); 10730bcf84cSAndrew Jeffery size_t patch(const std::string& name, const void* data, size_t len); 10830bcf84cSAndrew Jeffery 10930bcf84cSAndrew Jeffery private: 110*f1e547c7SEvan Lojewski struct backend* backend; 11130bcf84cSAndrew Jeffery fs::path root; 11230bcf84cSAndrew Jeffery const std::string attributes[4] = {"ro", "rw", "prsv", "patch"}; 11330bcf84cSAndrew Jeffery }; 11430bcf84cSAndrew Jeffery 1157a03b074SAndrew Jeffery } // namespace test 1167a03b074SAndrew Jeffery } // namespace virtual_pnor 1177a03b074SAndrew Jeffery } // namespace openpower 118