PEL: Add PEL repository capping related fields

If not capped, the PEL repository would keep taking up more and more
space as more PELs are added.  In preparation for handling this, add
a field to the Repository class to track the total size that all PELs can
take up and a field to track the maximum number of PELs that can be
stored.

The size value is hardcoded to be 20MB (and 100KB in unit test), though
a Repository class constructor allows the number to use to be passed in.
The max number of PELs field is hardcoded to 3000 (100 in test) and this
can also be changed in the constructor.

In the future if different systems or configurations require different
values, then this could be set at configure time.  This isn't done now
because I want to only add PEL options to the common phosphor-logging
configure.ac if absolutely necessary as the majority of phosphor-logging
users don't use PELs.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I72609a727229f96bd8ac23a630f25fd8b5c73427
diff --git a/extensions/openpower-pels/paths.cpp b/extensions/openpower-pels/paths.cpp
index a9e865c..14e5d71 100644
--- a/extensions/openpower-pels/paths.cpp
+++ b/extensions/openpower-pels/paths.cpp
@@ -25,6 +25,8 @@
 {
 
 namespace fs = std::filesystem;
+static constexpr size_t defaultRepoSize = 20 * 1024 * 1024;
+static constexpr size_t defaultMaxNumPELs = 3000;
 
 fs::path getPELIDFile()
 {
@@ -45,5 +47,19 @@
     return std::filesystem::path{"/usr/share/phosphor-logging/pels"};
 }
 
+size_t getPELRepoSize()
+{
+    // For now, always use 20MB, revisit in the future if different
+    // systems need different values so that we only put PEL
+    // content into configure.ac when absolutely necessary.
+    return defaultRepoSize;
+}
+
+size_t getMaxNumPELs()
+{
+    // Hardcode using the same reasoning as the repo size field.
+    return defaultMaxNumPELs;
+}
+
 } // namespace pels
 } // namespace openpower
diff --git a/extensions/openpower-pels/paths.hpp b/extensions/openpower-pels/paths.hpp
index 8d7a20f..600073a 100644
--- a/extensions/openpower-pels/paths.hpp
+++ b/extensions/openpower-pels/paths.hpp
@@ -20,5 +20,26 @@
  * @brief Returns the path to the read only data directory
  */
 std::filesystem::path getPELReadOnlyDataPath();
+
+/**
+ * @brief Returns the maximum size in bytes allocated to store PELs.
+ *
+ * This is still in paths.c/hpp even though it doesn't return a path
+ * because this file is easy to override when testing.
+ *
+ * @return size_t The maximum size in bytes to use for storing PELs.
+ */
+size_t getPELRepoSize();
+
+/**
+ * @brief Returns the maximum number of PELs allowed
+ *
+ * This is still in paths.c/hpp even though it doesn't return a path
+ * because this file is easy to override when testing.
+ *
+ * @return size_t The maximum number of PELs to allow in the repository.
+ */
+size_t getMaxNumPELs();
+
 } // namespace pels
 } // namespace openpower
diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index 2de3ee9..331b86a 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -28,8 +28,10 @@
 using namespace phosphor::logging;
 namespace file_error = sdbusplus::xyz::openbmc_project::Common::File::Error;
 
-Repository::Repository(const std::filesystem::path& basePath) :
-    _logPath(basePath / "logs")
+Repository::Repository(const std::filesystem::path& basePath, size_t repoSize,
+                       size_t maxNumPELs) :
+    _logPath(basePath / "logs"),
+    _maxRepoSize(repoSize), _maxNumPELs(maxNumPELs)
 {
     if (!fs::exists(_logPath))
     {
diff --git a/extensions/openpower-pels/repository.hpp b/extensions/openpower-pels/repository.hpp
index e55808f..2e2f623 100644
--- a/extensions/openpower-pels/repository.hpp
+++ b/extensions/openpower-pels/repository.hpp
@@ -1,5 +1,6 @@
 #pragma once
 #include "bcd_time.hpp"
+#include "paths.hpp"
 #include "pel.hpp"
 
 #include <algorithm>
@@ -118,7 +119,21 @@
      *
      * @param[in] basePath - the base filesystem path for the repository
      */
-    Repository(const std::filesystem::path& basePath);
+    Repository(const std::filesystem::path& basePath) :
+        Repository(basePath, getPELRepoSize(), getMaxNumPELs())
+    {
+    }
+
+    /**
+     * @brief Constructor that takes the repository size
+     *
+     * @param[in] basePath - the base filesystem path for the repository
+     * @param[in] repoSize - The maximum amount of space to use for PELs,
+     *                       in bytes
+     * @param[in] maxNumPELs - The maximum number of PELs to allow
+     */
+    Repository(const std::filesystem::path& basePath, size_t repoSize,
+               size_t maxNumPELs);
 
     /**
      * @brief Adds a PEL to the repository
@@ -370,6 +385,18 @@
      * @brief Subscriptions for deleted PELs.
      */
     std::map<std::string, DeleteCallback> _deleteSubscriptions;
+
+    /**
+     * @brief The maximum amount of space that the PELs in the
+     *        repository can occupy.
+     */
+    const uint64_t _maxRepoSize;
+
+    /**
+     * @brief The maximum number of PELs to allow in the repo
+     *        before pruning.
+     */
+    const size_t _maxNumPELs;
 };
 
 } // namespace pels