summaryrefslogtreecommitdiffstats
path: root/settings_manager.mako.hpp
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2017-06-23 23:05:47 -0500
committerDeepak Kodihalli <dkodihal@in.ibm.com>2017-07-03 09:33:52 -0500
commit7a6f2526fd46badb145baa4309f88036af1bee9c (patch)
tree48a5a3a94dfeb040aefdd0396beeb177da978b00 /settings_manager.mako.hpp
parent9711211cb53df56fb5bdf84e3882672ac7ec8a50 (diff)
downloadphosphor-settingsd-7a6f2526fd46badb145baa4309f88036af1bee9c.tar.gz
phosphor-settingsd-7a6f2526fd46badb145baa4309f88036af1bee9c.zip
Persist changes to settings
Persist changes made to settings, if any, such that those changes can be restored upon a reboot. Use Cereal for serialization of the settings' properties. Since the settings code is generated based on a system specific settings policy, generate the serialization code as well such that only relevant settings are serialized. Resolves openbmc/openbmc#1764. Change-Id: Id8bd84a9455cf4348b22f255d038b050d004eb7c Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
Diffstat (limited to 'settings_manager.mako.hpp')
-rw-r--r--settings_manager.mako.hpp156
1 files changed, 136 insertions, 20 deletions
diff --git a/settings_manager.mako.hpp b/settings_manager.mako.hpp
index acdf66d..6a4f1bf 100644
--- a/settings_manager.mako.hpp
+++ b/settings_manager.mako.hpp
@@ -1,17 +1,23 @@
## This file is a template. The comment below is emitted
## into the rendered file; feel free to edit this file.
// WARNING: Generated header. Do not edit!
-
<%
+from collections import defaultdict
objects = list(settingsDict.viewkeys())
-ns_list = []
-includes = []
+sdbusplus_namespaces = []
+sdbusplus_includes = []
+interfaces = []
+props = defaultdict(list)
-def get_setting_type(setting_intf):
+def get_setting_sdbusplus_type(setting_intf):
setting = "sdbusplus::" + setting_intf.replace('.', '::')
i = setting.rfind('::')
setting = setting[:i] + '::server::' + setting[i+2:]
return setting
+
+def get_setting_type(setting_intf):
+ setting = setting_intf.replace('.', '::')
+ return setting
%>\
#pragma once
@@ -20,30 +26,130 @@ def get_setting_type(setting_intf):
include = settingsDict[object]['Interface']
include = include.replace('.', '/')
include = include + "/server.hpp"
- includes.append(include)
+ sdbusplus_includes.append(include)
%>\
% endfor
-% for i in set(includes):
+#include <cereal/archives/json.hpp>
+#include <fstream>
+#include <utility>
+#include <experimental/filesystem>
+#include "config.h"
+
+% for i in set(sdbusplus_includes):
#include "${i}"
% endfor
% for object in objects:
<%
- ns = get_setting_type(settingsDict[object]['Interface'])
+ ns = get_setting_sdbusplus_type(settingsDict[object]['Interface'])
i = ns.rfind('::')
ns = ns[:i]
- ns_list.append(ns)
+ sdbusplus_namespaces.append(ns)
%>\
% endfor
-% for n in set(ns_list):
-using namespace ${n};
-% endfor
namespace phosphor
{
namespace settings
{
+namespace fs = std::experimental::filesystem;
+
+% for n in set(sdbusplus_namespaces):
+using namespace ${n};
+% endfor
+
+% for object in objects:
+<%
+ intf = settingsDict[object]['Interface']
+ interfaces.append(intf)
+ if intf not in props:
+ for property, value in settingsDict[object]['Defaults'].items():
+ props[intf].append(property)
+%>\
+% endfor
+% for intf in set(interfaces):
+<%
+ ns = intf.split(".")
+ sdbusplus_type = get_setting_sdbusplus_type(intf)
+%>\
+% for n in ns:
+namespace ${n}
+{
+% endfor
+
+using Base = ${sdbusplus_type};
+<% parent = "sdbusplus::server::object::object" + "<" + sdbusplus_type + ">" %>\
+using Parent = ${parent};
+
+class Impl : public Parent
+{
+ public:
+ Impl(sdbusplus::bus::bus& bus, const char* path):
+ Parent(bus, path, true),
+ path(path)
+ {
+ }
+ virtual ~Impl() = default;
+
+% for arg in props[intf]:
+<% t = arg[:1].lower() + arg[1:] %>\
+ decltype(std::declval<Base>().${t}()) ${t}(decltype(std::declval<Base>().${t}()) value) override
+ {
+ auto result = Base::${t}();
+ if (value != result)
+ {
+ fs::path p(SETTINGS_PERSIST_PATH);
+ p /= path;
+ fs::create_directories(p.parent_path());
+ std::ofstream os(p.c_str(), std::ios::binary);
+ cereal::JSONOutputArchive oarchive(os);
+ result = Base::${t}(value);
+ oarchive(*this);
+ }
+ return result;
+ }
+ using Base::${t};
+
+ private:
+ fs::path path;
+% endfor
+};
+
+template<class Archive>
+void save(Archive& a,
+ const Impl& setting)
+{
+<%
+ args = ["setting." + p[:1].lower() + p[1:] + "()" for p in props[intf]]
+ args = ','.join(args)
+%>\
+ a(${args});
+}
+
+template<class Archive>
+void load(Archive& a,
+ Impl& setting)
+{
+% for arg in props[intf]:
+<% t = "setting." + arg[:1].lower() + arg[1:] + "()" %>\
+ decltype(${t}) ${arg}{};
+% endfor
+<%
+ args = ','.join(props[intf])
+%>\
+ a(${args});
+% for arg in props[intf]:
+<% t = "setting." + arg[:1].lower() + arg[1:] + "(" + arg + ")" %>\
+ ${t};
+% endfor
+}
+
+% for n in reversed(ns):
+} // namespace ${n}
+% endfor
+% endfor
+
/** @class Manager
*
* @brief Compose settings objects and put them on the bus.
@@ -63,10 +169,11 @@ class Manager
*/
Manager(sdbusplus::bus::bus& bus)
{
+ fs::path path{};
settings =
std::make_tuple(
% for index, object in enumerate(objects):
-<% type = get_setting_type(settingsDict[object]['Interface']) %>\
+<% type = get_setting_type(settingsDict[object]['Interface']) + "::Impl" %>\
std::make_unique<${type}>(
bus,
% if index < len(settingsDict) - 1:
@@ -77,13 +184,22 @@ class Manager
% endfor
% for index, object in enumerate(objects):
- % if 'Defaults' in settingsDict[object].viewkeys():
- % for property, value in settingsDict[object]['Defaults'].items():
- std::get<${index}>(settings)->
- setPropertyByName("${property}", ${value});
- % endfor
- % endif
- bus.emit_object_added("${object}");
+ % for property, value in settingsDict[object]['Defaults'].items():
+<% p = property[:1].lower() + property[1:] %>\
+ path = fs::path(SETTINGS_PERSIST_PATH) / "${object}";
+ if (fs::exists(path))
+ {
+ std::ifstream is(path.c_str(), std::ios::in);
+ cereal::JSONInputArchive iarchive(is);
+ iarchive(*std::get<${index}>(settings));
+ }
+ else
+ {
+ std::get<${index}>(settings)->
+ ${get_setting_sdbusplus_type(settingsDict[object]['Interface'])}::${p}(${value});
+ }
+ % endfor
+ std::get<${index}>(settings)->emit_object_added();
% endfor
}
@@ -92,7 +208,7 @@ class Manager
/* @brief Composition of settings objects. */
std::tuple<
% for index, object in enumerate(objects):
-<% type = get_setting_type(settingsDict[object]['Interface']) %>\
+<% type = get_setting_type(settingsDict[object]['Interface']) + "::Impl" %>\
% if index < len(settingsDict) - 1:
std::unique_ptr<${type}>,
% else:
OpenPOWER on IntegriCloud