summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayanth Othayoth <ojayanth@in.ibm.com>2017-09-04 22:07:06 -0500
committerJayanth Othayoth <ojayanth@in.ibm.com>2017-09-14 06:39:09 +0000
commit2496482acd4df532ebb2850679d2b55680c2ec9f (patch)
treebbe3e54471370d2e5124aa134cfe13b59823032d
parentd0f0064eb989a93e241c599641654f12141ef636 (diff)
downloadphosphor-debug-collector-2496482acd4df532ebb2850679d2b55680c2ec9f.tar.gz
phosphor-debug-collector-2496482acd4df532ebb2850679d2b55680c2ec9f.zip
Enable support to handle InternalFailure type dump, during elog restore
Resolves openbmc/openbmc#2078 Change-Id: Iea47b9b7c0cd6cae21642057b21c4e99d85be1e8 Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
-rwxr-xr-xMakefile.am6
-rw-r--r--configure.ac6
-rw-r--r--dump_serialize.cpp35
-rw-r--r--dump_serialize.hpp34
-rw-r--r--elog_watch.cpp68
-rw-r--r--elog_watch.hpp63
6 files changed, 190 insertions, 22 deletions
diff --git a/Makefile.am b/Makefile.am
index f2bec7c..30f0331 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,8 @@ noinst_HEADERS = \
dump_manager.hpp \
dump_utils.hpp \
watch.hpp \
- elog_watch.hpp
+ elog_watch.hpp \
+ dump_serialize.hpp
nobase_nodist_include_HEADERS = \
xyz/openbmc_project/Dump/Internal/Create/server.hpp
@@ -23,7 +24,8 @@ phosphor_dump_manager_SOURCES = \
dump_manager.cpp \
watch.cpp \
xyz/openbmc_project/Dump/Internal/Create/server.cpp \
- elog_watch.cpp
+ elog_watch.cpp \
+ dump_serialize.cpp
phosphor_dump_monitor_SOURCES = \
watch.cpp \
diff --git a/configure.ac b/configure.ac
index 00a76bf..fa69297 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,5 +77,11 @@ AC_DEFINE_UNQUOTED([BMC_DUMP_TOTAL_SIZE], [$BMC_DUMP_TOTAL_SIZE], [Total size of
AC_DEFINE(OBJ_LOGGING, "/xyz/openbmc_project/logging", [The log manager DBus object path.])
+AC_ARG_VAR(ELOG_ID_PERSIST_PATH, [Path of file for storing elog id's, which have associated dumps])
+AS_IF([test "x$ELOG_ID_PERSIST_PATH" == "x"], \
+ [ELOG_ID_PERSIST_PATH="/var/lib/phosphor-debug-collector/elogid"])
+AC_DEFINE_UNQUOTED([ELOG_ID_PERSIST_PATH], ["$ELOG_ID_PERSIST_PATH"], \
+ [Path of file for storing elog id's, which have associated dumps])
+
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/dump_serialize.cpp b/dump_serialize.cpp
new file mode 100644
index 0000000..26990a0
--- /dev/null
+++ b/dump_serialize.cpp
@@ -0,0 +1,35 @@
+#include <cereal/types/set.hpp>
+#include <cereal/archives/binary.hpp>
+#include <fstream>
+
+#include "dump_serialize.hpp"
+
+namespace phosphor
+{
+namespace dump
+{
+namespace elog
+{
+
+void serialize(const ElogList& list, const fs::path& dir)
+{
+ std::ofstream os(dir.c_str(), std::ios::binary);
+ cereal::BinaryOutputArchive oarchive(os);
+ oarchive(list);
+}
+
+bool deserialize(const fs::path& path, ElogList& list)
+{
+ if (fs::exists(path))
+ {
+ std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
+ cereal::BinaryInputArchive iarchive(is);
+ iarchive(list);
+ return true;
+ }
+ return false;
+}
+
+} // namespace elog
+} // namespace dump
+} // namespace phosphor
diff --git a/dump_serialize.hpp b/dump_serialize.hpp
new file mode 100644
index 0000000..ecfc934
--- /dev/null
+++ b/dump_serialize.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <experimental/filesystem>
+
+#include "elog_watch.hpp"
+#include "config.h"
+
+namespace phosphor
+{
+namespace dump
+{
+namespace elog
+{
+
+namespace fs = std::experimental::filesystem;
+
+/** @brief Serialize and persist list of ids.
+ * @param[in] list - elog id list.
+ * @param[in] dir - pathname of file where the serialized elog id's will
+ * be placed.
+ */
+void serialize(const ElogList& list,
+ const fs::path& dir = fs::path(ELOG_ID_PERSIST_PATH));
+
+/** @brief Deserialze a persisted list of ids into list
+ * @param[in] path - pathname of persisted error file
+ * @param[out] list - elog id list
+ * @return bool - true if the deserialization was successful, false otherwise.
+ */
+bool deserialize(const fs::path& path, ElogList& list);
+
+} // namespace elog
+} // namespace dump
+} // namespace phosphor
diff --git a/elog_watch.cpp b/elog_watch.cpp
index 6c7ff93..5ab65df 100644
--- a/elog_watch.cpp
+++ b/elog_watch.cpp
@@ -3,6 +3,7 @@
#include "elog_watch.hpp"
#include "dump_internal.hpp"
#include "xyz/openbmc_project/Dump/Create/error.hpp"
+#include "dump_serialize.hpp"
namespace phosphor
{
@@ -23,7 +24,35 @@ using PropertyName = std::string;
using PropertyMap = std::map<PropertyName, AttributeMap>;
using LogEntryMsg = std::pair<sdbusplus::message::object_path, PropertyMap>;
-void Watch::callback(sdbusplus::message::message& msg)
+Watch::Watch(sdbusplus::bus::bus& bus, IMgr& iMgr):
+ iMgr(iMgr),
+ addMatch(
+ bus,
+ sdbusplus::bus::match::rules::interfacesAdded() +
+ sdbusplus::bus::match::rules::path_namespace(
+ OBJ_LOGGING),
+ std::bind(std::mem_fn(&Watch::addCallback),
+ this, std::placeholders::_1)),
+ delMatch(
+ bus,
+ sdbusplus::bus::match::rules::interfacesRemoved() +
+ sdbusplus::bus::match::rules::path_namespace(
+ OBJ_LOGGING),
+ std::bind(std::mem_fn(&Watch::delCallback),
+ this, std::placeholders::_1))
+{
+
+ fs::path file(ELOG_ID_PERSIST_PATH);
+ if (fs::exists(file))
+ {
+ if (!deserialize(ELOG_ID_PERSIST_PATH, elogList))
+ {
+ log<level::ERR>("Error occurred during error id deserialize");
+ }
+ }
+}
+
+void Watch::addCallback(sdbusplus::message::message& msg)
{
using Type =
sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
@@ -42,6 +71,15 @@ void Watch::callback(sdbusplus::message::message& msg)
return;
}
+ auto eId = getEid(objectPath);
+
+ auto search = elogList.find(eId);
+ if (search != elogList.end())
+ {
+ //elog exists in the list, Skip the dump
+ return;
+ }
+
auto iter = logEntry.second.find("xyz.openbmc_project.Logging.Entry");
if (iter == logEntry.second.end())
{
@@ -62,7 +100,7 @@ void Watch::callback(sdbusplus::message::message& msg)
return;
}
- if (INTERNAL_FAILURE != data)
+ if (data != INTERNAL_FAILURE)
{
//Not a InternalFailure, skip
return;
@@ -73,6 +111,12 @@ void Watch::callback(sdbusplus::message::message& msg)
try
{
+ //Save the elog information. This is to avoid dump requests
+ //in elog restore path.
+ elogList.insert(eId);
+
+ phosphor::dump::elog::serialize(elogList);
+
//Call internal create function to initiate dump
iMgr.IMgr::create(Type::InternalFailure, fullPaths);
}
@@ -83,6 +127,26 @@ void Watch::callback(sdbusplus::message::message& msg)
return;
}
+void Watch::delCallback(sdbusplus::message::message& msg)
+{
+ sdbusplus::message::object_path logEntry;
+ msg.read(logEntry);
+
+ //Get elog entry message string.
+ std::string objectPath(logEntry);
+
+ //Get elog id
+ auto eId = getEid(objectPath);
+
+ //Delete the elog entry from the list and serialize
+ auto search = elogList.find(eId);
+ if (search != elogList.end())
+ {
+ elogList.erase(search);
+ phosphor::dump::elog::serialize(elogList);
+ }
+}
+
}//namespace elog
}//namespace dump
}//namespace phosphor
diff --git a/elog_watch.hpp b/elog_watch.hpp
index cfdf41a..588ac34 100644
--- a/elog_watch.hpp
+++ b/elog_watch.hpp
@@ -1,9 +1,12 @@
#pragma once
+#include <set>
+#include <cereal/access.hpp>
+
#include <sdbusplus/bus.hpp>
#include <sdbusplus/server.hpp>
-#include "config.h"
+#include "config.h"
#include "dump_manager.hpp"
namespace phosphor
@@ -14,9 +17,11 @@ namespace elog
{
using IMgr = phosphor::dump::internal::Manager;
+using EId = uint32_t;
+using ElogList = std::set<EId>;
/** @class Watch
- * @brief Adds d-bus signal based watch for elog commit.
+ * @brief Adds d-bus signal based watch for elog add and delete.
* @details This implements methods for watching for InternalFailure
* type error message and call appropriate function to initiate dump
*/
@@ -30,36 +35,58 @@ class Watch
Watch(Watch&&) = default;
Watch& operator=(Watch&&) = default;
- /** @brief constructs watch for elog commits.
+ /** @brief constructs watch for elog add and delete signals.
* @param[in] bus - The Dbus bus object
* @param[in] intMgr - Dump internal Manager object
*/
- Watch(sdbusplus::bus::bus& bus, IMgr& iMgr):
- iMgr(iMgr),
- elogMatch(
- bus,
- sdbusplus::bus::match::rules::interfacesAdded() +
- sdbusplus::bus::match::rules::path_namespace(
- OBJ_LOGGING),
- std::bind(std::mem_fn(&Watch::callback),
- this, std::placeholders::_1))
+ Watch(sdbusplus::bus::bus& bus, IMgr& iMgr);
+ private:
+
+ friend class cereal::access;
+
+ /** @brief Function required by Cereal to perform serialization.
+ * @tparam Archive - Cereal archive type (binary in our case).
+ * @param[in] a - reference to Cereal archive.
+ */
+ template<class Archive>
+ void serialize(Archive& a)
{
- //Do nothing
+ a(elogList);
}
- private:
- /** @brief Callback function for error log commit.
+ /** @brief Callback function for error log add.
* @details InternalError type error message initiates
* Internal error type dump request.
* @param[in] msg - Data associated with subscribed signal
*/
- void callback(sdbusplus::message::message& msg);
+ void addCallback(sdbusplus::message::message& msg);
+
+ /** @brief Callback function for error log delete.
+ * @param[in] msg - Data associated with subscribed signal
+ */
+ void delCallback(sdbusplus::message::message& msg);
+
+ /** @brief get elog ID from elog entry object string.
+ * @param[in] objectPath - elog entry object path.
+ * @return - elog id.
+ */
+ inline EId getEid(const std::string& objectPath)
+ {
+ fs::path path(objectPath);
+ return std::stoul(path.filename());
+ }
/** @brief Dump internal Manager object. */
IMgr& iMgr;
- /** @brief sdbusplus signal match for elog commit */
- sdbusplus::bus::match_t elogMatch;
+ /** @brief sdbusplus signal match for elog add */
+ sdbusplus::bus::match_t addMatch;
+
+ /** @brief sdbusplus signal match for elog delete */
+ sdbusplus::bus::match_t delMatch;
+
+ /** @brief List of elog ids, which have associated dumps created */
+ ElogList elogList;
};
}//namespace elog
OpenPOWER on IntegriCloud