Create dump manager for each dump type.

Currently all types of dumps exist in the same path
and under the single dump manager. When there are
multiple dumps to be created separate path is needed
for creating and managing the dump. this commit
is splitting the dump manager into multiple objects
without  adding any new functionality. There will be
only one dump manager process but it will contain
seperate dump manager objects for system and BMC
dumps as per current scope.

Tested the existing dump functions with the build
- created bmc dump
- created system dump using notify
- deleted dump entry
- offloaded bmc dump

Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: Id4806660be1f1ba0b3cb6f840ae185a967f05a83
diff --git a/dump_internal.hpp b/dump_internal.hpp
index 529ca21..027480f 100644
--- a/dump_internal.hpp
+++ b/dump_internal.hpp
@@ -9,6 +9,8 @@
 {
 namespace dump
 {
+namespace bmc
+{
 
 class Manager;
 namespace internal
@@ -16,7 +18,7 @@
 
 using CreateIface = sdbusplus::server::object::object<
     sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create>;
-using Mgr = phosphor::dump::Manager;
+using Mgr = phosphor::dump::bmc::Manager;
 
 /** @class Manager
  *  @brief Implementation for the
@@ -55,5 +57,6 @@
 };
 
 } // namespace internal
+} // namespace bmc
 } // namespace dump
 } // namespace phosphor
diff --git a/dump_manager.cpp b/dump_manager.cpp
index 3fd03ee..455023e 100644
--- a/dump_manager.cpp
+++ b/dump_manager.cpp
@@ -1,132 +1,10 @@
-#include "config.h"
-
 #include "dump_manager.hpp"
 
-#include "bmc_dump_entry.hpp"
-#include "dump_internal.hpp"
-#include "system_dump_entry.hpp"
-#include "xyz/openbmc_project/Common/error.hpp"
-#include "xyz/openbmc_project/Dump/Create/error.hpp"
-
-#include <sys/inotify.h>
-#include <unistd.h>
-
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/elog.hpp>
-#include <regex>
-
 namespace phosphor
 {
 namespace dump
 {
 
-using namespace sdbusplus::xyz::openbmc_project::Common::Error;
-using namespace phosphor::logging;
-
-namespace internal
-{
-
-void Manager::create(Type type, std::vector<std::string> fullPaths)
-{
-    dumpMgr.phosphor::dump::Manager::captureDump(type, fullPaths);
-}
-
-} // namespace internal
-
-uint32_t Manager::createDump()
-{
-    std::vector<std::string> paths;
-    return captureDump(Type::UserRequested, paths);
-}
-
-uint32_t Manager::captureDump(Type type,
-                              const std::vector<std::string>& fullPaths)
-{
-    // Get Dump size.
-    auto size = getAllowedSize();
-
-    pid_t pid = fork();
-
-    if (pid == 0)
-    {
-        fs::path dumpPath(BMC_DUMP_PATH);
-        auto id = std::to_string(lastEntryId + 1);
-        dumpPath /= id;
-
-        // get dreport type map entry
-        auto tempType = TypeMap.find(type);
-
-        execl("/usr/bin/dreport", "dreport", "-d", dumpPath.c_str(), "-i",
-              id.c_str(), "-s", std::to_string(size).c_str(), "-q", "-v", "-p",
-              fullPaths.empty() ? "" : fullPaths.front().c_str(), "-t",
-              tempType->second.c_str(), nullptr);
-
-        // dreport script execution is failed.
-        auto error = errno;
-        log<level::ERR>("Error occurred during dreport function execution",
-                        entry("ERRNO=%d", error));
-        elog<InternalFailure>();
-    }
-    else if (pid > 0)
-    {
-        auto rc = sd_event_add_child(eventLoop.get(), nullptr, pid,
-                                     WEXITED | WSTOPPED, callback, nullptr);
-        if (0 > rc)
-        {
-            // Failed to add to event loop
-            log<level::ERR>("Error occurred during the sd_event_add_child call",
-                            entry("RC=%d", rc));
-            elog<InternalFailure>();
-        }
-    }
-    else
-    {
-        auto error = errno;
-        log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", error));
-        elog<InternalFailure>();
-    }
-
-    return ++lastEntryId;
-}
-
-void Manager::createEntry(const fs::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>("Invalid Dump file name",
-                        entry("FILENAME=%s", file.filename().c_str()));
-        return;
-    }
-
-    auto idString = match[ID_POS];
-    auto msString = match[EPOCHTIME_POS];
-
-    try
-    {
-        auto id = stoul(idString);
-        // Entry Object path.
-        auto objPath = fs::path(OBJ_ENTRY) / std::to_string(id);
-
-        entries.insert(
-            std::make_pair(id, std::make_unique<bmc::Entry>(
-                                   bus, objPath.c_str(), id, stoull(msString),
-                                   fs::file_size(file), file, *this)));
-    }
-    catch (const std::invalid_argument& e)
-    {
-        log<level::ERR>(e.what());
-        return;
-    }
-}
-
 void Manager::erase(uint32_t entryId)
 {
     entries.erase(entryId);
@@ -143,119 +21,5 @@
     }
 }
 
-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)
-        {
-            removeWatch(i.first);
-
-            createEntry(i.first);
-        }
-        // Start inotify watch on newly created directory.
-        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));
-
-            childWatchMap.emplace(i.first, std::move(watchObj));
-        }
-    }
-}
-
-void Manager::removeWatch(const fs::path& path)
-{
-    // Delete Watch entry from map.
-    childWatchMap.erase(path);
-}
-
-void Manager::restore()
-{
-    fs::path dir(BMC_DUMP_PATH);
-    if (!fs::exists(dir) || fs::is_empty(dir))
-    {
-        return;
-    }
-
-    // Dump file path: <BMC_DUMP_PATH>/<id>/<filename>
-    for (const auto& p : fs::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 ((fs::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 = fs::directory_iterator(p.path());
-            // Create dump entry d-bus object.
-            if (fileIt != fs::end(fileIt))
-            {
-                createEntry(fileIt->path());
-            }
-        }
-    }
-}
-
-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;
-
-    // Get current size of the dump directory.
-    for (const auto& p : fs::recursive_directory_iterator(BMC_DUMP_PATH))
-    {
-        if (!fs::is_directory(p))
-        {
-            size += fs::file_size(p);
-        }
-    }
-
-    // Convert size into KB
-    size = size / 1024;
-
-    // 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);
-
-    if (size < BMC_DUMP_MIN_SPACE_REQD)
-    {
-        // Reached to maximum limit
-        elog<QuotaExceeded>(Reason("Not enough space: Delete old dumps"));
-    }
-    if (size > BMC_DUMP_MAX_SIZE)
-    {
-        size = BMC_DUMP_MAX_SIZE;
-    }
-
-    return size;
-}
-
-void Manager::notify(NewDump::DumpType, uint32_t dumpId, uint64_t size)
-{
-    // Get the timestamp
-    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
-                  std::chrono::system_clock::now().time_since_epoch())
-                  .count();
-    // Get the id
-    auto id = lastEntryId + 1;
-    auto idString = std::to_string(id);
-    auto objPath = fs::path(OBJ_ENTRY) / idString;
-    entries.insert(std::make_pair(
-        id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, ms, size,
-                                            dumpId, *this)));
-    lastEntryId++;
-}
-
 } // namespace dump
 } // namespace phosphor
diff --git a/dump_manager.hpp b/dump_manager.hpp
index 40f62fb..967813a 100644
--- a/dump_manager.hpp
+++ b/dump_manager.hpp
@@ -1,60 +1,26 @@
 #pragma once
 
-#include "config.h"
-
 #include "dump_entry.hpp"
-#include "dump_utils.hpp"
-#include "watch.hpp"
 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
-#include "xyz/openbmc_project/Dump/Internal/Create/server.hpp"
-#include "xyz/openbmc_project/Dump/NewDump/server.hpp"
 
-#include <experimental/filesystem>
 #include <sdbusplus/bus.hpp>
 #include <sdbusplus/server/object.hpp>
-#include <xyz/openbmc_project/Dump/Create/server.hpp>
 
 namespace phosphor
 {
 namespace dump
 {
-namespace internal
-{
 
-class Manager;
-
-} // namespace internal
-
-using UserMap = phosphor::dump::inotify::UserMap;
-
-using Type =
-    sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
-
-using CreateIface = sdbusplus::server::object::object<
-    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll,
-    sdbusplus::xyz::openbmc_project::Dump::server::Create,
-    sdbusplus::xyz::openbmc_project::Dump::server::NewDump>;
-
-namespace fs = std::experimental::filesystem;
-
-using Watch = phosphor::dump::inotify::Watch;
-
-// Type to dreport type  string map
-static const std::map<Type, std::string> TypeMap = {
-    {Type::ApplicationCored, "core"},
-    {Type::UserRequested, "user"},
-    {Type::InternalFailure, "elog"},
-    {Type::Checkstop, "checkstop"}};
+using Iface = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
 
 /** @class Manager
- *  @brief OpenBMC Dump  manager implementation.
+ *  @brief Dump  manager base class.
  *  @details A concrete implementation for the
- *  xyz.openbmc_project.Dump.Create DBus API and
  *  xyz::openbmc_project::Collection::server::DeleteAll.
  */
-class Manager : public CreateIface
+class Manager : public Iface
 {
-    friend class internal::Manager;
     friend class Entry;
 
   public:
@@ -69,56 +35,21 @@
      *  @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 of the dump entry.
      */
-    Manager(sdbusplus::bus::bus& bus, const EventPtr& event, const char* path) :
-        CreateIface(bus, path), bus(bus), eventLoop(event.get()),
-        lastEntryId(0),
-        dumpWatch(
-            eventLoop, IN_NONBLOCK, IN_CLOSE_WRITE | IN_CREATE, EPOLLIN,
-            BMC_DUMP_PATH,
-            std::bind(std::mem_fn(&phosphor::dump::Manager::watchCallback),
-                      this, std::placeholders::_1))
+    Manager(sdbusplus::bus::bus& bus, const char* path,
+            const std::string& baseEntryPath) :
+        Iface(bus, path, true),
+        bus(bus), lastEntryId(0), baseEntryPath(baseEntryPath)
     {
     }
 
-    /** @brief Implementation for CreateDump
-     *  Method to create Dump.
-     *
-     *  @return id - The Dump entry id number.
-     */
-    uint32_t createDump() override;
-
-    /** @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();
+    virtual void restore() = 0;
 
-    /** @brief Notify the dump manager about creation of a new dump.
-     *  @param[in] dumpType - Type of the Dump.
-     *  @param[in] dumpId - Id from the source of the dump.
-     *  @param[in] size - Size of the dump.
-     */
-    void notify(NewDump::DumpType dumpType, uint32_t dumpId, uint64_t size);
-
-  private:
-    /** @brief Create Dump entry d-bus object
-     *  @param[in] fullPath - Full path of the Dump file name
-     */
-    void createEntry(const fs::path& fullPath);
-
-    /**  @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
-     *             to be included as part of Dump package.
-     *  @return id - The Dump entry id number.
-     */
-    uint32_t captureDump(Type type, const std::vector<std::string>& fullPaths);
-
+  protected:
     /** @brief Erase specified entry d-bus object
      *
      * @param[in] entryId - unique identifier of the entry
@@ -131,51 +62,17 @@
      */
     void deleteAll() override;
 
-    /** @brief sd_event_add_child callback
-     *
-     *  @param[in] s - event source
-     *  @param[in] si - signal info
-     *  @param[in] userdata - pointer to Watch object
-     *
-     *  @returns 0 on success, -1 on fail
-     */
-    static int callback(sd_event_source*, const siginfo_t*, void*)
-    {
-        // No specific action required in
-        // the sd_event_add_child callback.
-        return 0;
-    }
-    /** @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 fs::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 DBus bus connection. */
     sdbusplus::bus::bus& bus;
 
-    /** @brief sdbusplus Dump event loop */
-    EventPtr eventLoop;
-
     /** @brief Dump Entry dbus objects map based on entry id */
     std::map<uint32_t, std::unique_ptr<Entry>> entries;
 
     /** @brief Id of the last Dump entry */
     uint32_t lastEntryId;
 
-    /** @brief Dump main watch object */
-    Watch dumpWatch;
-
-    /** @brief Child directory path and its associated watch object map
-     *        [path:watch object]
-     */
-    std::map<fs::path, std::unique_ptr<Watch>> childWatchMap;
+    /** @bried base object path for the entry object */
+    std::string baseEntryPath;
 };
 
 } // namespace dump
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
new file mode 100644
index 0000000..f6556f1
--- /dev/null
+++ b/dump_manager_bmc.cpp
@@ -0,0 +1,232 @@
+#include "config.h"
+
+#include "dump_manager_bmc.hpp"
+
+#include "bmc_dump_entry.hpp"
+#include "dump_internal.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
+#include "xyz/openbmc_project/Dump/Create/error.hpp"
+
+#include <sys/inotify.h>
+#include <unistd.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <regex>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace bmc
+{
+
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+using namespace phosphor::logging;
+
+namespace internal
+{
+
+void Manager::create(Type type, std::vector<std::string> fullPaths)
+{
+    dumpMgr.phosphor::dump::bmc::Manager::captureDump(type, fullPaths);
+}
+
+} // namespace internal
+
+uint32_t Manager::createDump()
+{
+    std::vector<std::string> paths;
+    return captureDump(Type::UserRequested, paths);
+}
+
+uint32_t Manager::captureDump(Type type,
+                              const std::vector<std::string>& fullPaths)
+{
+    // Get Dump size.
+    auto size = getAllowedSize();
+
+    pid_t pid = fork();
+
+    if (pid == 0)
+    {
+        fs::path dumpPath(dumpDir);
+        auto id = std::to_string(lastEntryId + 1);
+        dumpPath /= id;
+
+        // get dreport type map entry
+        auto tempType = TypeMap.find(type);
+
+        execl("/usr/bin/dreport", "dreport", "-d", dumpPath.c_str(), "-i",
+              id.c_str(), "-s", std::to_string(size).c_str(), "-q", "-v", "-p",
+              fullPaths.empty() ? "" : fullPaths.front().c_str(), "-t",
+              tempType->second.c_str(), nullptr);
+
+        // dreport script execution is failed.
+        auto error = errno;
+        log<level::ERR>("Error occurred during dreport function execution",
+                        entry("ERRNO=%d", error));
+        elog<InternalFailure>();
+    }
+    else if (pid > 0)
+    {
+        auto rc = sd_event_add_child(eventLoop.get(), nullptr, pid,
+                                     WEXITED | WSTOPPED, callback, nullptr);
+        if (0 > rc)
+        {
+            // Failed to add to event loop
+            log<level::ERR>("Error occurred during the sd_event_add_child call",
+                            entry("RC=%d", rc));
+            elog<InternalFailure>();
+        }
+    }
+    else
+    {
+        auto error = errno;
+        log<level::ERR>("Error occurred during fork", entry("ERRNO=%d", error));
+        elog<InternalFailure>();
+    }
+
+    return ++lastEntryId;
+}
+
+void Manager::createEntry(const fs::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>("Invalid Dump file name",
+                        entry("FILENAME=%s", file.filename().c_str()));
+        return;
+    }
+
+    auto idString = match[ID_POS];
+    auto msString = match[EPOCHTIME_POS];
+
+    try
+    {
+        auto id = stoul(idString);
+        // Entry Object path.
+        auto objPath = fs::path(baseEntryPath) / std::to_string(id);
+
+        entries.insert(
+            std::make_pair(id, std::make_unique<bmc::Entry>(
+                                   bus, objPath.c_str(), id, stoull(msString),
+                                   fs::file_size(file), file, *this)));
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>(e.what());
+        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)
+        {
+            removeWatch(i.first);
+
+            createEntry(i.first);
+        }
+        // Start inotify watch on newly created directory.
+        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::bmc::Manager::watchCallback),
+                    this, std::placeholders::_1));
+
+            childWatchMap.emplace(i.first, std::move(watchObj));
+        }
+    }
+}
+
+void Manager::removeWatch(const fs::path& path)
+{
+    // Delete Watch entry from map.
+    childWatchMap.erase(path);
+}
+
+void Manager::restore()
+{
+    fs::path dir(dumpDir);
+    if (!fs::exists(dir) || fs::is_empty(dir))
+    {
+        return;
+    }
+
+    // Dump file path: <DUMP_PATH>/<id>/<filename>
+    for (const auto& p : fs::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 ((fs::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 = fs::directory_iterator(p.path());
+            // Create dump entry d-bus object.
+            if (fileIt != fs::end(fileIt))
+            {
+                createEntry(fileIt->path());
+            }
+        }
+    }
+}
+
+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;
+
+    // Get current size of the dump directory.
+    for (const auto& p : fs::recursive_directory_iterator(dumpDir))
+    {
+        if (!fs::is_directory(p))
+        {
+            size += fs::file_size(p);
+        }
+    }
+
+    // Convert size into KB
+    size = size / 1024;
+
+    // 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);
+
+    if (size < BMC_DUMP_MIN_SPACE_REQD)
+    {
+        // Reached to maximum limit
+        elog<QuotaExceeded>(Reason("Not enough space: Delete old dumps"));
+    }
+    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
new file mode 100644
index 0000000..49ba573
--- /dev/null
+++ b/dump_manager_bmc.hpp
@@ -0,0 +1,156 @@
+#pragma once
+
+#include "dump_manager.hpp"
+#include "dump_utils.hpp"
+#include "watch.hpp"
+#include "xyz/openbmc_project/Dump/Internal/Create/server.hpp"
+
+#include <experimental/filesystem>
+#include <xyz/openbmc_project/Dump/Create/server.hpp>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace bmc
+{
+namespace internal
+{
+
+class Manager;
+
+} // namespace internal
+
+using CreateIface = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Dump::server::Create>;
+
+using UserMap = phosphor::dump::inotify::UserMap;
+
+using Type =
+    sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
+
+namespace fs = std::experimental::filesystem;
+
+using Watch = phosphor::dump::inotify::Watch;
+
+// Type to dreport type  string map
+static const std::map<Type, std::string> TypeMap = {
+    {Type::ApplicationCored, "core"},
+    {Type::UserRequested, "user"},
+    {Type::InternalFailure, "elog"},
+    {Type::Checkstop, "checkstop"}};
+
+/** @class Manager
+ *  @brief OpenBMC Dump  manager implementation.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Dump.Create DBus API
+ */
+class Manager : virtual public CreateIface,
+                virtual public phosphor::dump::Manager
+{
+    friend class internal::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.
+     */
+    Manager(sdbusplus::bus::bus& 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)
+    {
+    }
+
+    /** @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 Dump.
+     *
+     *  @return id - The Dump entry id number.
+     */
+    uint32_t createDump() override;
+
+  private:
+    /** @brief Create Dump entry d-bus object
+     *  @param[in] fullPath - Full path of the Dump file name
+     */
+    void createEntry(const fs::path& fullPath);
+
+    /**  @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
+     *             to be included as part of Dump package.
+     *  @return id - The Dump entry id number.
+     */
+    uint32_t captureDump(Type type, const std::vector<std::string>& fullPaths);
+
+    /** @brief sd_event_add_child callback
+     *
+     *  @param[in] s - event source
+     *  @param[in] si - signal info
+     *  @param[in] userdata - pointer to Watch object
+     *
+     *  @returns 0 on success, -1 on fail
+     */
+    static int callback(sd_event_source*, const siginfo_t*, void*)
+    {
+        // No specific action required in
+        // the sd_event_add_child callback.
+        return 0;
+    }
+    /** @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 fs::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 Child directory path and its associated watch object map
+     *        [path:watch object]
+     */
+    std::map<fs::path, std::unique_ptr<Watch>> childWatchMap;
+};
+
+} // namespace bmc
+} // namespace dump
+} // namespace phosphor
diff --git a/dump_manager_main.cpp b/dump_manager_main.cpp
index cd76742..4ac89af 100644
--- a/dump_manager_main.cpp
+++ b/dump_manager_main.cpp
@@ -2,6 +2,8 @@
 
 #include "dump_internal.hpp"
 #include "dump_manager.hpp"
+#include "dump_manager_bmc.hpp"
+#include "dump_manager_system.hpp"
 #include "elog_watch.hpp"
 #include "watch.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
@@ -57,10 +59,14 @@
 
     try
     {
-        phosphor::dump::Manager manager(bus, eventP, DUMP_OBJPATH);
+        phosphor::dump::bmc::Manager bmcDumpMgr(
+            bus, eventP, BMC_DUMP_OBJPATH, BMC_DUMP_OBJ_ENTRY, BMC_DUMP_PATH);
         // Restore dump d-bus objects.
-        manager.restore();
-        phosphor::dump::internal::Manager mgr(bus, manager, OBJ_INTERNAL);
+        bmcDumpMgr.restore();
+        phosphor::dump::bmc::internal::Manager mgr(bus, bmcDumpMgr,
+                                                   OBJ_INTERNAL);
+        phosphor::dump::system::Manager systemDumpMgr(bus, SYSTEM_DUMP_OBJPATH,
+                                                      SYSTEM_DUMP_OBJ_ENTRY);
         phosphor::dump::elog::Watch eWatch(bus, mgr);
         bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
 
diff --git a/dump_manager_system.cpp b/dump_manager_system.cpp
new file mode 100644
index 0000000..ab7ca72
--- /dev/null
+++ b/dump_manager_system.cpp
@@ -0,0 +1,43 @@
+#include "config.h"
+
+#include "dump_manager_system.hpp"
+
+#include "system_dump_entry.hpp"
+
+#include <phosphor-logging/elog.hpp>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace system
+{
+
+using namespace phosphor::logging;
+
+void Manager::notify(NewDump::DumpType dumpType, uint32_t dumpId, uint64_t size)
+{
+
+    if (dumpType != NewDump::DumpType::System)
+    {
+        log<level::ERR>("Only system dump is supported",
+                        entry("DUMPTYPE=%d", dumpType));
+        return;
+    }
+    // Get the timestamp
+    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
+                  std::chrono::system_clock::now().time_since_epoch())
+                  .count();
+    // Get the id
+    auto id = lastEntryId + 1;
+    auto idString = std::to_string(id);
+    auto objPath = fs::path(baseEntryPath) / idString;
+    entries.insert(std::make_pair(
+        id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, ms, size,
+                                            dumpId, *this)));
+    lastEntryId++;
+}
+
+} // namespace system
+} // namespace dump
+} // namespace phosphor
diff --git a/dump_manager_system.hpp b/dump_manager_system.hpp
new file mode 100644
index 0000000..948dc3d
--- /dev/null
+++ b/dump_manager_system.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include "dump_manager.hpp"
+#include "dump_utils.hpp"
+#include "xyz/openbmc_project/Dump/NewDump/server.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/object.hpp>
+
+namespace phosphor
+{
+namespace dump
+{
+namespace system
+{
+
+using NotifyIface = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Dump::server::NewDump>;
+
+/** @class Manager
+ *  @brief System Dump  manager implementation.
+ *  @details A concrete implementation for the
+ *  xyz.openbmc_project.Dump.Notify DBus API
+ */
+class Manager : virtual public NotifyIface,
+                virtual 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 of the dump entry.
+     */
+    Manager(sdbusplus::bus::bus& bus, const char* path,
+            const std::string& baseEntryPath) :
+        NotifyIface(bus, path),
+        phosphor::dump::Manager(bus, path, baseEntryPath)
+    {
+    }
+
+    void restore() override
+    {
+        // TODO #2597  Implement the restore to restore the dump entries
+        // after the service restart.
+    }
+
+    /** @brief Notify the system dump manager about creation of a new dump.
+     *  @param[in] dumpType - Type of the Dump.
+     *  @param[in] dumpId - Id from the source of the dump.
+     *  @param[in] size - Size of the dump.
+     */
+    void notify(NewDump::DumpType dumpType, uint32_t dumpId,
+                uint64_t size) override;
+};
+
+} // namespace system
+} // namespace dump
+} // namespace phosphor
diff --git a/elog_watch.cpp b/elog_watch.cpp
index cbcfa3c..ed26fd5 100644
--- a/elog_watch.cpp
+++ b/elog_watch.cpp
@@ -138,9 +138,10 @@
         phosphor::dump::elog::serialize(elogList);
 
         auto item = std::find_if(
-            TypeMap.begin(), TypeMap.end(),
+            phosphor::dump::bmc::TypeMap.begin(),
+            phosphor::dump::bmc::TypeMap.end(),
             [errorType](const auto& err) { return (err.second == errorType); });
-        if (item != TypeMap.end())
+        if (item != phosphor::dump::bmc::TypeMap.end())
         {
             iMgr.IMgr::create((*item).first, fullPaths);
         }
diff --git a/elog_watch.hpp b/elog_watch.hpp
index 2c808cf..3b345b5 100644
--- a/elog_watch.hpp
+++ b/elog_watch.hpp
@@ -2,7 +2,7 @@
 
 #include "config.h"
 
-#include "dump_manager.hpp"
+#include "dump_manager_bmc.hpp"
 
 #include <cereal/access.hpp>
 #include <sdbusplus/bus.hpp>
@@ -16,7 +16,7 @@
 namespace elog
 {
 
-using IMgr = phosphor::dump::internal::Manager;
+using IMgr = phosphor::dump::bmc::internal::Manager;
 using EId = uint32_t;
 using ElogList = std::set<EId>;
 
diff --git a/meson.build b/meson.build
index 5dfe67d..8492d5d 100644
--- a/meson.build
+++ b/meson.build
@@ -29,14 +29,23 @@
 conf_data.set_quoted('DUMP_OBJPATH', get_option('DUMP_OBJPATH'),
                       description : 'The Dump manager Dbus root'
                     )
+conf_data.set_quoted('BMC_DUMP_OBJPATH', get_option('BMC_DUMP_OBJPATH'),
+                      description : 'The BMC Dump manager Dbus path'
+                    )
+conf_data.set_quoted('SYSTEM_DUMP_OBJPATH', get_option('SYSTEM_DUMP_OBJPATH'),
+                      description : 'The system Dump manager Dbus path'
+                    )
 conf_data.set_quoted('CORE_FILE_DIR', get_option('CORE_FILE_DIR'),
                       description : 'Directory where core dumps are placed'
                     )
 conf_data.set_quoted('OBJ_INTERNAL', get_option('OBJ_INTERNAL'),
                       description : 'Internal Dump manager Dbus object path'
                     )
-conf_data.set_quoted('OBJ_ENTRY', get_option('OBJ_ENTRY'),
-                      description : 'The dump entry DBus object path'
+conf_data.set_quoted('SYSTEM_DUMP_OBJ_ENTRY', get_option('SYSTEM_DUMP_OBJ_ENTRY'),
+                      description : 'The system dump entry DBus object path'
+                    )
+conf_data.set_quoted('BMC_DUMP_OBJ_ENTRY', get_option('BMC_DUMP_OBJ_ENTRY'),
+                      description : 'The BMC dump entry DBus object path'
                     )
 conf_data.set_quoted('BMC_DUMP_PATH', get_option('BMC_DUMP_PATH'),
                      description : 'Directory where bmc dumps are placed')
@@ -93,6 +102,8 @@
 phosphor_dump_manager_sources = [
         'dump_entry.cpp',
         'dump_manager.cpp',
+        'dump_manager_bmc.cpp',
+        'dump_manager_system.cpp',
         'dump_manager_main.cpp',
         'dump_serialize.cpp',
         'elog_watch.cpp',
diff --git a/meson_options.txt b/meson_options.txt
index 75d97a8..21517ca 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -18,6 +18,16 @@
         description : 'The Dump manager Dbus root'
       )
 
+option('BMC_DUMP_OBJPATH', type : 'string',
+        value : '/xyz/openbmc_project/dump/bmc',
+        description : 'The BMC Dump manager Dbus object path'
+      )
+
+option('SYSTEM_DUMP_OBJPATH', type : 'string',
+        value : '/xyz/openbmc_project/dump/system',
+        description : 'The system Dump manager Dbus object path'
+      )
+
 option('CORE_FILE_DIR', type : 'string',
         value : '/var/lib/systemd/coredump',
         description : 'Directory where core dumps are placed'
@@ -28,9 +38,14 @@
         description : 'Internal Dump manager Dbus object path'
       )
 
-option('OBJ_ENTRY', type : 'string',
-        value : '/xyz/openbmc_project/dump/entry',
-        description : 'The dump entry DBus object path'
+option('BMC_DUMP_OBJ_ENTRY', type : 'string',
+        value : '/xyz/openbmc_project/dump/bmc/entry',
+        description : 'The BMC dump entry DBus object path'
+      )
+
+option('SYSTEM_DUMP_OBJ_ENTRY', type : 'string',
+        value : '/xyz/openbmc_project/dump/system/entry',
+        description : 'The system dump entry DBus object path'
       )
 
 option('BMC_DUMP_PATH', type : 'string',