Return the object path for user requested dumps.

Return the object path to a dump entry for the user requested
dump. A dump entry will be created when the user request for
the dump and that will be used for tracking the progress.
 The dump details like size etc  will be empty and the complete
details will be filled once the dump creation is completed.

Executed current BMC and system dump test cases on a test build
- Create BMC dump
- List All dumps
- Offload BMC dump
- Delete BMC dump
- Create manual system dump.
- Attempt to offload dump.

Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I89b252e2731f4f1fb924d26c7ac05999341fc691
diff --git a/bmc_dump_entry.hpp b/bmc_dump_entry.hpp
index 9219be4..b9549f2 100644
--- a/bmc_dump_entry.hpp
+++ b/bmc_dump_entry.hpp
@@ -68,6 +68,20 @@
      */
     void initiateOffload(std::string uri) override;
 
+    /** @brief Method to update an existing dump entry, once the dump creation
+     *  is completed this function will be used to update the entry which got
+     *  created during the dump request.
+     *  @param[in] timeStamp - Dump creation timestamp
+     *  @param[in] fileSize - Dump file size in bytes.
+     *  @param[in] file - Name of dump file.
+     */
+    void update(uint64_t timeStamp, uint64_t fileSize, const fs::path& filePath)
+    {
+        elapsed(timeStamp);
+        size(fileSize);
+        file = filePath;
+    }
+
   private:
     /** @Dump file name */
     fs::path file;
diff --git a/dump-extensions/openpower-dumps/dump_manager_system.cpp b/dump-extensions/openpower-dumps/dump_manager_system.cpp
index 865ed91..891326b 100644
--- a/dump-extensions/openpower-dumps/dump_manager_system.cpp
+++ b/dump-extensions/openpower-dumps/dump_manager_system.cpp
@@ -3,7 +3,9 @@
 #include "dump_manager_system.hpp"
 
 #include "system_dump_entry.hpp"
+#include "xyz/openbmc_project/Common/error.hpp"
 
+#include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/elog.hpp>
 
 namespace phosphor
@@ -14,6 +16,7 @@
 {
 
 using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 
 void Manager::notify(NewDump::DumpType dumpType, uint32_t dumpId, uint64_t size)
 {
@@ -28,17 +31,50 @@
     auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
                   std::chrono::system_clock::now().time_since_epoch())
                   .count();
+
+    // System dump can get created due to a fault in server
+    // or by request from user. A system dump by fault is
+    // first reported here, but for a user requested dump an
+    // entry will be created first with invalid source id.
+    // Since there can be only one system dump creation at a time,
+    // if there is an entry with invalid sourceId update that.
+    for (auto& entry : entries)
+    {
+        phosphor::dump::system::Entry* sysEntry =
+            dynamic_cast<phosphor::dump::system::Entry*>(entry.second.get());
+        if (sysEntry->sourceDumpId() == INVALID_SOURCE_ID)
+        {
+            sysEntry->update(ms, size, dumpId);
+            return;
+        }
+    }
+
     // 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)));
+
+    try
+    {
+        entries.insert(std::make_pair(
+            id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, ms,
+                                                size, dumpId, *this)));
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>(e.what());
+        log<level::ERR>("Error in creating system dump entry",
+                        entry("OBJECTPATH=%s", objPath.c_str()),
+                        entry("ID=%d", id), entry("TIMESTAMP=%ull", ms),
+                        entry("SIZE=%d", size), entry("SOURCEID=%d", dumpId));
+        report<InternalFailure>();
+        return;
+    }
     lastEntryId++;
+    return;
 }
 
-uint32_t Manager::createDump()
+sdbusplus::message::object_path Manager::createDump()
 {
     constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
     constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
@@ -50,7 +86,28 @@
     method.append(DIAG_MOD_TARGET); // unit to activate
     method.append("replace");
     bus.call_noreply(method);
-    return ++lastEntryId;
+
+    auto id = lastEntryId + 1;
+    auto idString = std::to_string(id);
+    auto objPath = fs::path(baseEntryPath) / idString;
+
+    try
+    {
+        entries.insert(std::make_pair(
+            id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, 0, 0,
+                                                INVALID_SOURCE_ID, *this)));
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>(e.what());
+        log<level::ERR>("Error in creating system dump entry",
+                        entry("OBJECTPATH=%s", objPath.c_str()),
+                        entry("ID=%d", id));
+        elog<InternalFailure>();
+        return std::string();
+    }
+    lastEntryId++;
+    return objPath.string();
 }
 
 } // namespace system
diff --git a/dump-extensions/openpower-dumps/dump_manager_system.hpp b/dump-extensions/openpower-dumps/dump_manager_system.hpp
index 441611d..126bb59 100644
--- a/dump-extensions/openpower-dumps/dump_manager_system.hpp
+++ b/dump-extensions/openpower-dumps/dump_manager_system.hpp
@@ -15,6 +15,7 @@
 namespace system
 {
 
+constexpr uint32_t INVALID_SOURCE_ID = 0xFFFFFFFF;
 using NotifyIface = sdbusplus::server::object::object<
     sdbusplus::xyz::openbmc_project::Dump::server::Create,
     sdbusplus::xyz::openbmc_project::Dump::server::NewDump>;
@@ -63,11 +64,12 @@
                 uint64_t size) override;
 
     /** @brief Implementation for CreateDump
-     *  Method to create Dump.
+     *  Method to create a new system dump entry when user
+     *  requests for a new system dump.
      *
-     *  @return id - The Dump entry id number.
+     *  @return object_path - The path to the new dump entry.
      */
-    uint32_t createDump() override;
+    sdbusplus::message::object_path createDump() override;
 };
 
 } // namespace system
diff --git a/dump-extensions/openpower-dumps/system_dump_entry.hpp b/dump-extensions/openpower-dumps/system_dump_entry.hpp
index 895ca37..4f7d233 100644
--- a/dump-extensions/openpower-dumps/system_dump_entry.hpp
+++ b/dump-extensions/openpower-dumps/system_dump_entry.hpp
@@ -61,6 +61,18 @@
      *  @param[in] uri - URI to offload dump.
      */
     void initiateOffload(std::string uri);
+
+    /** @brief Method to update an existing dump entry
+     *  @param[in] timeStamp - Dump creation timestamp
+     *  @param[in] dumpSize - Dump size in bytes.
+     *  @param[in] sourceId - DumpId provided by the source.
+     */
+    void update(uint64_t timeStamp, uint64_t dumpSize, const uint32_t sourceId)
+    {
+        elapsed(timeStamp);
+        size(dumpSize);
+        sourceDumpId(sourceId);
+    }
 };
 
 } // namespace system
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
index f6556f1..acd14a2 100644
--- a/dump_manager_bmc.cpp
+++ b/dump_manager_bmc.cpp
@@ -34,10 +34,30 @@
 
 } // namespace internal
 
-uint32_t Manager::createDump()
+sdbusplus::message::object_path Manager::createDump()
 {
     std::vector<std::string> paths;
-    return captureDump(Type::UserRequested, paths);
+    auto id = captureDump(Type::UserRequested, paths);
+
+    // Entry Object path.
+    auto objPath = fs::path(baseEntryPath) / std::to_string(id);
+
+    try
+    {
+        entries.insert(std::make_pair(
+            id, std::make_unique<bmc::Entry>(bus, objPath.c_str(), id, 0, 0,
+                                             std::string(), *this)));
+    }
+    catch (const std::invalid_argument& e)
+    {
+        log<level::ERR>(e.what());
+        log<level::ERR>("Error in creating dump entry",
+                        entry("OBJECTPATH=%s", objPath.c_str()),
+                        entry("ID=%d", id));
+        elog<InternalFailure>();
+    }
+
+    return objPath.string();
 }
 
 uint32_t Manager::captureDump(Type type,
@@ -110,12 +130,22 @@
     auto idString = match[ID_POS];
     auto msString = match[EPOCHTIME_POS];
 
+    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(stoull(msString), fs::file_size(file), file);
+        return;
+    }
+
+    // Entry Object path.
+    auto objPath = fs::path(baseEntryPath) / std::to_string(id);
+
     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),
@@ -124,6 +154,12 @@
     catch (const std::invalid_argument& e)
     {
         log<level::ERR>(e.what());
+        log<level::ERR>("Error in creating dump entry",
+                        entry("OBJECTPATH=%s", objPath.c_str()),
+                        entry("ID=%d", id),
+                        entry("TIMESTAMP=%ull", stoull(msString)),
+                        entry("SIZE=%d", fs::file_size(file)),
+                        entry("FILENAME=%s", file.c_str()));
         return;
     }
 }
diff --git a/dump_manager_bmc.hpp b/dump_manager_bmc.hpp
index 49ba573..79a7bc7 100644
--- a/dump_manager_bmc.hpp
+++ b/dump_manager_bmc.hpp
@@ -90,11 +90,11 @@
     void restore() override;
 
     /** @brief Implementation for CreateDump
-     *  Method to create Dump.
+     *  Method to create a BMC dump entry when user requests for a new BMC dump
      *
-     *  @return id - The Dump entry id number.
+     *  @return object_path - The object path of the new dump entry.
      */
-    uint32_t createDump() override;
+    sdbusplus::message::object_path createDump() override;
 
   private:
     /** @brief Create Dump entry d-bus object