blob: 289541c2974382cf049537788818174bd8b78750 [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 Spinler89fa0822019-07-17 13:54:30 -0500139 private:
140 /**
Matt Spinler475e5742019-07-18 16:09:49 -0500141 * @brief Finds an entry in the _idsToPELs map.
142 *
143 * @param[in] id - the ID (either the pel ID, OBMC ID, or both)
144 *
145 * @return an iterator to the entry
146 */
147 std::map<LogID, std::filesystem::path>::iterator findPEL(const LogID& id)
148 {
149 return std::find_if(_idsToPELs.begin(), _idsToPELs.end(),
150 [&id](const auto& i) { return i.first == id; });
151 }
152
153 /**
154 * @brief Restores the _idsToPELs map on startup based on the existing
155 * PEL data files.
156 */
157 void restore();
158
159 /**
Matt Spinler89fa0822019-07-17 13:54:30 -0500160 * @brief The filesystem path to the PEL logs.
161 */
162 const std::filesystem::path _logPath;
Matt Spinler475e5742019-07-18 16:09:49 -0500163
164 /**
165 * @brief A map of the PEL/OBMC IDs to the PEL data files.
166 */
167 std::map<LogID, std::filesystem::path> _idsToPELs;
Matt Spinler89fa0822019-07-17 13:54:30 -0500168};
169
170} // namespace pels
171} // namespace openpower