user-mgmt: sync ipmi user & channel conf file

ipmi_user.json file is stored in non-volatile memory, and it is
necessary to make sure that file is properly synced to the storage
device, to avoid any corruption issue related to power
loss. This fix makes sure that temporary file is fully synced with
storage device and then renamed, such that the file is either
in old state or in new updated state.
Same is also performed for channel configuration file too.

Tested:
1. Verified regular ipmi user list & channel works without
any issue
2. Verifid that any power loss, immediately, once the file
is written doesn't corrupt the entries.

Change-Id: I9ef84573947ab6f85f66530ac4a20e9eeaddf283
Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index 5ca2884..89ba142 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -1087,15 +1087,6 @@
     boost::interprocess::scoped_lock<boost::interprocess::named_recursive_mutex>
         userLock{*userMutex};
 
-    static std::string tmpFile{std::string(ipmiUserDataFile) + "_tmp"};
-    std::ofstream oUsrData(tmpFile, std::ios::out | std::ios::binary);
-    if (!oUsrData.good())
-    {
-        log<level::ERR>("Error in creating temporary IPMI user data file");
-        throw std::ios_base::failure(
-            "Error in creating temporary IPMI user data file");
-    }
-
     Json jsonUsersTbl = Json::array();
     // user index 0 is reserved, starts with 1
     for (size_t usrIndex = 1; usrIndex <= ipmiMaxUsers; ++usrIndex)
@@ -1130,9 +1121,25 @@
         jsonUsersTbl.push_back(jsonUserInfo);
     }
 
-    oUsrData << jsonUsersTbl;
-    oUsrData.flush();
-    oUsrData.close();
+    static std::string tmpFile{std::string(ipmiUserDataFile) + "_tmp"};
+    int fd = open(tmpFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_SYNC,
+                  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+    if (fd < 0)
+    {
+        log<level::ERR>("Error in creating temporary IPMI user data file");
+        throw std::ios_base::failure(
+            "Error in creating temporary IPMI user data file");
+    }
+    const auto& writeStr = jsonUsersTbl.dump();
+    if (write(fd, writeStr.c_str(), writeStr.size()) !=
+        static_cast<ssize_t>(writeStr.size()))
+    {
+        close(fd);
+        log<level::ERR>("Error in writing temporary IPMI user data file");
+        throw std::ios_base::failure(
+            "Error in writing temporary IPMI user data file");
+    }
+    close(fd);
 
     if (std::rename(tmpFile.c_str(), ipmiUserDataFile) != 0)
     {