Cap the number of dumps

Calculate number of dumps allowed in a system based on
individual dump Max size configured in the system.

Algorithm: Setting Dump size to maximum size,
if (dump entries + active dumps) is less than total allowed dump entries.
Otherwise return error.

Next patch will provide additional algorithm to cap the
dump based on actual size of the dump files.

Change-Id: Id8916a31d72f5c2f2f23eaf68062b829b7e4100c
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
diff --git a/dump_manager.cpp b/dump_manager.cpp
index 02429c2..80e117b 100644
--- a/dump_manager.cpp
+++ b/dump_manager.cpp
@@ -2,11 +2,13 @@
 #include <sys/inotify.h>
 #include <regex>
 
+#include <phosphor-logging/elog.hpp>
 #include <phosphor-logging/elog-errors.hpp>
 
 #include "dump_manager.hpp"
 #include "dump_internal.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
+#include "xyz/openbmc_project/Dump/Create/error.hpp"
 #include "config.h"
 
 namespace phosphor
@@ -79,11 +81,17 @@
         elog<InternalFailure>();
     }
 
+    //Increment active dump count.
+    activeDumpCount++;
+
     return ++lastEntryId;
 }
 
 void Manager::createEntry(const fs::path& file)
 {
+    //Decrement the Dump in progress counter.
+    activeDumpCount = (activeDumpCount == 0 ? 0 : activeDumpCount - 1);
+
     //Dump File Name format obmcdump_ID_EPOCHTIME.EXT
     static constexpr auto ID_POS         = 1;
     static constexpr auto EPOCHTIME_POS  = 2;
@@ -147,17 +155,17 @@
         else if ((IN_CREATE == i.second) && fs::is_directory(i.first))
         {
             auto watchObj = std::make_unique<Watch>(
-                                    eventLoop,
-                                    IN_NONBLOCK,
-                                    IN_CLOSE_WRITE,
-                                    EPOLLIN,
-                                    i.first,
-                                    std::bind(
-                                         std::mem_fn(
-                                      &phosphor::dump::Manager::watchCallback),
-                                         this, std::placeholders::_1));
+                                eventLoop,
+                                IN_NONBLOCK,
+                                IN_CLOSE_WRITE,
+                                EPOLLIN,
+                                i.first,
+                                std::bind(
+                                    std::mem_fn(
+                                       &phosphor::dump::Manager::watchCallback),
+                                    this, std::placeholders::_1));
 
-           childWatchMap.emplace(i.first, std::move(watchObj));
+            childWatchMap.emplace(i.first, std::move(watchObj));
         }
 
     }
@@ -199,5 +207,31 @@
     }
 }
 
+size_t Manager::getAllowedSize()
+{
+    using namespace sdbusplus::xyz::openbmc_project::Dump::Create::Error;
+    using Reason = xyz::openbmc_project::Dump::Create::QuotaExceeded::REASON;
+
+    auto size = 0;
+
+    // Maximum number of dump is based on total dump size
+    // and individual dump Max size configured in the system.
+    // Set the new dump size to max, in case sum of available
+    // dump and active dumps is less than maximum number of dumps.
+
+    constexpr auto dumpCount = BMC_DUMP_TOTAL_SIZE / BMC_DUMP_MAX_SIZE;
+
+    if ((entries.size() + activeDumpCount) < dumpCount)
+    {
+        size = BMC_DUMP_MAX_SIZE;
+    }
+    else
+    {
+        //Reached to maximum limit
+        elog<QuotaExceeded>(Reason("Not enough space: Delete old dumps"));
+    }
+    return size;
+}
+
 } //namespace dump
 } //namespace phosphor