PEL: Add size, creator, sev to repo attributes

Have the Repository class track the disk usage, creator ID and severity
of each PEL along with the attributes already tracked so that they can
be used in the future for categorizing PELs to prune.

Note the size field is the amount of space the PEL file uses on disk, as
determined by the stat() function call, and not just the regular file
size, as the pruning algorithm is based on disk usage.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Idc996ef38726651d23ad478b18460b3d1ca950b5
diff --git a/extensions/openpower-pels/repository.cpp b/extensions/openpower-pels/repository.cpp
index 331b86a..4e40678 100644
--- a/extensions/openpower-pels/repository.cpp
+++ b/extensions/openpower-pels/repository.cpp
@@ -15,6 +15,8 @@
  */
 #include "repository.hpp"
 
+#include <sys/stat.h>
+
 #include <fstream>
 #include <phosphor-logging/log.hpp>
 #include <xyz/openbmc_project/Common/File/error.hpp>
@@ -28,6 +30,32 @@
 using namespace phosphor::logging;
 namespace file_error = sdbusplus::xyz::openbmc_project::Common::File::Error;
 
+/**
+ * @brief Returns the amount of space the file uses on disk.
+ *
+ * This is different than just the regular size of the file.
+ *
+ * @param[in] file - The file to get the size of
+ *
+ * @return size_t The disk space the file uses
+ */
+size_t getFileDiskSize(const std::filesystem::path& file)
+{
+    constexpr size_t statBlockSize = 512;
+    struct stat statData;
+    auto rc = stat(file.c_str(), &statData);
+    if (rc != 0)
+    {
+        auto e = errno;
+        std::string msg = "call to stat() failed on " + file.native() +
+                          " with errno " + std::to_string(e);
+        log<level::ERR>(msg.c_str());
+        abort();
+    }
+
+    return statData.st_blocks * statBlockSize;
+}
+
 Repository::Repository(const std::filesystem::path& basePath, size_t repoSize,
                        size_t maxNumPELs) :
     _logPath(basePath / "logs"),
@@ -77,9 +105,13 @@
                     }
                 }
 
-                PELAttributes attributes{
-                    dirEntry.path(), pel.userHeader().actionFlags(),
-                    pel.hostTransmissionState(), pel.hmcTransmissionState()};
+                PELAttributes attributes{dirEntry.path(),
+                                         getFileDiskSize(dirEntry.path()),
+                                         pel.privateHeader().creatorID(),
+                                         pel.userHeader().severity(),
+                                         pel.userHeader().actionFlags(),
+                                         pel.hostTransmissionState(),
+                                         pel.hmcTransmissionState()};
 
                 using pelID = LogID::Pel;
                 using obmcID = LogID::Obmc;
@@ -122,7 +154,11 @@
 
     write(*(pel.get()), path);
 
-    PELAttributes attributes{path, pel->userHeader().actionFlags(),
+    PELAttributes attributes{path,
+                             getFileDiskSize(path),
+                             pel->privateHeader().creatorID(),
+                             pel->userHeader().severity(),
+                             pel->userHeader().actionFlags(),
                              pel->hostTransmissionState(),
                              pel->hmcTransmissionState()};
 
diff --git a/extensions/openpower-pels/repository.hpp b/extensions/openpower-pels/repository.hpp
index 2e2f623..ecfcf7e 100644
--- a/extensions/openpower-pels/repository.hpp
+++ b/extensions/openpower-pels/repository.hpp
@@ -27,15 +27,20 @@
     struct PELAttributes
     {
         std::filesystem::path path;
+        size_t sizeOnDisk;
+        uint8_t creator;
+        uint8_t severity;
         std::bitset<16> actionFlags;
         TransmissionState hostState;
         TransmissionState hmcState;
 
         PELAttributes() = delete;
 
-        PELAttributes(const std::filesystem::path& p, uint16_t flags,
+        PELAttributes(const std::filesystem::path& p, size_t size,
+                      uint8_t creator, uint8_t sev, uint16_t flags,
                       TransmissionState hostState, TransmissionState hmcState) :
             path(p),
+            sizeOnDisk(size), creator(creator), severity(sev),
             actionFlags(flags), hostState(hostState), hmcState(hmcState)
         {
         }