summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Spinler <spinler@us.ibm.com>2019-11-06 16:19:46 -0600
committerMatt Spinler <spinler@us.ibm.com>2019-12-03 15:08:08 -0600
commit0ff00485b1e8f9b57eafc2065b3b8cd82471c58d (patch)
tree9b4200769f540bfe4d834164e69cfc804e7d4f97
parent421f6531c5563d1e4e66b17062ebb9e632ca967b (diff)
downloadphosphor-logging-0ff00485b1e8f9b57eafc2065b3b8cd82471c58d.tar.gz
phosphor-logging-0ff00485b1e8f9b57eafc2065b3b8cd82471c58d.zip
PEL: Keep PEL attributes in Repository map
Instead of the Repository class only storing the path to a PEL file for a corresponding PEL ID, change it to a structure that includes the PEL's size and action flags as well as the path. This way, a PEL won't have to be read from the filesystem to find these values every time someone needs them. These new fields will be needed by the code that sends PELs to the host. Change-Id: I7650b6cbad12cc120426854767403f5cba2ee572
-rw-r--r--extensions/openpower-pels/repository.cpp48
-rw-r--r--extensions/openpower-pels/repository.hpp44
-rw-r--r--test/openpower-pels/repository_test.cpp45
3 files changed, 113 insertions, 24 deletions
diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index aaa6a87..93d2f81 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -58,11 +58,14 @@ void Repository::restore()
PEL pel{data};
if (pel.valid())
{
+ PELAttributes attributes{dirEntry.path(),
+ pel.userHeader().actionFlags()};
+
using pelID = LogID::Pel;
using obmcID = LogID::Obmc;
- _idsToPELs.emplace(
+ _pelAttributes.emplace(
LogID(pelID(pel.id()), obmcID(pel.obmcLogID())),
- dirEntry.path());
+ attributes);
}
else
{
@@ -100,8 +103,6 @@ void Repository::add(std::unique_ptr<PEL>& pel)
// If this fails, the filesystem is probably full so it isn't like
// we could successfully create yet another error log here.
auto e = errno;
- log<level::ERR>("Failed creating PEL file",
- entry("FILE=%s", path.c_str()));
fs::remove(path);
log<level::ERR>("Unable to open PEL file for writing",
entry("ERRNO=%d", e), entry("PATH=%s", path.c_str()));
@@ -116,8 +117,6 @@ void Repository::add(std::unique_ptr<PEL>& pel)
// Same note as above about not being able to create an error log
// for this case even if we wanted.
auto e = errno;
- log<level::ERR>("Failed writing PEL file",
- entry("FILE=%s", path.c_str()));
file.close();
fs::remove(path);
log<level::ERR>("Unable to write PEL file", entry("ERRNO=%d", e),
@@ -125,9 +124,14 @@ void Repository::add(std::unique_ptr<PEL>& pel)
throw file_error::Write();
}
+ file.close();
+
+ PELAttributes attributes{path, pel->userHeader().actionFlags()};
+
using pelID = LogID::Pel;
using obmcID = LogID::Obmc;
- _idsToPELs.emplace(LogID(pelID(pel->id()), obmcID(pel->obmcLogID())), path);
+ _pelAttributes.emplace(LogID(pelID(pel->id()), obmcID(pel->obmcLogID())),
+ attributes);
processAddCallbacks(*pel);
}
@@ -135,10 +139,10 @@ void Repository::add(std::unique_ptr<PEL>& pel)
void Repository::remove(const LogID& id)
{
auto pel = findPEL(id);
- if (pel != _idsToPELs.end())
+ if (pel != _pelAttributes.end())
{
- fs::remove(pel->second);
- _idsToPELs.erase(pel);
+ fs::remove(pel->second.path);
+ _pelAttributes.erase(pel);
processDeleteCallbacks(id.pelID.id);
}
@@ -147,14 +151,14 @@ void Repository::remove(const LogID& id)
std::optional<std::vector<uint8_t>> Repository::getPELData(const LogID& id)
{
auto pel = findPEL(id);
- if (pel != _idsToPELs.end())
+ if (pel != _pelAttributes.end())
{
- std::ifstream file{pel->second.c_str()};
+ std::ifstream file{pel->second.path.c_str()};
if (!file.good())
{
auto e = errno;
log<level::ERR>("Unable to open PEL file", entry("ERRNO=%d", e),
- entry("PATH=%s", pel->second.c_str()));
+ entry("PATH=%s", pel->second.path.c_str()));
throw file_error::Open();
}
@@ -168,16 +172,16 @@ std::optional<std::vector<uint8_t>> Repository::getPELData(const LogID& id)
void Repository::for_each(ForEachFunc func) const
{
- for (const auto& [id, path] : _idsToPELs)
+ for (const auto& [id, attributes] : _pelAttributes)
{
- std::ifstream file{path};
+ std::ifstream file{attributes.path};
if (!file.good())
{
auto e = errno;
log<level::ERR>("Repository::for_each: Unable to open PEL file",
entry("ERRNO=%d", e),
- entry("PATH=%s", path.c_str()));
+ entry("PATH=%s", attributes.path.c_str()));
continue;
}
@@ -236,5 +240,17 @@ void Repository::processDeleteCallbacks(uint32_t id) const
}
}
+std::optional<std::reference_wrapper<const Repository::PELAttributes>>
+ Repository::getPELAttributes(const LogID& id) const
+{
+ auto pel = findPEL(id);
+ if (pel != _pelAttributes.end())
+ {
+ return pel->second;
+ }
+
+ return std::nullopt;
+}
+
} // namespace pels
} // namespace openpower
diff --git a/extensions/openpower-pels/repository.hpp b/extensions/openpower-pels/repository.hpp
index 78ab174..5c31fed 100644
--- a/extensions/openpower-pels/repository.hpp
+++ b/extensions/openpower-pels/repository.hpp
@@ -3,6 +3,7 @@
#include "pel.hpp"
#include <algorithm>
+#include <bitset>
#include <filesystem>
#include <map>
@@ -20,6 +21,22 @@ class Repository
{
public:
/**
+ * @brief Structure of commonly used PEL attributes.
+ */
+ struct PELAttributes
+ {
+ std::filesystem::path path;
+ std::bitset<16> actionFlags;
+
+ PELAttributes() = delete;
+
+ PELAttributes(const std::filesystem::path& path, uint16_t flags) :
+ path(path), actionFlags(flags)
+ {
+ }
+ };
+
+ /**
* @brief A structure that holds both the PEL and corresponding
* OpenBMC IDs.
* Used for correlating the IDs with their data files for quick
@@ -133,7 +150,7 @@ class Repository
*/
inline bool hasPEL(const LogID& id)
{
- return findPEL(id) != _idsToPELs.end();
+ return findPEL(id) != _pelAttributes.end();
}
/**
@@ -230,18 +247,29 @@ class Repository
_deleteSubscriptions.erase(name);
}
+ /**
+ * @brief Get the PEL attributes for a PEL
+ *
+ * @param[in] id - The ID to find the attributes for
+ *
+ * @return The attributes or an empty optional if not found
+ */
+ std::optional<std::reference_wrapper<const PELAttributes>>
+ getPELAttributes(const LogID& id) const;
+
private:
/**
- * @brief Finds an entry in the _idsToPELs map.
+ * @brief Finds an entry in the _pelAttributes map.
*
* @param[in] id - the ID (either the pel ID, OBMC ID, or both)
*
* @return an iterator to the entry
*/
- std::map<LogID, std::filesystem::path>::iterator findPEL(const LogID& id)
+ std::map<LogID, PELAttributes>::const_iterator
+ findPEL(const LogID& id) const
{
- return std::find_if(_idsToPELs.begin(), _idsToPELs.end(),
- [&id](const auto& i) { return i.first == id; });
+ return std::find_if(_pelAttributes.begin(), _pelAttributes.end(),
+ [&id](const auto& a) { return a.first == id; });
}
/**
@@ -259,7 +287,7 @@ class Repository
void processDeleteCallbacks(uint32_t id) const;
/**
- * @brief Restores the _idsToPELs map on startup based on the existing
+ * @brief Restores the _pelAttributes map on startup based on the existing
* PEL data files.
*/
void restore();
@@ -270,9 +298,9 @@ class Repository
const std::filesystem::path _logPath;
/**
- * @brief A map of the PEL/OBMC IDs to the PEL data files.
+ * @brief A map of the PEL/OBMC IDs to PEL attributes.
*/
- std::map<LogID, std::filesystem::path> _idsToPELs;
+ std::map<LogID, PELAttributes> _pelAttributes;
/**
* @brief Subcriptions for new PELs.
diff --git a/test/openpower-pels/repository_test.cpp b/test/openpower-pels/repository_test.cpp
index 34de855..8596840 100644
--- a/test/openpower-pels/repository_test.cpp
+++ b/test/openpower-pels/repository_test.cpp
@@ -255,3 +255,48 @@ TEST_F(RepositoryTest, TestSubscriptions)
repo.remove(id);
EXPECT_EQ(removed.size(), 0);
}
+
+TEST_F(RepositoryTest, TestGetAttributes)
+{
+ uint32_t pelID = 0;
+ std::bitset<16> actionFlags;
+
+ {
+ Repository repo{repoPath};
+
+ // Add a PEL to the repo
+ auto data = pelDataFactory(TestPELType::pelSimple);
+ auto pel = std::make_unique<PEL>(data);
+ repo.add(pel);
+
+ pelID = pel->id();
+ actionFlags = pel->userHeader().actionFlags();
+
+ using ID = Repository::LogID;
+ ID id{ID::Pel(pelID)};
+
+ auto a = repo.getPELAttributes(id);
+ EXPECT_TRUE(a);
+ EXPECT_EQ((*a).get().actionFlags, actionFlags);
+
+ id.pelID.id = 0;
+ a = repo.getPELAttributes(id);
+ EXPECT_FALSE(a);
+ }
+
+ {
+ // Restore the repository and check again
+ Repository repo{repoPath};
+
+ using ID = Repository::LogID;
+ ID id{ID::Pel(pelID)};
+
+ auto a = repo.getPELAttributes(id);
+ EXPECT_TRUE(a);
+ EXPECT_EQ((*a).get().actionFlags, actionFlags);
+
+ id.pelID.id = 0;
+ a = repo.getPELAttributes(id);
+ EXPECT_FALSE(a);
+ }
+}
OpenPOWER on IntegriCloud