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/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