Fix settingsd core dump/persistence fail

The problem was seen only with network settings objects, because they
had paths as following:

A setting d-bus object /foo/bar/baz is persisted in the filesystem with
the same path. This eases re-construction of settings objects when we
restore from the filesystem. This can be a problem though when you have
two objects such as - /foo/bar and /foo/bar/baz. This is because 'bar'
will be treated a file in the first case, and a subdir in the second.
This was causing an exception to be thrown by Cereal, because it found a
dir where it was expecting a file. This also caused us to not persist
certain network setting objects because we couldn't create subdirs
as there were files of the same name.

To solve this, suffix files with a trailing __. The __ is a safe
character sequence to use, because we won't have d-bus object paths
ending with this. With this the objects would be persisted as -
/foo/bar__ and /foo/bar/baz__.

Change-Id: I76b6a0423db1f2f51bd1b6ab2ea5f9cafd1a36d9
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/settings_manager.mako.hpp b/settings_manager.mako.hpp
index 9fca3da..b1c3988 100644
--- a/settings_manager.mako.hpp
+++ b/settings_manager.mako.hpp
@@ -62,6 +62,21 @@
 
 namespace fs = std::experimental::filesystem;
 
+namespace persistent
+{
+
+// A setting d-bus object /foo/bar/baz is persisted in the filesystem with the
+// same path. This eases re-construction of settings objects when we restore
+// from the filesystem. This can be a problem though when you have two objects
+// such as - /foo/bar and /foo/bar/baz. This is because 'bar' will be treated as
+// a file in the first case, and a subdir in the second. To solve this, suffix
+// files with a trailing __. The __ is a safe character sequence to use, because
+// we won't have d-bus object paths ending with this.
+// With this the objects would be persisted as - /foo/bar__ and /foo/bar/baz__.
+constexpr auto fileSuffix = "__";
+
+}
+
 % for n in set(sdbusplus_namespaces):
 using namespace ${n};
 % endfor
@@ -132,6 +147,7 @@
              % endif
                 fs::path p(SETTINGS_PERSIST_PATH);
                 p /= path;
+                p += persistent::fileSuffix;
                 fs::create_directories(p.parent_path());
                 std::ofstream os(p.c_str(), std::ios::binary);
                 cereal::JSONOutputArchive oarchive(os);
@@ -259,6 +275,7 @@
 <% p = property[:1].lower() + property[1:] %>\
 <% defaultValue = value['Default'] %>\
             path = fs::path(SETTINGS_PERSIST_PATH) / "${object}";
+            path += persistent::fileSuffix;
             if (fs::exists(path))
             {
                 std::ifstream is(path.c_str(), std::ios::in);