blob: d15340006e64a0c31f48cd04db3ead2d2cd5f657 [file] [log] [blame]
Matt Spinler89fa0822019-07-17 13:54:30 -05001#pragma once
2#include "bcd_time.hpp"
3#include "pel.hpp"
4
5#include <algorithm>
6#include <filesystem>
Matt Spinler475e5742019-07-18 16:09:49 -05007#include <map>
Matt Spinler89fa0822019-07-17 13:54:30 -05008
9namespace openpower
10{
11namespace pels
12{
13
14/**
15 * @class Repository
16 *
17 * The class handles saving and retrieving PELs on the BMC.
18 */
19class Repository
20{
21 public:
Matt Spinler475e5742019-07-18 16:09:49 -050022 /**
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
Matt Spinler89fa0822019-07-17 13:54:30 -050088 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 /**
Matt Spinler475e5742019-07-18 16:09:49 -0500112 * @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 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500119 * @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
Matt Spinler475e5742019-07-18 16:09:49 -0500128 /**
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
Matt Spinler2813f362019-07-19 12:45:28 -0500139 /**
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
Matt Spinler89fa0822019-07-17 13:54:30 -0500151 private:
152 /**
Matt Spinler475e5742019-07-18 16:09:49 -0500153 * @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 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500172 * @brief The filesystem path to the PEL logs.
173 */
174 const std::filesystem::path _logPath;
Matt Spinler475e5742019-07-18 16:09:49 -0500175
176 /**
177 * @brief A map of the PEL/OBMC IDs to the PEL data files.
178 */
179 std::map<LogID, std::filesystem::path> _idsToPELs;
Matt Spinler89fa0822019-07-17 13:54:30 -0500180};
181
182} // namespace pels
183} // namespace openpower