Split BMC dump manager to accomodate more locally stored dumps

The BMC dump manager is having all infrastucure to manage
locally stored dumps. To avoid code duplication while
implementing other locally stored dumps, splitting the
BMC dump manager into locally stored dump manager and
BMC dump manager.
Changes:
Add a new base class bmc_stored::Manager for bmc::Manager
new base class will have following functions
- Store dump properties
- create dump entry based on file watch.
New class diagram will look like this
          |-------------|
          |  base dump  |
          |   manager   |
          |-------------|
                 |
          |-------------|
          | BMC stored  |
          |   dump      |
          |  manager    |
          |-------------|
                |
     -------------------------
     |                       |
 |---------|             |----------|
 |  BMC    |             |   New    |
 |  dump   |             |  dump    |
 | manager |             | Manager  |
 |---------|             |----------|

Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I02a8766113d030ba2f20bd98cb8713296d01eebe
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
index f95683d..2318c40 100644
--- a/dump_manager_bmc.cpp
+++ b/dump_manager_bmc.cpp
@@ -18,7 +18,6 @@
 
 #include <cmath>
 #include <ctime>
-#include <regex>
 
 namespace phosphor
 {
@@ -69,30 +68,39 @@
     // Entry Object path.
     auto objPath = std::filesystem::path(baseEntryPath) / std::to_string(id);
 
+    uint64_t timeStamp =
+        std::chrono::duration_cast<std::chrono::microseconds>(
+            std::chrono::system_clock::now().time_since_epoch())
+            .count();
+    createEntry(id, objPath, timeStamp, 0, std::string(),
+                phosphor::dump::OperationStatus::InProgress, originatorId,
+                originatorType);
+    Manager::fUserDumpInProgress = true;
+    return objPath.string();
+}
+
+void Manager::createEntry(const uint32_t id, const std::string objPath,
+                          const uint64_t ms, uint64_t fileSize,
+                          const std::filesystem::path& file,
+                          phosphor::dump::OperationStatus status,
+                          std::string originatorId,
+                          originatorTypes originatorType)
+{
     try
     {
-        uint64_t timeStamp =
-            std::chrono::duration_cast<std::chrono::microseconds>(
-                std::chrono::system_clock::now().time_since_epoch())
-                .count();
-
         entries.insert(std::make_pair(
             id, std::make_unique<bmc::Entry>(
-                    bus, objPath.c_str(), id, timeStamp, 0, std::string(),
-                    phosphor::dump::OperationStatus::InProgress, originatorId,
-                    originatorType, *this)));
+                    bus, objPath.c_str(), id, ms, fileSize, file, status,
+                    originatorId, originatorType, *this)));
     }
     catch (const std::invalid_argument& e)
     {
-        log<level::ERR>(fmt::format("Error in creating dump entry, "
+        log<level::ERR>(fmt::format("Error in creating BMC dump entry, "
                                     "errormsg({}), OBJECTPATH({}), ID({})",
                                     e.what(), objPath.c_str(), id)
                             .c_str());
         elog<InternalFailure>();
     }
-
-    Manager::fUserDumpInProgress = true;
-    return objPath.string();
 }
 
 uint32_t Manager::captureDump(Type type,
@@ -165,195 +173,6 @@
     return ++lastEntryId;
 }
 
-void Manager::createEntry(const std::filesystem::path& file)
-{
-    // Dump File Name format obmcdump_ID_EPOCHTIME.EXT
-    static constexpr auto ID_POS = 1;
-    static constexpr auto EPOCHTIME_POS = 2;
-    std::regex file_regex("obmcdump_([0-9]+)_([0-9]+).([a-zA-Z0-9]+)");
-
-    std::smatch match;
-    std::string name = file.filename();
-
-    if (!((std::regex_search(name, match, file_regex)) && (match.size() > 0)))
-    {
-        log<level::ERR>(fmt::format("Invalid Dump file name, FILENAME({})",
-                                    file.filename().c_str())
-                            .c_str());
-        return;
-    }
-
-    auto idString = match[ID_POS];
-    uint64_t timestamp = stoull(match[EPOCHTIME_POS]) * 1000 * 1000;
-
-    auto id = stoul(idString);
-
-    // If there is an existing entry update it and return.
-    auto dumpEntry = entries.find(id);
-    if (dumpEntry != entries.end())
-    {
-        dynamic_cast<phosphor::dump::bmc::Entry*>(dumpEntry->second.get())
-            ->update(timestamp, std::filesystem::file_size(file), file);
-        return;
-    }
-
-    // Entry Object path.
-    auto objPath = std::filesystem::path(baseEntryPath) / std::to_string(id);
-
-    // TODO: Get the persisted originator id & type
-    // For now, replacing it with null
-    try
-    {
-        entries.insert(std::make_pair(
-            id, std::make_unique<bmc::Entry>(
-                    bus, objPath.c_str(), id, timestamp,
-                    std::filesystem::file_size(file), file,
-                    phosphor::dump::OperationStatus::Completed, std::string(),
-                    originatorTypes::Internal, *this)));
-    }
-    catch (const std::invalid_argument& e)
-    {
-        log<level::ERR>(
-            fmt::format("Error in creating dump entry, errormsg({}), "
-                        "OBJECTPATH({}), "
-                        "ID({}), TIMESTAMP({}), SIZE({}), FILENAME({})",
-                        e.what(), objPath.c_str(), id, timestamp,
-                        std::filesystem::file_size(file),
-                        file.filename().c_str())
-                .c_str());
-        return;
-    }
-}
-
-void Manager::watchCallback(const UserMap& fileInfo)
-{
-    for (const auto& i : fileInfo)
-    {
-        // For any new dump file create dump entry object
-        // and associated inotify watch.
-        if (IN_CLOSE_WRITE == i.second)
-        {
-            if (!std::filesystem::is_directory(i.first))
-            {
-                // Don't require filename to be passed, as the path
-                // of dump directory is stored in the childWatchMap
-                removeWatch(i.first.parent_path());
-
-                // dump file is written now create D-Bus entry
-                createEntry(i.first);
-            }
-            else
-            {
-                removeWatch(i.first);
-            }
-        }
-        // Start inotify watch on newly created directory.
-        else if ((IN_CREATE == i.second) &&
-                 std::filesystem::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::bmc::Manager::watchCallback),
-                    this, std::placeholders::_1));
-
-            childWatchMap.emplace(i.first, std::move(watchObj));
-        }
-    }
-}
-
-void Manager::removeWatch(const std::filesystem::path& path)
-{
-    // Delete Watch entry from map.
-    childWatchMap.erase(path);
-}
-
-void Manager::restore()
-{
-    std::filesystem::path dir(dumpDir);
-    if (!std::filesystem::exists(dir) || std::filesystem::is_empty(dir))
-    {
-        return;
-    }
-
-    // Dump file path: <DUMP_PATH>/<id>/<filename>
-    for (const auto& p : std::filesystem::directory_iterator(dir))
-    {
-        auto idStr = p.path().filename().string();
-
-        // Consider only directory's with dump id as name.
-        // Note: As per design one file per directory.
-        if ((std::filesystem::is_directory(p.path())) &&
-            std::all_of(idStr.begin(), idStr.end(), ::isdigit))
-        {
-            lastEntryId =
-                std::max(lastEntryId, static_cast<uint32_t>(std::stoul(idStr)));
-            auto fileIt = std::filesystem::directory_iterator(p.path());
-            // Create dump entry d-bus object.
-            if (fileIt != std::filesystem::end(fileIt))
-            {
-                createEntry(fileIt->path());
-            }
-        }
-    }
-}
-
-size_t getDirectorySize(const std::string dir)
-{
-    auto size = 0;
-    for (const auto& p : std::filesystem::recursive_directory_iterator(dir))
-    {
-        if (!std::filesystem::is_directory(p))
-        {
-            size += std::ceil(std::filesystem::file_size(p) / 1024.0);
-        }
-    }
-    return size;
-}
-
-size_t Manager::getAllowedSize()
-{
-    // Get current size of the dump directory.
-    auto size = getDirectorySize(dumpDir);
-
-    // Set the Dump size to Maximum  if the free space is greater than
-    // Dump max size otherwise return the available size.
-
-    size = (size > BMC_DUMP_TOTAL_SIZE ? 0 : BMC_DUMP_TOTAL_SIZE - size);
-
-#ifdef BMC_DUMP_ROTATE_CONFIG
-    // Delete the first existing file until the space is enough
-    while (size < BMC_DUMP_MIN_SPACE_REQD)
-    {
-        auto delEntry = min_element(
-            entries.begin(), entries.end(),
-            [](const auto& l, const auto& r) { return l.first < r.first; });
-        auto delPath =
-            std::filesystem::path(dumpDir) / std::to_string(delEntry->first);
-
-        size += getDirectorySize(delPath);
-
-        delEntry->second->delete_();
-    }
-#else
-    using namespace sdbusplus::xyz::openbmc_project::Dump::Create::Error;
-    using Reason = xyz::openbmc_project::Dump::Create::QuotaExceeded::REASON;
-
-    if (size < BMC_DUMP_MIN_SPACE_REQD)
-    {
-        // Reached to maximum limit
-        elog<QuotaExceeded>(Reason("Not enough space: Delete old dumps"));
-    }
-#endif
-
-    if (size > BMC_DUMP_MAX_SIZE)
-    {
-        size = BMC_DUMP_MAX_SIZE;
-    }
-
-    return size;
-}
-
 } // namespace bmc
 } // namespace dump
 } // namespace phosphor
diff --git a/dump_manager_bmc.hpp b/dump_manager_bmc.hpp
index 6dbb7ad..5d92736 100644
--- a/dump_manager_bmc.hpp
+++ b/dump_manager_bmc.hpp
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "dump_manager.hpp"
+#include "dump_manager_bmcstored.hpp"
 #include "dump_utils.hpp"
 #include "watch.hpp"
 #include "xyz/openbmc_project/Dump/Internal/Create/server.hpp"
@@ -24,16 +24,16 @@
 
 } // namespace internal
 
+constexpr auto BMC_DUMP_FILENAME_REGEX =
+    "obmcdump_([0-9]+)_([0-9]+).([a-zA-Z0-9]+)";
+
 using CreateIface = sdbusplus::server::object_t<
     sdbusplus::xyz::openbmc_project::Dump::server::Create>;
 
-using UserMap = phosphor::dump::inotify::UserMap;
-
 using Type =
     sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
-
-using Watch = phosphor::dump::inotify::Watch;
 using ::sdeventplus::source::Child;
+
 // Type to dreport type  string map
 static const std::map<Type, std::string> TypeMap = {
     {Type::ApplicationCored, "core"},
@@ -49,7 +49,7 @@
  */
 class Manager :
     virtual public CreateIface,
-    virtual public phosphor::dump::Manager
+    virtual public phosphor::dump::bmc_stored::Manager
 {
     friend class internal::Manager;
 
@@ -71,26 +71,11 @@
     Manager(sdbusplus::bus_t& bus, const EventPtr& event, const char* path,
             const std::string& baseEntryPath, const char* filePath) :
         CreateIface(bus, path),
-        phosphor::dump::Manager(bus, path, baseEntryPath),
-        eventLoop(event.get()),
-        dumpWatch(
-            eventLoop, IN_NONBLOCK, IN_CLOSE_WRITE | IN_CREATE, EPOLLIN,
-            filePath,
-            std::bind(std::mem_fn(&phosphor::dump::bmc::Manager::watchCallback),
-                      this, std::placeholders::_1)),
-        dumpDir(filePath)
+        phosphor::dump::bmc_stored::Manager(
+            bus, event, path, baseEntryPath, filePath, BMC_DUMP_FILENAME_REGEX,
+            BMC_DUMP_MAX_SIZE, BMC_DUMP_MIN_SPACE_REQD, BMC_DUMP_TOTAL_SIZE)
     {}
 
-    /** @brief Implementation of dump watch call back
-     *  @param [in] fileInfo - map of file info  path:event
-     */
-    void watchCallback(const UserMap& fileInfo);
-
-    /** @brief Construct dump d-bus objects from their persisted
-     *        representations.
-     */
-    void restore() override;
-
     /** @brief Implementation for CreateDump
      *  Method to create a BMC dump entry when user requests for a new BMC dump
      *
@@ -99,12 +84,24 @@
     sdbusplus::message::object_path
         createDump(phosphor::dump::DumpCreateParams params) override;
 
-  private:
-    /** @brief Create Dump entry d-bus object
-     *  @param[in] fullPath - Full path of the Dump file name
+    /** @brief Create a  Dump Entry Object
+     *  @param[in] id - Id of the dump
+     *  @param[in] objPath - Object path to attach to
+     *  @param[in] timeStamp - Dump creation timestamp
+     *             since the epoch.
+     *  @param[in] fileSize - Dump file size in bytes.
+     *  @param[in] file - Name of dump file.
+     *  @param[in] status - status of the dump.
+     *  @param[in] parent - The dump entry's parent.
      */
-    void createEntry(const std::filesystem::path& fullPath);
+    void createEntry(const uint32_t id, const std::string objPath,
+                     const uint64_t ms, uint64_t fileSize,
+                     const std::filesystem::path& file,
+                     phosphor::dump::OperationStatus status,
+                     std::string originatorId,
+                     originatorTypes originatorType) override;
 
+  private:
     /**  @brief Capture BMC Dump based on the Dump type.
      *  @param[in] type - Type of the Dump.
      *  @param[in] fullPaths - List of absolute paths to the files
@@ -113,38 +110,9 @@
      */
     uint32_t captureDump(Type type, const std::vector<std::string>& fullPaths);
 
-    /** @brief Remove specified watch object pointer from the
-     *        watch map and associated entry from the map.
-     *        @param[in] path - unique identifier of the map
-     */
-    void removeWatch(const std::filesystem::path& path);
-
-    /** @brief Calculate per dump allowed size based on the available
-     *        size in the dump location.
-     *  @returns dump size in kilobytes.
-     */
-    size_t getAllowedSize();
-
-    /** @brief sdbusplus Dump event loop */
-    EventPtr eventLoop;
-
-    /** @brief Dump main watch object */
-    Watch dumpWatch;
-
-    /** @brief Path to the dump file*/
-    std::string dumpDir;
-
     /** @brief Flag to reject user intiated dump if a dump is in progress*/
     // TODO: https://github.com/openbmc/phosphor-debug-collector/issues/19
     static bool fUserDumpInProgress;
-
-    /** @brief Child directory path and its associated watch object map
-     *        [path:watch object]
-     */
-    std::map<std::filesystem::path, std::unique_ptr<Watch>> childWatchMap;
-
-    /** @brief map of SDEventPlus child pointer added to event loop */
-    std::map<pid_t, std::unique_ptr<Child>> childPtrMap;
 };
 
 } // namespace bmc
diff --git a/dump_manager_bmcstored.cpp b/dump_manager_bmcstored.cpp
new file mode 100644
index 0000000..a470960
--- /dev/null
+++ b/dump_manager_bmcstored.cpp
@@ -0,0 +1,220 @@
+#include "config.h"
+
+#include "bmc_dump_entry.hpp"
+#include "dump_internal.hpp"
+#include "dump_manager_bmc.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+#include "xyz/openbmc_project/Dump/Create/error.hpp"
+
+#include <fmt/core.h>
+#include <sys/inotify.h>
+#include <unistd.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+
+#include <cmath>
+#include <ctime>
+#include <regex>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace bmc_stored
+{
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using namespace phosphor::logging;
+
+void Manager::createEntry(const std::filesystem::path& file)
+{
+    static constexpr auto ID_POS = 1;
+    static constexpr auto EPOCHTIME_POS = 2;
+    std::regex file_regex(dumpFilenameFormat.c_str());
+
+    std::smatch match;
+    std::string name = file.filename();
+
+    if (!((std::regex_search(name, match, file_regex)) && (match.size() > 0)))
+    {
+        log<level::ERR>(fmt::format("Invalid Dump file name, FILENAME({})",
+                                    file.filename().c_str())
+                            .c_str());
+        return;
+    }
+
+    auto idString = match[ID_POS];
+    uint64_t timestamp = stoull(match[EPOCHTIME_POS]) * 1000 * 1000;
+
+    auto id = stoul(idString);
+
+    // If there is an existing entry update it and return.
+    auto dumpEntry = entries.find(id);
+    if (dumpEntry != entries.end())
+    {
+        dynamic_cast<phosphor::dump::bmc_stored::Entry*>(
+            dumpEntry->second.get())
+            ->update(timestamp, std::filesystem::file_size(file), file);
+        return;
+    }
+
+    // Entry Object path.
+    auto objPath = std::filesystem::path(baseEntryPath) / std::to_string(id);
+
+    try
+    {
+        createEntry(id, objPath, timestamp, std::filesystem::file_size(file),
+                    file, phosphor::dump::OperationStatus::Completed,
+                    std::string(), originatorTypes::Internal);
+    }
+    catch (const InternalFailure& e)
+    {
+        log<level::ERR>(
+            fmt::format(
+                "Error in creating dump entry, errormsg({}), OBJECTPATH({}), "
+                "ID({}), TIMESTAMP({}), SIZE({}), FILENAME({})",
+                e.what(), objPath.c_str(), id, timestamp,
+                std::filesystem::file_size(file), file.filename().c_str())
+                .c_str());
+        return;
+    }
+}
+
+void Manager::watchCallback(const UserMap& fileInfo)
+{
+    for (const auto& i : fileInfo)
+    {
+        // For any new dump file create dump entry object
+        // and associated inotify watch.
+        if (IN_CLOSE_WRITE == i.second)
+        {
+            if (!std::filesystem::is_directory(i.first))
+            {
+                // Don't require filename to be passed, as the path
+                // of dump directory is stored in the childWatchMap
+                removeWatch(i.first.parent_path());
+
+                // dump file is written now create D-Bus entry
+                createEntry(i.first);
+            }
+            else
+            {
+                removeWatch(i.first);
+            }
+        }
+        // Start inotify watch on newly created directory.
+        else if ((IN_CREATE == i.second) &&
+                 std::filesystem::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::bmc::Manager::watchCallback),
+                    this, std::placeholders::_1));
+
+            childWatchMap.emplace(i.first, std::move(watchObj));
+        }
+    }
+}
+
+void Manager::removeWatch(const std::filesystem::path& path)
+{
+    // Delete Watch entry from map.
+    childWatchMap.erase(path);
+}
+
+void Manager::restore()
+{
+    std::filesystem::path dir(dumpDir);
+    if (!std::filesystem::exists(dir) || std::filesystem::is_empty(dir))
+    {
+        return;
+    }
+
+    // Dump file path: <DUMP_PATH>/<id>/<filename>
+    for (const auto& p : std::filesystem::directory_iterator(dir))
+    {
+        auto idStr = p.path().filename().string();
+
+        // Consider only directory's with dump id as name.
+        // Note: As per design one file per directory.
+        if ((std::filesystem::is_directory(p.path())) &&
+            std::all_of(idStr.begin(), idStr.end(), ::isdigit))
+        {
+            lastEntryId =
+                std::max(lastEntryId, static_cast<uint32_t>(std::stoul(idStr)));
+            auto fileIt = std::filesystem::directory_iterator(p.path());
+            // Create dump entry d-bus object.
+            if (fileIt != std::filesystem::end(fileIt))
+            {
+                createEntry(fileIt->path());
+            }
+        }
+    }
+}
+
+size_t getDirectorySize(const std::string dir)
+{
+    auto size = 0;
+    for (const auto& p : std::filesystem::recursive_directory_iterator(dir))
+    {
+        if (!std::filesystem::is_directory(p))
+        {
+            size += std::ceil(std::filesystem::file_size(p) / 1024.0);
+        }
+    }
+    return size;
+}
+
+size_t Manager::getAllowedSize()
+{
+    // Get current size of the dump directory.
+    auto size = getDirectorySize(dumpDir);
+
+    // Set the Dump size to Maximum  if the free space is greater than
+    // Dump max size otherwise return the available size.
+
+    size = (size > allocatedSize ? 0 : allocatedSize - size);
+
+#ifdef BMC_DUMP_ROTATE_CONFIG
+    // Delete the first existing file until the space is enough
+    while (size < minDumpSize)
+    {
+        auto delEntry = min_element(
+            entries.begin(), entries.end(),
+            [](const auto& l, const auto& r) { return l.first < r.first; });
+        auto delPath =
+            std::filesystem::path(dumpDir) / std::to_string(delEntry->first);
+
+        size += getDirectorySize(delPath);
+
+        delEntry->second->delete_();
+    }
+#else
+    using namespace sdbusplus::xyz::openbmc_project::Dump::Create::Error;
+    using Reason = xyz::openbmc_project::Dump::Create::QuotaExceeded::REASON;
+
+    if (size < minDumpSize)
+    {
+        log<level::ERR>(fmt::format("Not enough space available({}) miniumum "
+                                    "needed({}) filled({}) allocated({})",
+                                    size, minDumpSize,
+                                    getDirectorySize(dumpDir), allocatedSize)
+                            .c_str());
+        // Reached to maximum limit
+        elog<QuotaExceeded>(Reason("Not enough space: Delete old dumps"));
+    }
+#endif
+
+    if (size > maxDumpSize)
+    {
+        size = maxDumpSize;
+    }
+
+    return size;
+}
+
+} // namespace bmc_stored
+} // namespace dump
+} // namespace phosphor
diff --git a/dump_manager_bmcstored.hpp b/dump_manager_bmcstored.hpp
new file mode 100644
index 0000000..1ea17d4
--- /dev/null
+++ b/dump_manager_bmcstored.hpp
@@ -0,0 +1,143 @@
+#pragma once
+
+#include "dump_manager.hpp"
+#include "dump_utils.hpp"
+#include "watch.hpp"
+
+#include <sdeventplus/source/child.hpp>
+
+#include <filesystem>
+#include <map>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace bmc_stored
+{
+using UserMap = phosphor::dump::inotify::UserMap;
+
+using Watch = phosphor::dump::inotify::Watch;
+using ::sdeventplus::source::Child;
+
+/** @class Manager
+ *  @brief Manager base class for locally stored dumps.
+ */
+class Manager : public phosphor::dump::Manager
+{
+  public:
+    Manager() = delete;
+    Manager(const Manager&) = default;
+    Manager& operator=(const Manager&) = delete;
+    Manager(Manager&&) = delete;
+    Manager& operator=(Manager&&) = delete;
+    virtual ~Manager() = default;
+
+    /** @brief Constructor to put object onto bus at a dbus path.
+     *  @param[in] bus - Bus to attach to.
+     *  @param[in] event - Dump manager sd_event loop.
+     *  @param[in] path - Path to attach at.
+     *  @param[in] baseEntryPath - Base path for dump entry.
+     *  @param[in] filePath - Path where the dumps are stored.
+     *  @param[in] dumpFilenameFormat - Format of dump filename in regex
+     *  @param[in] maxDumpSize - Maximum size of the dump
+     *  @param[in] minDumpSize - Minimum possible size of a usable dump.
+     *  @param[in] allocatedSize - Total size allocated for the dumps
+     */
+    Manager(sdbusplus::bus::bus& bus, const EventPtr& event, const char* path,
+            const std::string& baseEntryPath, const char* filePath,
+            const std::string dumpFilenameFormat, const uint64_t maxDumpSize,
+            const uint64_t minDumpSize, const uint64_t allocatedSize) :
+        phosphor::dump::Manager(bus, path, baseEntryPath),
+        eventLoop(event.get()), dumpDir(filePath),
+        dumpWatch(
+            eventLoop, IN_NONBLOCK, IN_CLOSE_WRITE | IN_CREATE, EPOLLIN,
+            filePath,
+            std::bind(std::mem_fn(
+                          &phosphor::dump::bmc_stored::Manager::watchCallback),
+                      this, std::placeholders::_1)),
+        dumpFilenameFormat(dumpFilenameFormat), maxDumpSize(maxDumpSize),
+        minDumpSize(minDumpSize), allocatedSize(allocatedSize)
+    {}
+
+    /** @brief Implementation of dump watch call back
+     *  @param [in] fileInfo - map of file info  path:event
+     */
+    void watchCallback(const UserMap& fileInfo);
+
+    /** @brief Construct dump d-bus objects from their persisted
+     *        representations.
+     */
+    void restore() override;
+
+    /** @brief sdbusplus Dump event loop */
+    EventPtr eventLoop;
+
+  protected:
+    /** @brief Calculate per dump allowed size based on the available
+     *        size in the dump location.
+     *  @returns dump size in kilobytes.
+     */
+    size_t getAllowedSize();
+
+    /** @brief Create a  Dump Entry Object
+     *  @param[in] id - Id of the dump
+     *  @param[in] objPath - Object path to attach to
+     *  @param[in] timeStamp - Dump creation timestamp
+     *             since the epoch.
+     *  @param[in] fileSize - Dump file size in bytes.
+     *  @param[in] file - Name of dump file.
+     *  @param[in] status - status of the dump.
+     *  @param[in] parent - The dump entry's parent.
+     *  @param[in] originatorId - Id of the originator of the dump
+     *  @param[in] originatorType - Originator type
+     */
+    virtual void createEntry(const uint32_t id, const std::string objPath,
+                             const uint64_t ms, uint64_t fileSize,
+                             const std::filesystem::path& file,
+                             phosphor::dump::OperationStatus status,
+                             std::string originatorId,
+                             originatorTypes originatorType) = 0;
+
+    /** @brief Path to the dump file*/
+    std::string dumpDir;
+
+    /** @brief map of SDEventPlus child pointer added to event loop */
+    std::map<pid_t, std::unique_ptr<Child>> childPtrMap;
+
+  private:
+    /** @brief Create Dump entry d-bus object
+     *  @param[in] fullPath - Full path of the Dump file name
+     */
+    void createEntry(const std::filesystem::path& fullPath);
+
+    /** @brief Remove specified watch object pointer from the
+     *        watch map and associated entry from the map.
+     *        @param[in] path - unique identifier of the map
+     */
+    void removeWatch(const std::filesystem::path& path);
+
+    /** @brief Dump main watch object */
+    Watch dumpWatch;
+
+    /** @brief Child directory path and its associated watch object map
+     *        [path:watch object]
+     */
+    std::map<std::filesystem::path, std::unique_ptr<Watch>> childWatchMap;
+
+    /** @brief A regex based format for the filename */
+    std::string dumpFilenameFormat;
+
+    /** @brief Maximum possible size of a dump */
+    uint64_t maxDumpSize;
+
+    /** @brief Minimum viable dump size */
+    uint64_t minDumpSize;
+
+    /** @brief The total size allocated for a kind of dump */
+    uint64_t allocatedSize;
+};
+
+} // namespace bmc_stored
+} // namespace dump
+} // namespace phosphor
diff --git a/meson.build b/meson.build
index 94ce4d0..052fad8 100644
--- a/meson.build
+++ b/meson.build
@@ -160,6 +160,7 @@
 phosphor_dump_manager_sources = [
         'dump_entry.cpp',
         'dump_manager.cpp',
+        'dump_manager_bmcstored.cpp',
         'dump_manager_bmc.cpp',
         'dump_manager_main.cpp',
         'dump_serialize.cpp',