diff options
author | Jayanth Othayoth <ojayanth@in.ibm.com> | 2017-09-04 22:07:06 -0500 |
---|---|---|
committer | Jayanth Othayoth <ojayanth@in.ibm.com> | 2017-09-14 06:39:09 +0000 |
commit | 2496482acd4df532ebb2850679d2b55680c2ec9f (patch) | |
tree | bbe3e54471370d2e5124aa134cfe13b59823032d | |
parent | d0f0064eb989a93e241c599641654f12141ef636 (diff) | |
download | phosphor-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-x | Makefile.am | 6 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | dump_serialize.cpp | 35 | ||||
-rw-r--r-- | dump_serialize.hpp | 34 | ||||
-rw-r--r-- | elog_watch.cpp | 68 | ||||
-rw-r--r-- | elog_watch.hpp | 63 |
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 |