1 #pragma once 2 #include "bcd_time.hpp" 3 #include "pel.hpp" 4 5 #include <algorithm> 6 #include <filesystem> 7 #include <map> 8 9 namespace openpower 10 { 11 namespace pels 12 { 13 14 /** 15 * @class Repository 16 * 17 * The class handles saving and retrieving PELs on the BMC. 18 */ 19 class Repository 20 { 21 public: 22 /** 23 * @brief A structure that holds both the PEL and corresponding 24 * OpenBMC IDs. 25 * Used for correlating the IDs with their data files for quick 26 * lookup. To find a PEL based on just one of the IDs, just use 27 * the constructor that takes that ID. 28 */ 29 struct LogID 30 { 31 struct Pel 32 { 33 uint32_t id; 34 explicit Pel(uint32_t i) : id(i) 35 { 36 } 37 }; 38 struct Obmc 39 { 40 uint32_t id; 41 explicit Obmc(uint32_t i) : id(i) 42 { 43 } 44 }; 45 46 Pel pelID; 47 48 Obmc obmcID; 49 50 LogID(Pel pel, Obmc obmc) : pelID(pel), obmcID(obmc) 51 { 52 } 53 54 explicit LogID(Pel id) : pelID(id), obmcID(0) 55 { 56 } 57 58 explicit LogID(Obmc id) : pelID(0), obmcID(id) 59 { 60 } 61 62 LogID() = delete; 63 64 /** 65 * @brief A == operator that will match on either ID 66 * being equal if the other is zero, so that 67 * one can look up a PEL with just one of the IDs. 68 */ 69 bool operator==(const LogID& id) const 70 { 71 if (id.pelID.id != 0) 72 { 73 return id.pelID.id == pelID.id; 74 } 75 if (id.obmcID.id != 0) 76 { 77 return id.obmcID.id == obmcID.id; 78 } 79 return false; 80 } 81 82 bool operator<(const LogID& id) const 83 { 84 return pelID.id < id.pelID.id; 85 } 86 }; 87 88 Repository() = delete; 89 ~Repository() = default; 90 Repository(const Repository&) = default; 91 Repository& operator=(const Repository&) = default; 92 Repository(Repository&&) = default; 93 Repository& operator=(Repository&&) = default; 94 95 /** 96 * @brief Constructor 97 * 98 * @param[in] basePath - the base filesystem path for the repository 99 */ 100 Repository(const std::filesystem::path& basePath); 101 102 /** 103 * @brief Adds a PEL to the repository 104 * 105 * Throws File.Error.Open or File.Error.Write exceptions on failure 106 * 107 * @param[in] pel - the PEL to add 108 */ 109 void add(std::unique_ptr<PEL>& pel); 110 111 /** 112 * @brief Removes a PEL from the repository 113 * 114 * @param[in] id - the ID (either the pel ID, OBMC ID, or both) to remove 115 */ 116 void remove(const LogID& id); 117 118 /** 119 * @brief Generates the filename to use for the PEL ID and BCDTime. 120 * 121 * @param[in] pelID - the PEL ID 122 * @param[in] time - the BCD time 123 * 124 * @return string - A filename string of <BCD_time>_<pelID> 125 */ 126 static std::string getPELFilename(uint32_t pelID, const BCDTime& time); 127 128 /** 129 * @brief Returns true if the PEL with the specified ID is in the repo. 130 * 131 * @param[in] id - the ID (either the pel ID, OBMC ID, or both) 132 * @return bool - true if that PEL is present 133 */ 134 inline bool hasPEL(const LogID& id) 135 { 136 return findPEL(id) != _idsToPELs.end(); 137 } 138 139 /** 140 * @brief Returns the PEL data based on its ID. 141 * 142 * If the data can't be found for that ID, then the optional object 143 * will be empty. 144 * 145 * @param[in] id - the LogID to get the PEL for, which can be either a 146 * PEL ID or OpenBMC log ID. 147 * @return std::optional<std::vector<uint8_t>> - the PEL data 148 */ 149 std::optional<std::vector<uint8_t>> getPELData(const LogID& id); 150 151 private: 152 /** 153 * @brief Finds an entry in the _idsToPELs map. 154 * 155 * @param[in] id - the ID (either the pel ID, OBMC ID, or both) 156 * 157 * @return an iterator to the entry 158 */ 159 std::map<LogID, std::filesystem::path>::iterator findPEL(const LogID& id) 160 { 161 return std::find_if(_idsToPELs.begin(), _idsToPELs.end(), 162 [&id](const auto& i) { return i.first == id; }); 163 } 164 165 /** 166 * @brief Restores the _idsToPELs map on startup based on the existing 167 * PEL data files. 168 */ 169 void restore(); 170 171 /** 172 * @brief The filesystem path to the PEL logs. 173 */ 174 const std::filesystem::path _logPath; 175 176 /** 177 * @brief A map of the PEL/OBMC IDs to the PEL data files. 178 */ 179 std::map<LogID, std::filesystem::path> _idsToPELs; 180 }; 181 182 } // namespace pels 183 } // namespace openpower 184