summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2017-08-08 07:19:34 -0500
committerDeepak Kodihalli <dkodihal@in.ibm.com>2017-08-23 22:35:28 -0500
commitb28990f35e1b9d932a1df83b1606f411ba70c637 (patch)
tree4f133a7b2a7463ab519f6754733048eae81d73c4
parent6620e98de4b81e5eadb96cb739b76c8c030418c8 (diff)
downloadphosphor-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.cpp5
-rw-r--r--manager.cpp69
-rw-r--r--manager.hpp21
-rw-r--r--serialize.hpp21
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
OpenPOWER on IntegriCloud