diff options
author | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-08-08 07:19:34 -0500 |
---|---|---|
committer | Deepak Kodihalli <dkodihal@in.ibm.com> | 2017-08-23 22:35:28 -0500 |
commit | b28990f35e1b9d932a1df83b1606f411ba70c637 (patch) | |
tree | 4f133a7b2a7463ab519f6754733048eae81d73c4 | |
parent | 6620e98de4b81e5eadb96cb739b76c8c030418c8 (diff) | |
download | phosphor-inventory-manager-b28990f35e1b9d932a1df83b1606f411ba70c637.tar.gz phosphor-inventory-manager-b28990f35e1b9d932a1df83b1606f411ba70c637.zip |
inventory: implement deserialization
Use Cereal to deserialize inventory information persisted in the
filesystem and restore that to create inventory d-bus objects. Perform
the restore when the app starts.
Change-Id: I0f36a9cbdde223e4bfd9e178e33f5677217ba881
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
-rw-r--r-- | generated.mako.cpp | 5 | ||||
-rw-r--r-- | manager.cpp | 69 | ||||
-rw-r--r-- | manager.hpp | 21 | ||||
-rw-r--r-- | serialize.hpp | 21 |
4 files changed, 107 insertions, 9 deletions
diff --git a/generated.mako.cpp b/generated.mako.cpp index 7eeb8c4..6fc1521 100644 --- a/generated.mako.cpp +++ b/generated.mako.cpp @@ -31,7 +31,10 @@ const Manager::Makers Manager::_makers{ ${i.namespace()}>>::assign, MakeInterface< ServerObject< - ${i.namespace()}>>::serialize + ${i.namespace()}>>::serialize, + MakeInterface< + ServerObject< + ${i.namespace()}>>::deserialize ) }, % endfor diff --git a/manager.cpp b/manager.cpp index 86b1757..6049161 100644 --- a/manager.cpp +++ b/manager.cpp @@ -18,6 +18,7 @@ #include <chrono> #include <algorithm> #include <phosphor-logging/log.hpp> +#include <experimental/filesystem> #include "manager.hpp" #include "errors.hpp" @@ -103,6 +104,9 @@ Manager::Manager( } _bus.request_name(busname); + + // Restore any persistent inventory + restore(); } void Manager::shutdown() noexcept @@ -146,7 +150,8 @@ void Manager::updateInterfaces( const sdbusplus::message::object_path& path, const Object& interfaces, ObjectReferences::iterator pos, - bool newObject) + bool newObject, + bool restoreFromCache) { auto& refaces = pos->second; auto ifaceit = interfaces.cbegin(); @@ -200,8 +205,16 @@ void Manager::updateInterfaces( auto& assign = std::get<AssignerType>(opsit->second); assign(ifaceit->second, refaceit->second); } - auto& serialize = std::get<SerializerType>(opsit->second); - serialize(path, ifaceit->first, refaceit->second); + if (!restoreFromCache) + { + auto& serialize = std::get<SerializerType>(opsit->second); + serialize(path, ifaceit->first, refaceit->second); + } + else + { + auto& deserialize = std::get<DeserializerType>(opsit->second); + deserialize(path, ifaceit->first, refaceit->second); + } } catch (const InterfaceError& e) { @@ -225,7 +238,8 @@ void Manager::updateInterfaces( } void Manager::updateObjects( - const std::map<sdbusplus::message::object_path, Object>& objs) + const std::map<sdbusplus::message::object_path, Object>& objs, + bool restoreFromCache) { auto objit = objs.cbegin(); auto refit = _refs.begin(); @@ -255,7 +269,8 @@ void Manager::updateObjects( newObj = true; } - updateInterfaces(absPath, objit->second, refit, newObj); + updateInterfaces(absPath, objit->second, refit, newObj, + restoreFromCache); ++objit; } } @@ -331,6 +346,50 @@ const any_ns::any& Manager::getInterfaceHolder( return iit->second; } +void Manager::restore() +{ + namespace fs = std::experimental::filesystem; + + if (!fs::exists(fs::path(PIM_PERSIST_PATH))) + { + return; + } + + static const std::string remove = + std::string(PIM_PERSIST_PATH) + INVENTORY_ROOT; + + std::map<sdbusplus::message::object_path, Object> objects; + for (const auto& dirent : + fs::recursive_directory_iterator(PIM_PERSIST_PATH)) + { + const auto& path = dirent.path(); + if (fs::is_regular_file(path)) + { + auto ifaceName = path.filename().string(); + auto objPath = path.parent_path().string(); + objPath.erase(0, remove.length()); + auto objit = objects.find(objPath); + Interface propertyMap{}; + if (objects.end() != objit) + { + auto& object = objit->second; + object.emplace(std::move(ifaceName), std::move(propertyMap)); + } + else + { + Object object; + object.emplace(std::move(ifaceName), std::move(propertyMap)); + objects.emplace(std::move(objPath), std::move(object)); + } + } + } + if (!objects.empty()) + { + auto restoreFromCache = true; + updateObjects(objects, restoreFromCache); + } +} + } // namespace manager } // namespace inventory } // namespace phosphor diff --git a/manager.hpp b/manager.hpp index a94d5ea..e6c60a3 100644 --- a/manager.hpp +++ b/manager.hpp @@ -94,6 +94,13 @@ struct MakeInterface *any_ns::any_cast<const std::shared_ptr<T> &>(holder); cereal::serialize(path, iface, object); } + + static void deserialize(const std::string& path, const std::string& iface, + any_ns::any& holder) + { + auto& object = *any_ns::any_cast<std::shared_ptr<T> &>(holder); + cereal::deserialize(path, iface, object); + } }; /** @class Manager @@ -152,7 +159,11 @@ class Manager final : /** @brief Add or update objects on DBus. */ void updateObjects( - const std::map<sdbusplus::message::object_path, Object>& objs); + const std::map<sdbusplus::message::object_path, Object>& objs, + bool restoreFromCache = false); + + /** @brief Restore persistent inventory items */ + void restore(); /** @brief Invoke an sdbusplus server binding method. * @@ -201,8 +212,11 @@ class Manager final : decltype(MakeInterface<int>::assign) >; using SerializerType = std::add_pointer_t < decltype(MakeInterface<int>::serialize) >; + using DeserializerType = std::add_pointer_t < + decltype(MakeInterface<int>::deserialize) >; using Makers = std::map<std::string, - std::tuple<MakerType, AssignerType, SerializerType>>; + std::tuple<MakerType, AssignerType, + SerializerType, DeserializerType>>; /** @brief Provides weak references to interface holders. * @@ -249,7 +263,8 @@ class Manager final : const sdbusplus::message::object_path& path, const Object& interfaces, ObjectReferences::iterator pos, - bool emitSignals = true); + bool emitSignals = true, + bool restoreFromCache = false); /** @brief Provided for testing only. */ volatile bool _shutdown; diff --git a/serialize.hpp b/serialize.hpp index 281f61c..7c30b9c 100644 --- a/serialize.hpp +++ b/serialize.hpp @@ -31,4 +31,25 @@ inline void serialize(const Path& path, const Interface& iface, const T& object) oarchive(object); } +/** @brief Deserialize inventory item + * + * @param[in] path - DBus object path + * @param[in] iface - Inventory interface name + * @param[in] object - Object to be serialized + */ +template <typename T> +inline void deserialize( + const Path& path, const Interface& iface, T& object) +{ + fs::path p(PIM_PERSIST_PATH); + p /= path; + p /= iface; + if (fs::exists(p)) + { + std::ifstream is(p, std::ios::in | std::ios::binary); + cereal::JSONInputArchive iarchive(is); + iarchive(object); + } +} + } // namespace cereal |