Progress tracking support for dump entries.

A new attribute status is added which indicates the status of the
dump creation. The user requested dump entries will be created
with InProgress and updated to Completed once the dump creation
is completed

Test: Request user initiated BMC and system dump and
make sure the progress is changing and the dump details
are updated correctly

Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
Change-Id: I68e25c865765dff97913af00bf89c8c3a4b65d43
diff --git a/bmc_dump_entry.hpp b/bmc_dump_entry.hpp
index b9549f2..31670be 100644
--- a/bmc_dump_entry.hpp
+++ b/bmc_dump_entry.hpp
@@ -49,14 +49,16 @@
      *             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.
      */
     Entry(sdbusplus::bus::bus& bus, const std::string& objPath, uint32_t dumpId,
           uint64_t timeStamp, uint64_t fileSize, const fs::path& file,
+          phosphor::dump::OperationStatus status,
           phosphor::dump::Manager& parent) :
         EntryIfaces(bus, objPath.c_str(), true),
         phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, fileSize,
-                              parent),
+                              status, parent),
         file(file){};
 
     /** @brief Delete this d-bus object.
@@ -79,7 +81,12 @@
     {
         elapsed(timeStamp);
         size(fileSize);
+        // TODO: Handled dump failed case with #ibm-openbmc/2808
+        status(OperationStatus::Completed);
         file = filePath;
+        // TODO: serialization of this property will be handled with
+        // #ibm-openbmc/2597
+        completedTime(timeStamp);
     }
 
   private:
diff --git a/dump-extensions/openpower-dumps/dump_manager_system.cpp b/dump-extensions/openpower-dumps/dump_manager_system.cpp
index 891326b..3f9d973 100644
--- a/dump-extensions/openpower-dumps/dump_manager_system.cpp
+++ b/dump-extensions/openpower-dumps/dump_manager_system.cpp
@@ -28,9 +28,7 @@
         return;
     }
     // Get the timestamp
-    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
-                  std::chrono::system_clock::now().time_since_epoch())
-                  .count();
+    std::time_t timeStamp = std::time(nullptr);
 
     // System dump can get created due to a fault in server
     // or by request from user. A system dump by fault is
@@ -44,7 +42,7 @@
             dynamic_cast<phosphor::dump::system::Entry*>(entry.second.get());
         if (sysEntry->sourceDumpId() == INVALID_SOURCE_ID)
         {
-            sysEntry->update(ms, size, dumpId);
+            sysEntry->update(timeStamp, size, dumpId);
             return;
         }
     }
@@ -57,15 +55,16 @@
     try
     {
         entries.insert(std::make_pair(
-            id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, ms,
-                                                size, dumpId, *this)));
+            id, std::make_unique<system::Entry>(
+                    bus, objPath.c_str(), id, timeStamp, size, dumpId,
+                    phosphor::dump::OperationStatus::Completed, *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("ID=%d", id), entry("TIMESTAMP=%ull", timeStamp),
                         entry("SIZE=%d", size), entry("SOURCEID=%d", dumpId));
         report<InternalFailure>();
         return;
@@ -90,12 +89,14 @@
     auto id = lastEntryId + 1;
     auto idString = std::to_string(id);
     auto objPath = fs::path(baseEntryPath) / idString;
+    std::time_t timeStamp = std::time(nullptr);
 
     try
     {
         entries.insert(std::make_pair(
-            id, std::make_unique<system::Entry>(bus, objPath.c_str(), id, 0, 0,
-                                                INVALID_SOURCE_ID, *this)));
+            id, std::make_unique<system::Entry>(
+                    bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
+                    phosphor::dump::OperationStatus::InProgress, *this)));
     }
     catch (const std::invalid_argument& e)
     {
diff --git a/dump-extensions/openpower-dumps/system_dump_entry.hpp b/dump-extensions/openpower-dumps/system_dump_entry.hpp
index 4f7d233..52d857a 100644
--- a/dump-extensions/openpower-dumps/system_dump_entry.hpp
+++ b/dump-extensions/openpower-dumps/system_dump_entry.hpp
@@ -44,15 +44,17 @@
      *  @param[in] timeStamp - Dump creation timestamp
      *             since the epoch.
      *  @param[in] dumpSize - Dump size in bytes.
-     *  @param[in] sourceId - DumpId provided by the source..
+     *  @param[in] sourceId - DumpId provided by the source.
+     *  @param[in] status - status  of the dump.
      *  @param[in] parent - The dump entry's parent.
      */
     Entry(sdbusplus::bus::bus& bus, const std::string& objPath, uint32_t dumpId,
           uint64_t timeStamp, uint64_t dumpSize, const uint32_t sourceId,
+          phosphor::dump::OperationStatus status,
           phosphor::dump::Manager& parent) :
         EntryIfaces(bus, objPath.c_str(), true),
         phosphor::dump::Entry(bus, objPath.c_str(), dumpId, timeStamp, dumpSize,
-                              parent)
+                              status, parent)
     {
         sourceDumpId(sourceId);
     };
@@ -72,6 +74,10 @@
         elapsed(timeStamp);
         size(dumpSize);
         sourceDumpId(sourceId);
+        // TODO: Handled dump failure case with
+        // #bm-openbmc/2808
+        status(OperationStatus::Completed);
+        completedTime(timeStamp);
     }
 };
 
diff --git a/dump_entry.hpp b/dump_entry.hpp
index b36f880..d493cb1 100644
--- a/dump_entry.hpp
+++ b/dump_entry.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "xyz/openbmc_project/Common/Progress/server.hpp"
 #include "xyz/openbmc_project/Dump/Entry/server.hpp"
 #include "xyz/openbmc_project/Object/Delete/server.hpp"
 #include "xyz/openbmc_project/Time/EpochTime/server.hpp"
@@ -16,11 +17,18 @@
 template <typename T>
 using ServerObject = typename sdbusplus::server::object::object<T>;
 
+// TODO Revisit whether sdbusplus::xyz::openbmc_project::Time::server::EpochTime
+// still needed in dump entry since start time and completed time are available
+// from sdbusplus::xyz::openbmc_project::Common::server::Progress
+// #ibm-openbmc/2809
 using EntryIfaces = sdbusplus::server::object::object<
+    sdbusplus::xyz::openbmc_project::Common::server::Progress,
     sdbusplus::xyz::openbmc_project::Dump::server::Entry,
     sdbusplus::xyz::openbmc_project::Object::server::Delete,
     sdbusplus::xyz::openbmc_project::Time::server::EpochTime>;
 
+using OperationStatus =
+    sdbusplus::xyz::openbmc_project::Common::server::Progress::OperationStatus;
 namespace fs = std::experimental::filesystem;
 
 class Manager;
@@ -50,12 +58,31 @@
      *  @param[in] parent - The dump entry's parent.
      */
     Entry(sdbusplus::bus::bus& bus, const std::string& objPath, uint32_t dumpId,
-          uint64_t timeStamp, uint64_t dumpSize, Manager& parent) :
+          uint64_t timeStamp, uint64_t dumpSize, OperationStatus dumpStatus,
+          Manager& parent) :
         EntryIfaces(bus, objPath.c_str(), true),
         parent(parent), id(dumpId)
     {
         size(dumpSize);
-        elapsed(timeStamp);
+        status(dumpStatus);
+
+        // If the object is created after the dump creation keep
+        // all same as timeStamp
+        // if the object created before the dump creation, update
+        // only the start time. Completed and elapsed time will
+        // be updated once the dump is completed.
+        if (dumpStatus == OperationStatus::Completed)
+        {
+            elapsed(timeStamp);
+            startTime(timeStamp);
+            completedTime(timeStamp);
+        }
+        else
+        {
+            elapsed(0);
+            startTime(timeStamp);
+            completedTime(0);
+        }
         // Emit deferred signal.
         this->emit_object_added();
     };
diff --git a/dump_manager_bmc.cpp b/dump_manager_bmc.cpp
index acd14a2..0236e46 100644
--- a/dump_manager_bmc.cpp
+++ b/dump_manager_bmc.cpp
@@ -10,6 +10,7 @@
 #include <sys/inotify.h>
 #include <unistd.h>
 
+#include <ctime>
 #include <phosphor-logging/elog-errors.hpp>
 #include <phosphor-logging/elog.hpp>
 #include <regex>
@@ -44,9 +45,11 @@
 
     try
     {
+        std::time_t timeStamp = std::time(nullptr);
         entries.insert(std::make_pair(
-            id, std::make_unique<bmc::Entry>(bus, objPath.c_str(), id, 0, 0,
-                                             std::string(), *this)));
+            id, std::make_unique<bmc::Entry>(
+                    bus, objPath.c_str(), id, timeStamp, 0, std::string(),
+                    phosphor::dump::OperationStatus::InProgress, *this)));
     }
     catch (const std::invalid_argument& e)
     {
@@ -146,10 +149,11 @@
 
     try
     {
-        entries.insert(
-            std::make_pair(id, std::make_unique<bmc::Entry>(
-                                   bus, objPath.c_str(), id, stoull(msString),
-                                   fs::file_size(file), file, *this)));
+        entries.insert(std::make_pair(
+            id,
+            std::make_unique<bmc::Entry>(
+                bus, objPath.c_str(), id, stoull(msString), fs::file_size(file),
+                file, phosphor::dump::OperationStatus::Completed, *this)));
     }
     catch (const std::invalid_argument& e)
     {