Change files to use standard unix file endings

CRLF line endings are non-standard for this project. Change them to use
the standard unix LF ending.

Tested: `git show -w` shows no difference

Change-Id: I353adcd2054c48a040b4e3a09bc46913cb6422fa
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/inc/srvcfg_manager.hpp b/inc/srvcfg_manager.hpp
index ea84c53..d0a3ae1 100644
--- a/inc/srvcfg_manager.hpp
+++ b/inc/srvcfg_manager.hpp
@@ -1,113 +1,113 @@
-/*

-// Copyright (c) 2018 Intel Corporation

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//      http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-*/

-#pragma once

-#include "utils.hpp"

-

-#include <sdbusplus/timer.hpp>

-

-namespace phosphor

-{

-namespace service

-{

-

-static constexpr const char* serviceConfigSrvName =

-    "xyz.openbmc_project.Control.Service.Manager";

-static constexpr const char* serviceConfigIntfName =

-    "xyz.openbmc_project.Control.Service.Attributes";

-static constexpr const char* sockAttrIntfName =

-    "xyz.openbmc_project.Control.Service.SocketAttributes";

-static constexpr const char* srcCfgMgrBasePath =

-    "/xyz/openbmc_project/control/service";

-static constexpr const char* srcCfgMgrIntf =

-    "/xyz/openbmc_project.Control.Service.Manager";

-static constexpr const char* sockAttrPropPort = "Port";

-static constexpr const char* srvCfgPropMasked = "Masked";

-static constexpr const char* srvCfgPropEnabled = "Enabled";

-static constexpr const char* srvCfgPropRunning = "Running";

-

-enum class UpdatedProp

-{

-    port = 1,

-    maskedState,

-    enabledState,

-    runningState

-};

-

-using VariantType =

-    std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,

-                 int16_t, uint16_t, uint8_t, bool,

-                 std::vector<std::tuple<std::string, std::string>>>;

-

-class ServiceConfig

-{

-  public:

-    ServiceConfig(sdbusplus::asio::object_server& srv_,

-                  std::shared_ptr<sdbusplus::asio::connection>& conn_,

-                  const std::string& objPath_, const std::string& baseUnitName,

-                  const std::string& instanceName,

-                  const std::string& serviceObjPath,

-                  const std::string& socketObjPath);

-    ~ServiceConfig() = default;

-

-    std::shared_ptr<sdbusplus::asio::connection> conn;

-    uint8_t updatedFlag;

-

-    void stopAndApplyUnitConfig(boost::asio::yield_context yield);

-    void restartUnitConfig(boost::asio::yield_context yield);

-    void startServiceRestartTimer();

-

-  private:

-    sdbusplus::asio::object_server& server;

-    std::shared_ptr<sdbusplus::asio::dbus_interface> srvCfgIface;

-    std::shared_ptr<sdbusplus::asio::dbus_interface> sockAttrIface;

-

-    bool internalSet = false;

-    std::string objPath;

-    std::string baseUnitName;

-    std::string instanceName;

-    std::string instantiatedUnitName;

-    std::string serviceObjectPath;

-    std::string socketObjectPath;

-    std::string overrideConfDir;

-

-    // Properties

-    std::string activeState;

-    std::string subState;

-    uint16_t portNum;

-    std::vector<std::string> channelList;

-    std::string protocol;

-    std::string stateValue;

-    bool unitMaskedState = false;

-    bool unitEnabledState = false;

-    bool unitRunningState = false;

-    std::string subStateValue;

-

-    bool isMaskedOut();

-    void registerProperties();

-    void queryAndUpdateProperties();

-    void createSocketOverrideConf();

-    void updateServiceProperties(

-        const boost::container::flat_map<std::string, VariantType>&

-            propertyMap);

-    void updateSocketProperties(

-        const boost::container::flat_map<std::string, VariantType>&

-            propertyMap);

-    std::string getSocketUnitName();

-    std::string getServiceUnitName();

-};

-

-} // namespace service

-} // namespace phosphor

+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+#include "utils.hpp"
+
+#include <sdbusplus/timer.hpp>
+
+namespace phosphor
+{
+namespace service
+{
+
+static constexpr const char* serviceConfigSrvName =
+    "xyz.openbmc_project.Control.Service.Manager";
+static constexpr const char* serviceConfigIntfName =
+    "xyz.openbmc_project.Control.Service.Attributes";
+static constexpr const char* sockAttrIntfName =
+    "xyz.openbmc_project.Control.Service.SocketAttributes";
+static constexpr const char* srcCfgMgrBasePath =
+    "/xyz/openbmc_project/control/service";
+static constexpr const char* srcCfgMgrIntf =
+    "/xyz/openbmc_project.Control.Service.Manager";
+static constexpr const char* sockAttrPropPort = "Port";
+static constexpr const char* srvCfgPropMasked = "Masked";
+static constexpr const char* srvCfgPropEnabled = "Enabled";
+static constexpr const char* srvCfgPropRunning = "Running";
+
+enum class UpdatedProp
+{
+    port = 1,
+    maskedState,
+    enabledState,
+    runningState
+};
+
+using VariantType =
+    std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
+                 int16_t, uint16_t, uint8_t, bool,
+                 std::vector<std::tuple<std::string, std::string>>>;
+
+class ServiceConfig
+{
+  public:
+    ServiceConfig(sdbusplus::asio::object_server& srv_,
+                  std::shared_ptr<sdbusplus::asio::connection>& conn_,
+                  const std::string& objPath_, const std::string& baseUnitName,
+                  const std::string& instanceName,
+                  const std::string& serviceObjPath,
+                  const std::string& socketObjPath);
+    ~ServiceConfig() = default;
+
+    std::shared_ptr<sdbusplus::asio::connection> conn;
+    uint8_t updatedFlag;
+
+    void stopAndApplyUnitConfig(boost::asio::yield_context yield);
+    void restartUnitConfig(boost::asio::yield_context yield);
+    void startServiceRestartTimer();
+
+  private:
+    sdbusplus::asio::object_server& server;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> srvCfgIface;
+    std::shared_ptr<sdbusplus::asio::dbus_interface> sockAttrIface;
+
+    bool internalSet = false;
+    std::string objPath;
+    std::string baseUnitName;
+    std::string instanceName;
+    std::string instantiatedUnitName;
+    std::string serviceObjectPath;
+    std::string socketObjectPath;
+    std::string overrideConfDir;
+
+    // Properties
+    std::string activeState;
+    std::string subState;
+    uint16_t portNum;
+    std::vector<std::string> channelList;
+    std::string protocol;
+    std::string stateValue;
+    bool unitMaskedState = false;
+    bool unitEnabledState = false;
+    bool unitRunningState = false;
+    std::string subStateValue;
+
+    bool isMaskedOut();
+    void registerProperties();
+    void queryAndUpdateProperties();
+    void createSocketOverrideConf();
+    void updateServiceProperties(
+        const boost::container::flat_map<std::string, VariantType>&
+            propertyMap);
+    void updateSocketProperties(
+        const boost::container::flat_map<std::string, VariantType>&
+            propertyMap);
+    std::string getSocketUnitName();
+    std::string getServiceUnitName();
+};
+
+} // namespace service
+} // namespace phosphor
diff --git a/inc/utils.hpp b/inc/utils.hpp
index e4a31bb..c9df6ae 100644
--- a/inc/utils.hpp
+++ b/inc/utils.hpp
@@ -1,64 +1,64 @@
-/*

-// Copyright (c) 2018 Intel Corporation

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//      http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-*/

-#pragma once

-#include <boost/asio.hpp>

-#include <phosphor-logging/elog-errors.hpp>

-#include <sdbusplus/asio/object_server.hpp>

-#include <xyz/openbmc_project/Common/error.hpp>

-

-#include <chrono>

-#include <ctime>

-#include <filesystem>

-#include <string>

-

-static constexpr const char* sysdStartUnit = "StartUnit";

-static constexpr const char* sysdStopUnit = "StopUnit";

-static constexpr const char* sysdRestartUnit = "RestartUnit";

-static constexpr const char* sysdReloadMethod = "Reload";

-static constexpr const char* sysdGetJobMethod = "GetJob";

-static constexpr const char* sysdReplaceMode = "replace";

-static constexpr const char* dBusGetAllMethod = "GetAll";

-static constexpr const char* dBusGetMethod = "Get";

-static constexpr const char* sysdService = "org.freedesktop.systemd1";

-static constexpr const char* sysdObjPath = "/org/freedesktop/systemd1";

-static constexpr const char* sysdMgrIntf = "org.freedesktop.systemd1.Manager";

-static constexpr const char* sysdUnitIntf = "org.freedesktop.systemd1.Unit";

-static constexpr const char* sysdSocketIntf = "org.freedesktop.systemd1.Socket";

-static constexpr const char* dBusPropIntf = "org.freedesktop.DBus.Properties";

-static constexpr const char* stateMasked = "masked";

-static constexpr const char* stateEnabled = "enabled";

-static constexpr const char* stateDisabled = "disabled";

-static constexpr const char* subStateRunning = "running";

-

-static inline std::string addInstanceName(const std::string& instanceName,

-                                          const std::string& suffix)

-{

-    return (instanceName.empty() ? "" : suffix + instanceName);

-}

-

-void systemdDaemonReload(

-    const std::shared_ptr<sdbusplus::asio::connection>& conn,

-    boost::asio::yield_context yield);

-

-void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,

-                       boost::asio::yield_context yield,

-                       const std::string& unitName,

-                       const std::string& actionMethod);

-

-void systemdUnitFilesStateChange(

-    const std::shared_ptr<sdbusplus::asio::connection>& conn,

-    boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,

-    const std::string& unitState, bool maskedState, bool enabledState);

+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+#include <boost/asio.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
+
+#include <chrono>
+#include <ctime>
+#include <filesystem>
+#include <string>
+
+static constexpr const char* sysdStartUnit = "StartUnit";
+static constexpr const char* sysdStopUnit = "StopUnit";
+static constexpr const char* sysdRestartUnit = "RestartUnit";
+static constexpr const char* sysdReloadMethod = "Reload";
+static constexpr const char* sysdGetJobMethod = "GetJob";
+static constexpr const char* sysdReplaceMode = "replace";
+static constexpr const char* dBusGetAllMethod = "GetAll";
+static constexpr const char* dBusGetMethod = "Get";
+static constexpr const char* sysdService = "org.freedesktop.systemd1";
+static constexpr const char* sysdObjPath = "/org/freedesktop/systemd1";
+static constexpr const char* sysdMgrIntf = "org.freedesktop.systemd1.Manager";
+static constexpr const char* sysdUnitIntf = "org.freedesktop.systemd1.Unit";
+static constexpr const char* sysdSocketIntf = "org.freedesktop.systemd1.Socket";
+static constexpr const char* dBusPropIntf = "org.freedesktop.DBus.Properties";
+static constexpr const char* stateMasked = "masked";
+static constexpr const char* stateEnabled = "enabled";
+static constexpr const char* stateDisabled = "disabled";
+static constexpr const char* subStateRunning = "running";
+
+static inline std::string addInstanceName(const std::string& instanceName,
+                                          const std::string& suffix)
+{
+    return (instanceName.empty() ? "" : suffix + instanceName);
+}
+
+void systemdDaemonReload(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::yield_context yield);
+
+void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+                       boost::asio::yield_context yield,
+                       const std::string& unitName,
+                       const std::string& actionMethod);
+
+void systemdUnitFilesStateChange(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,
+    const std::string& unitState, bool maskedState, bool enabledState);
diff --git a/src/main.cpp b/src/main.cpp
index d15a4b9..b45cf63 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,333 +1,333 @@
-/*

-// Copyright (c) 2018 Intel Corporation

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//      http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-*/

-#include "srvcfg_manager.hpp"

-

-#include <boost/algorithm/string/replace.hpp>

-#include <cereal/archives/json.hpp>

-#include <cereal/types/tuple.hpp>

-#include <cereal/types/unordered_map.hpp>

-#include <sdbusplus/bus/match.hpp>

-

-#include <filesystem>

-#include <fstream>

-

-std::unique_ptr<boost::asio::steady_timer> timer = nullptr;

-std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;

-std::map<std::string, std::shared_ptr<phosphor::service::ServiceConfig>>

-    srvMgrObjects;

-static bool unitQueryStarted = false;

-

-static constexpr const char* srvCfgMgrFile = "/etc/srvcfg-mgr.json";

-

-// Base service name list. All instance of these services and

-// units(service/socket) will be managed by this daemon.

-static std::array<std::string, 5> serviceNames = {

-    "phosphor-ipmi-net", "bmcweb", "phosphor-ipmi-kcs", "start-ipkvm",

-    "obmc-console"};

-

-using ListUnitsType =

-    std::tuple<std::string, std::string, std::string, std::string, std::string,

-               std::string, sdbusplus::message::object_path, uint32_t,

-               std::string, sdbusplus::message::object_path>;

-

-enum class ListUnitElements

-{

-    name,

-    descriptionString,

-    loadState,

-    activeState,

-    subState,

-    followedUnit,

-    objectPath,

-    queuedJobType,

-    jobType,

-    jobObject

-};

-

-enum class UnitType

-{

-    service,

-    socket,

-    target,

-    device,

-    invalid

-};

-

-using MonitorListMap =

-    std::unordered_map<std::string, std::tuple<std::string, std::string,

-                                               std::string, std::string>>;

-MonitorListMap unitsToMonitor;

-

-enum class monitorElement

-{

-    unitName,

-    instanceName,

-    serviceObjPath,

-    socketObjPath

-};

-

-std::tuple<std::string, UnitType, std::string>

-    getUnitNameTypeAndInstance(const std::string& fullUnitName)

-{

-    UnitType type = UnitType::invalid;

-    std::string instanceName;

-    std::string unitName;

-    // get service type

-    auto typePos = fullUnitName.rfind(".");

-    if (typePos != std::string::npos)

-    {

-        const auto& typeStr = fullUnitName.substr(typePos + 1);

-        // Ignore types other than service and socket

-        if (typeStr == "service")

-        {

-            type = UnitType::service;

-        }

-        else if (typeStr == "socket")

-        {

-            type = UnitType::socket;

-        }

-        // get instance name if available

-        auto instancePos = fullUnitName.rfind("@");

-        if (instancePos != std::string::npos)

-        {

-            instanceName =

-                fullUnitName.substr(instancePos + 1, typePos - instancePos - 1);

-            unitName = fullUnitName.substr(0, instancePos);

-        }

-        else

-        {

-            unitName = fullUnitName.substr(0, typePos);

-        }

-    }

-    return std::make_tuple(unitName, type, instanceName);

-}

-

-static inline void

-    handleListUnitsResponse(sdbusplus::asio::object_server& server,

-                            std::shared_ptr<sdbusplus::asio::connection>& conn,

-                            boost::system::error_code /*ec*/,

-                            const std::vector<ListUnitsType>& listUnits)

-{

-    // Loop through all units, and mark all units, which has to be

-    // managed, irrespective of instance name.

-    for (const auto& unit : listUnits)

-    {

-        const auto& fullUnitName =

-            std::get<static_cast<int>(ListUnitElements::name)>(unit);

-        auto [unitName, type, instanceName] =

-            getUnitNameTypeAndInstance(fullUnitName);

-        if (std::find(serviceNames.begin(), serviceNames.end(), unitName) !=

-            serviceNames.end())

-        {

-            std::string instantiatedUnitName =

-                unitName + addInstanceName(instanceName, "_40");

-            boost::replace_all(instantiatedUnitName, "-", "_2d");

-            const sdbusplus::message::object_path& objectPath =

-                std::get<static_cast<int>(ListUnitElements::objectPath)>(unit);

-            // Group the service & socket units togther.. Same services

-            // are managed together.

-            auto it = unitsToMonitor.find(instantiatedUnitName);

-            if (it != unitsToMonitor.end())

-            {

-                auto& value = it->second;

-                if (type == UnitType::service)

-                {

-                    std::get<static_cast<int>(monitorElement::unitName)>(

-                        value) = unitName;

-                    std::get<static_cast<int>(monitorElement::instanceName)>(

-                        value) = instanceName;

-                    std::get<static_cast<int>(monitorElement::serviceObjPath)>(

-                        value) = objectPath;

-                }

-                else if (type == UnitType::socket)

-                {

-                    std::get<static_cast<int>(monitorElement::socketObjPath)>(

-                        value) = objectPath;

-                }

-            }

-            if (type == UnitType::service)

-            {

-                unitsToMonitor.emplace(instantiatedUnitName,

-                                       std::make_tuple(unitName, instanceName,

-                                                       objectPath.str, ""));

-            }

-            else if (type == UnitType::socket)

-            {

-                unitsToMonitor.emplace(

-                    instantiatedUnitName,

-                    std::make_tuple("", "", "", objectPath.str));

-            }

-        }

-    }

-

-    bool updateRequired = false;

-    bool jsonExist = std::filesystem::exists(srvCfgMgrFile);

-    if (jsonExist)

-    {

-        std::ifstream file(srvCfgMgrFile);

-        cereal::JSONInputArchive archive(file);

-        MonitorListMap savedMonitorList;

-        archive(savedMonitorList);

-

-        // compare the unit list read from systemd1 and the save list.

-        MonitorListMap diffMap;

-        std::set_difference(begin(unitsToMonitor), end(unitsToMonitor),

-                            begin(savedMonitorList), end(savedMonitorList),

-                            std::inserter(diffMap, begin(diffMap)));

-        for (auto& unitIt : diffMap)

-        {

-            auto it = savedMonitorList.find(unitIt.first);

-            if (it == savedMonitorList.end())

-            {

-                savedMonitorList.insert(unitIt);

-                updateRequired = true;

-            }

-        }

-        unitsToMonitor = savedMonitorList;

-    }

-    if (!jsonExist || updateRequired)

-    {

-        std::ofstream file(srvCfgMgrFile);

-        cereal::JSONOutputArchive archive(file);

-        archive(CEREAL_NVP(unitsToMonitor));

-    }

-

-    // create objects for needed services

-    for (auto& it : unitsToMonitor)

-    {

-        std::string objPath(std::string(phosphor::service::srcCfgMgrBasePath) +

-                            "/" + it.first);

-        std::string instanciatedUnitName =

-            std::get<static_cast<int>(monitorElement::unitName)>(it.second) +

-            addInstanceName(

-                std::get<static_cast<int>(monitorElement::instanceName)>(

-                    it.second),

-                "@");

-        auto srvCfgObj = std::make_unique<phosphor::service::ServiceConfig>(

-            server, conn, objPath,

-            std::get<static_cast<int>(monitorElement::unitName)>(it.second),

-            std::get<static_cast<int>(monitorElement::instanceName)>(it.second),

-            std::get<static_cast<int>(monitorElement::serviceObjPath)>(

-                it.second),

-            std::get<static_cast<int>(monitorElement::socketObjPath)>(

-                it.second));

-        srvMgrObjects.emplace(

-            std::make_pair(std::move(objPath), std::move(srvCfgObj)));

-    }

-}

-

-void init(sdbusplus::asio::object_server& server,

-          std::shared_ptr<sdbusplus::asio::connection>& conn)

-{

-    // Go through all systemd units, and dynamically detect and manage

-    // the service daemons

-    conn->async_method_call(

-        [&server, &conn](boost::system::error_code ec,

-                         const std::vector<ListUnitsType>& listUnits) {

-            if (ec)

-            {

-                phosphor::logging::log<phosphor::logging::level::ERR>(

-                    "async_method_call error: ListUnits failed");

-                return;

-            }

-            handleListUnitsResponse(server, conn, ec, listUnits);

-        },

-        sysdService, sysdObjPath, sysdMgrIntf, "ListUnits");

-}

-

-void checkAndInit(sdbusplus::asio::object_server& server,

-                  std::shared_ptr<sdbusplus::asio::connection>& conn)

-{

-    // Check whether systemd completed all the loading before initializing

-    conn->async_method_call(

-        [&server, &conn](boost::system::error_code ec,

-                         const std::variant<uint64_t>& value) {

-            if (ec)

-            {

-                phosphor::logging::log<phosphor::logging::level::ERR>(

-                    "async_method_call error: ListUnits failed");

-                return;

-            }

-            if (std::get<uint64_t>(value))

-            {

-                if (!unitQueryStarted)

-                {

-                    unitQueryStarted = true;

-                    init(server, conn);

-                }

-            }

-            else

-            {

-                // FIX-ME: Latest up-stream sync caused issue in receiving

-                // StartupFinished signal. Unable to get StartupFinished signal

-                // from systemd1 hence using poll method too, to trigger it

-                // properly.

-                constexpr size_t pollTimeout = 10; // seconds

-                initTimer->expires_after(std::chrono::seconds(pollTimeout));

-                initTimer->async_wait([&server, &conn](

-                                          const boost::system::error_code& ec) {

-                    if (ec == boost::asio::error::operation_aborted)

-                    {

-                        // Timer reset.

-                        return;

-                    }

-                    if (ec)

-                    {

-                        phosphor::logging::log<phosphor::logging::level::ERR>(

-                            "service config mgr - init - async wait error.");

-                        return;

-                    }

-                    checkAndInit(server, conn);

-                });

-            }

-        },

-        sysdService, sysdObjPath, dBusPropIntf, dBusGetMethod, sysdMgrIntf,

-        "FinishTimestamp");

-}

-

-int main()

-{

-    boost::asio::io_service io;

-    auto conn = std::make_shared<sdbusplus::asio::connection>(io);

-    timer = std::make_unique<boost::asio::steady_timer>(io);

-    initTimer = std::make_unique<boost::asio::steady_timer>(io);

-    conn->request_name(phosphor::service::serviceConfigSrvName);

-    auto server = sdbusplus::asio::object_server(conn, true);

-    auto mgrIntf = server.add_interface(phosphor::service::srcCfgMgrBasePath,

-                                        phosphor::service::srcCfgMgrIntf);

-    mgrIntf->initialize();

-    server.add_manager(phosphor::service::srcCfgMgrBasePath);

-    // Initialize the objects after systemd indicated startup finished.

-    auto userUpdatedSignal = std::make_unique<sdbusplus::bus::match::match>(

-        static_cast<sdbusplus::bus::bus&>(*conn),

-        "type='signal',"

-        "member='StartupFinished',path='/org/freedesktop/systemd1',"

-        "interface='org.freedesktop.systemd1.Manager'",

-        [&server, &conn](sdbusplus::message::message& /*msg*/) {

-            if (!unitQueryStarted)

-            {

-                unitQueryStarted = true;

-                init(server, conn);

-            }

-        });

-    // this will make sure to initialize the objects, when daemon is

-    // restarted.

-    checkAndInit(server, conn);

-

-    io.run();

-

-    return 0;

-}

+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "srvcfg_manager.hpp"
+
+#include <boost/algorithm/string/replace.hpp>
+#include <cereal/archives/json.hpp>
+#include <cereal/types/tuple.hpp>
+#include <cereal/types/unordered_map.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <filesystem>
+#include <fstream>
+
+std::unique_ptr<boost::asio::steady_timer> timer = nullptr;
+std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;
+std::map<std::string, std::shared_ptr<phosphor::service::ServiceConfig>>
+    srvMgrObjects;
+static bool unitQueryStarted = false;
+
+static constexpr const char* srvCfgMgrFile = "/etc/srvcfg-mgr.json";
+
+// Base service name list. All instance of these services and
+// units(service/socket) will be managed by this daemon.
+static std::array<std::string, 5> serviceNames = {
+    "phosphor-ipmi-net", "bmcweb", "phosphor-ipmi-kcs", "start-ipkvm",
+    "obmc-console"};
+
+using ListUnitsType =
+    std::tuple<std::string, std::string, std::string, std::string, std::string,
+               std::string, sdbusplus::message::object_path, uint32_t,
+               std::string, sdbusplus::message::object_path>;
+
+enum class ListUnitElements
+{
+    name,
+    descriptionString,
+    loadState,
+    activeState,
+    subState,
+    followedUnit,
+    objectPath,
+    queuedJobType,
+    jobType,
+    jobObject
+};
+
+enum class UnitType
+{
+    service,
+    socket,
+    target,
+    device,
+    invalid
+};
+
+using MonitorListMap =
+    std::unordered_map<std::string, std::tuple<std::string, std::string,
+                                               std::string, std::string>>;
+MonitorListMap unitsToMonitor;
+
+enum class monitorElement
+{
+    unitName,
+    instanceName,
+    serviceObjPath,
+    socketObjPath
+};
+
+std::tuple<std::string, UnitType, std::string>
+    getUnitNameTypeAndInstance(const std::string& fullUnitName)
+{
+    UnitType type = UnitType::invalid;
+    std::string instanceName;
+    std::string unitName;
+    // get service type
+    auto typePos = fullUnitName.rfind(".");
+    if (typePos != std::string::npos)
+    {
+        const auto& typeStr = fullUnitName.substr(typePos + 1);
+        // Ignore types other than service and socket
+        if (typeStr == "service")
+        {
+            type = UnitType::service;
+        }
+        else if (typeStr == "socket")
+        {
+            type = UnitType::socket;
+        }
+        // get instance name if available
+        auto instancePos = fullUnitName.rfind("@");
+        if (instancePos != std::string::npos)
+        {
+            instanceName =
+                fullUnitName.substr(instancePos + 1, typePos - instancePos - 1);
+            unitName = fullUnitName.substr(0, instancePos);
+        }
+        else
+        {
+            unitName = fullUnitName.substr(0, typePos);
+        }
+    }
+    return std::make_tuple(unitName, type, instanceName);
+}
+
+static inline void
+    handleListUnitsResponse(sdbusplus::asio::object_server& server,
+                            std::shared_ptr<sdbusplus::asio::connection>& conn,
+                            boost::system::error_code /*ec*/,
+                            const std::vector<ListUnitsType>& listUnits)
+{
+    // Loop through all units, and mark all units, which has to be
+    // managed, irrespective of instance name.
+    for (const auto& unit : listUnits)
+    {
+        const auto& fullUnitName =
+            std::get<static_cast<int>(ListUnitElements::name)>(unit);
+        auto [unitName, type, instanceName] =
+            getUnitNameTypeAndInstance(fullUnitName);
+        if (std::find(serviceNames.begin(), serviceNames.end(), unitName) !=
+            serviceNames.end())
+        {
+            std::string instantiatedUnitName =
+                unitName + addInstanceName(instanceName, "_40");
+            boost::replace_all(instantiatedUnitName, "-", "_2d");
+            const sdbusplus::message::object_path& objectPath =
+                std::get<static_cast<int>(ListUnitElements::objectPath)>(unit);
+            // Group the service & socket units togther.. Same services
+            // are managed together.
+            auto it = unitsToMonitor.find(instantiatedUnitName);
+            if (it != unitsToMonitor.end())
+            {
+                auto& value = it->second;
+                if (type == UnitType::service)
+                {
+                    std::get<static_cast<int>(monitorElement::unitName)>(
+                        value) = unitName;
+                    std::get<static_cast<int>(monitorElement::instanceName)>(
+                        value) = instanceName;
+                    std::get<static_cast<int>(monitorElement::serviceObjPath)>(
+                        value) = objectPath;
+                }
+                else if (type == UnitType::socket)
+                {
+                    std::get<static_cast<int>(monitorElement::socketObjPath)>(
+                        value) = objectPath;
+                }
+            }
+            if (type == UnitType::service)
+            {
+                unitsToMonitor.emplace(instantiatedUnitName,
+                                       std::make_tuple(unitName, instanceName,
+                                                       objectPath.str, ""));
+            }
+            else if (type == UnitType::socket)
+            {
+                unitsToMonitor.emplace(
+                    instantiatedUnitName,
+                    std::make_tuple("", "", "", objectPath.str));
+            }
+        }
+    }
+
+    bool updateRequired = false;
+    bool jsonExist = std::filesystem::exists(srvCfgMgrFile);
+    if (jsonExist)
+    {
+        std::ifstream file(srvCfgMgrFile);
+        cereal::JSONInputArchive archive(file);
+        MonitorListMap savedMonitorList;
+        archive(savedMonitorList);
+
+        // compare the unit list read from systemd1 and the save list.
+        MonitorListMap diffMap;
+        std::set_difference(begin(unitsToMonitor), end(unitsToMonitor),
+                            begin(savedMonitorList), end(savedMonitorList),
+                            std::inserter(diffMap, begin(diffMap)));
+        for (auto& unitIt : diffMap)
+        {
+            auto it = savedMonitorList.find(unitIt.first);
+            if (it == savedMonitorList.end())
+            {
+                savedMonitorList.insert(unitIt);
+                updateRequired = true;
+            }
+        }
+        unitsToMonitor = savedMonitorList;
+    }
+    if (!jsonExist || updateRequired)
+    {
+        std::ofstream file(srvCfgMgrFile);
+        cereal::JSONOutputArchive archive(file);
+        archive(CEREAL_NVP(unitsToMonitor));
+    }
+
+    // create objects for needed services
+    for (auto& it : unitsToMonitor)
+    {
+        std::string objPath(std::string(phosphor::service::srcCfgMgrBasePath) +
+                            "/" + it.first);
+        std::string instanciatedUnitName =
+            std::get<static_cast<int>(monitorElement::unitName)>(it.second) +
+            addInstanceName(
+                std::get<static_cast<int>(monitorElement::instanceName)>(
+                    it.second),
+                "@");
+        auto srvCfgObj = std::make_unique<phosphor::service::ServiceConfig>(
+            server, conn, objPath,
+            std::get<static_cast<int>(monitorElement::unitName)>(it.second),
+            std::get<static_cast<int>(monitorElement::instanceName)>(it.second),
+            std::get<static_cast<int>(monitorElement::serviceObjPath)>(
+                it.second),
+            std::get<static_cast<int>(monitorElement::socketObjPath)>(
+                it.second));
+        srvMgrObjects.emplace(
+            std::make_pair(std::move(objPath), std::move(srvCfgObj)));
+    }
+}
+
+void init(sdbusplus::asio::object_server& server,
+          std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+    // Go through all systemd units, and dynamically detect and manage
+    // the service daemons
+    conn->async_method_call(
+        [&server, &conn](boost::system::error_code ec,
+                         const std::vector<ListUnitsType>& listUnits) {
+            if (ec)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "async_method_call error: ListUnits failed");
+                return;
+            }
+            handleListUnitsResponse(server, conn, ec, listUnits);
+        },
+        sysdService, sysdObjPath, sysdMgrIntf, "ListUnits");
+}
+
+void checkAndInit(sdbusplus::asio::object_server& server,
+                  std::shared_ptr<sdbusplus::asio::connection>& conn)
+{
+    // Check whether systemd completed all the loading before initializing
+    conn->async_method_call(
+        [&server, &conn](boost::system::error_code ec,
+                         const std::variant<uint64_t>& value) {
+            if (ec)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "async_method_call error: ListUnits failed");
+                return;
+            }
+            if (std::get<uint64_t>(value))
+            {
+                if (!unitQueryStarted)
+                {
+                    unitQueryStarted = true;
+                    init(server, conn);
+                }
+            }
+            else
+            {
+                // FIX-ME: Latest up-stream sync caused issue in receiving
+                // StartupFinished signal. Unable to get StartupFinished signal
+                // from systemd1 hence using poll method too, to trigger it
+                // properly.
+                constexpr size_t pollTimeout = 10; // seconds
+                initTimer->expires_after(std::chrono::seconds(pollTimeout));
+                initTimer->async_wait([&server, &conn](
+                                          const boost::system::error_code& ec) {
+                    if (ec == boost::asio::error::operation_aborted)
+                    {
+                        // Timer reset.
+                        return;
+                    }
+                    if (ec)
+                    {
+                        phosphor::logging::log<phosphor::logging::level::ERR>(
+                            "service config mgr - init - async wait error.");
+                        return;
+                    }
+                    checkAndInit(server, conn);
+                });
+            }
+        },
+        sysdService, sysdObjPath, dBusPropIntf, dBusGetMethod, sysdMgrIntf,
+        "FinishTimestamp");
+}
+
+int main()
+{
+    boost::asio::io_service io;
+    auto conn = std::make_shared<sdbusplus::asio::connection>(io);
+    timer = std::make_unique<boost::asio::steady_timer>(io);
+    initTimer = std::make_unique<boost::asio::steady_timer>(io);
+    conn->request_name(phosphor::service::serviceConfigSrvName);
+    auto server = sdbusplus::asio::object_server(conn, true);
+    auto mgrIntf = server.add_interface(phosphor::service::srcCfgMgrBasePath,
+                                        phosphor::service::srcCfgMgrIntf);
+    mgrIntf->initialize();
+    server.add_manager(phosphor::service::srcCfgMgrBasePath);
+    // Initialize the objects after systemd indicated startup finished.
+    auto userUpdatedSignal = std::make_unique<sdbusplus::bus::match::match>(
+        static_cast<sdbusplus::bus::bus&>(*conn),
+        "type='signal',"
+        "member='StartupFinished',path='/org/freedesktop/systemd1',"
+        "interface='org.freedesktop.systemd1.Manager'",
+        [&server, &conn](sdbusplus::message::message& /*msg*/) {
+            if (!unitQueryStarted)
+            {
+                unitQueryStarted = true;
+                init(server, conn);
+            }
+        });
+    // this will make sure to initialize the objects, when daemon is
+    // restarted.
+    checkAndInit(server, conn);
+
+    io.run();
+
+    return 0;
+}
diff --git a/src/srvcfg_manager.cpp b/src/srvcfg_manager.cpp
index 2d346c2..038d11a 100644
--- a/src/srvcfg_manager.cpp
+++ b/src/srvcfg_manager.cpp
@@ -1,505 +1,505 @@
-/*

-// Copyright (c) 2018 Intel Corporation

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//      http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-*/

-#include "srvcfg_manager.hpp"

-

-#include <boost/asio/spawn.hpp>

-

-#include <fstream>

-#include <regex>

-

-extern std::unique_ptr<boost::asio::steady_timer> timer;

-extern std::map<std::string, std::shared_ptr<phosphor::service::ServiceConfig>>

-    srvMgrObjects;

-static bool updateInProgress = false;

-

-namespace phosphor

-{

-namespace service

-{

-

-static constexpr const char* overrideConfFileName = "override.conf";

-static constexpr const size_t restartTimeout = 15; // seconds

-

-static constexpr const char* systemd1UnitBasePath =

-    "/org/freedesktop/systemd1/unit/";

-static constexpr const char* systemdOverrideUnitBasePath =

-    "/etc/systemd/system/";

-

-void ServiceConfig::updateSocketProperties(

-    const boost::container::flat_map<std::string, VariantType>& propertyMap)

-{

-    auto listenIt = propertyMap.find("Listen");

-    if (listenIt != propertyMap.end())

-    {

-        auto listenVal =

-            std::get<std::vector<std::tuple<std::string, std::string>>>(

-                listenIt->second);

-        if (listenVal.size())

-        {

-            protocol = std::get<0>(listenVal[0]);

-            std::string port = std::get<1>(listenVal[0]);

-            auto tmp = std::stoul(port.substr(port.find_last_of(":") + 1),

-                                  nullptr, 10);

-            if (tmp > std::numeric_limits<uint16_t>::max())

-            {

-                throw std::out_of_range("Out of range");

-            }

-            portNum = tmp;

-            if (sockAttrIface && sockAttrIface->is_initialized())

-            {

-                internalSet = true;

-                sockAttrIface->set_property(sockAttrPropPort, portNum);

-                internalSet = false;

-            }

-        }

-    }

-}

-

-void ServiceConfig::updateServiceProperties(

-    const boost::container::flat_map<std::string, VariantType>& propertyMap)

-{

-    auto stateIt = propertyMap.find("UnitFileState");

-    if (stateIt != propertyMap.end())

-    {

-        stateValue = std::get<std::string>(stateIt->second);

-        unitEnabledState = unitMaskedState = false;

-        if (stateValue == stateMasked)

-        {

-            unitMaskedState = true;

-        }

-        else if (stateValue == stateEnabled)

-        {

-            unitEnabledState = true;

-        }

-        if (srvCfgIface && srvCfgIface->is_initialized())

-        {

-            internalSet = true;

-            srvCfgIface->set_property(srvCfgPropMasked, unitMaskedState);

-            srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);

-            internalSet = false;

-        }

-    }

-    auto subStateIt = propertyMap.find("SubState");

-    if (subStateIt != propertyMap.end())

-    {

-        subStateValue = std::get<std::string>(subStateIt->second);

-        if (subStateValue == subStateRunning)

-        {

-            unitRunningState = true;

-        }

-        if (srvCfgIface && srvCfgIface->is_initialized())

-        {

-            internalSet = true;

-            srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);

-            internalSet = false;

-        }

-    }

-}

-

-void ServiceConfig::queryAndUpdateProperties()

-{

-    conn->async_method_call(

-        [this](boost::system::error_code ec,

-               const boost::container::flat_map<std::string, VariantType>&

-                   propertyMap) {

-            if (ec)

-            {

-                phosphor::logging::log<phosphor::logging::level::ERR>(

-                    "async_method_call error: Failed to service unit "

-                    "properties");

-                return;

-            }

-            try

-            {

-                updateServiceProperties(propertyMap);

-                if (!socketObjectPath.empty())

-                {

-                    conn->async_method_call(

-                        [this](boost::system::error_code ec,

-                               const boost::container::flat_map<

-                                   std::string, VariantType>& propertyMap) {

-                            if (ec)

-                            {

-                                phosphor::logging::log<

-                                    phosphor::logging::level::ERR>(

-                                    "async_method_call error: Failed to get "

-                                    "all property");

-                                return;

-                            }

-                            try

-                            {

-                                updateSocketProperties(propertyMap);

-                                if (!srvCfgIface)

-                                {

-                                    registerProperties();

-                                }

-                            }

-                            catch (const std::exception& e)

-                            {

-                                phosphor::logging::log<

-                                    phosphor::logging::level::ERR>(

-                                    "Exception in getting socket properties",

-                                    phosphor::logging::entry("WHAT=%s",

-                                                             e.what()));

-                                return;

-                            }

-                        },

-                        sysdService, socketObjectPath, dBusPropIntf,

-                        dBusGetAllMethod, sysdSocketIntf);

-                }

-                else if (!srvCfgIface)

-                {

-                    registerProperties();

-                }

-            }

-            catch (const std::exception& e)

-            {

-                phosphor::logging::log<phosphor::logging::level::ERR>(

-                    "Exception in getting socket properties",

-                    phosphor::logging::entry("WHAT=%s", e.what()));

-                return;

-            }

-        },

-        sysdService, serviceObjectPath, dBusPropIntf, dBusGetAllMethod,

-        sysdUnitIntf);

-    return;

-}

-

-void ServiceConfig::createSocketOverrideConf()

-{

-    if (!socketObjectPath.empty())

-    {

-        std::string socketUnitName(instantiatedUnitName + ".socket");

-        /// Check override socket directory exist, if not create it.

-        std::filesystem::path ovrUnitFileDir(systemdOverrideUnitBasePath);

-        ovrUnitFileDir += socketUnitName;

-        ovrUnitFileDir += ".d";

-        if (!std::filesystem::exists(ovrUnitFileDir))

-        {

-            if (!std::filesystem::create_directories(ovrUnitFileDir))

-            {

-                phosphor::logging::log<phosphor::logging::level::ERR>(

-                    "Unable to create the directory.",

-                    phosphor::logging::entry("DIR=%s", ovrUnitFileDir.c_str()));

-                phosphor::logging::elog<sdbusplus::xyz::openbmc_project::

-                                            Common::Error::InternalFailure>();

-            }

-        }

-        overrideConfDir = std::string(ovrUnitFileDir);

-    }

-}

-

-ServiceConfig::ServiceConfig(

-    sdbusplus::asio::object_server& srv_,

-    std::shared_ptr<sdbusplus::asio::connection>& conn_,

-    const std::string& objPath_, const std::string& baseUnitName_,

-    const std::string& instanceName_, const std::string& serviceObjPath_,

-    const std::string& socketObjPath_) :

-    conn(conn_),

-    server(srv_), objPath(objPath_), baseUnitName(baseUnitName_),

-    instanceName(instanceName_), serviceObjectPath(serviceObjPath_),

-    socketObjectPath(socketObjPath_)

-{

-    instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");

-    updatedFlag = 0;

-    queryAndUpdateProperties();

-    return;

-}

-

-std::string ServiceConfig::getSocketUnitName()

-{

-    return instantiatedUnitName + ".socket";

-}

-

-std::string ServiceConfig::getServiceUnitName()

-{

-    return instantiatedUnitName + ".service";

-}

-

-bool ServiceConfig::isMaskedOut()

-{

-    // return true  if state is masked & no request to update the maskedState

-    return (

-        stateValue == "masked" &&

-        !(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::maskedState))));

-}

-

-void ServiceConfig::stopAndApplyUnitConfig(boost::asio::yield_context yield)

-{

-    if (!updatedFlag || isMaskedOut())

-    {

-        // No updates / masked - Just return.

-        return;

-    }

-    phosphor::logging::log<phosphor::logging::level::INFO>(

-        "Applying new settings.",

-        phosphor::logging::entry("OBJPATH=%s", objPath.c_str()));

-    if (subStateValue == "running")

-    {

-        if (!socketObjectPath.empty())

-        {

-            systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);

-        }

-        systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);

-    }

-

-    if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))

-    {

-        createSocketOverrideConf();

-        // Create override config file and write data.

-        std::string ovrCfgFile{overrideConfDir + "/" + overrideConfFileName};

-        std::string tmpFile{ovrCfgFile + "_tmp"};

-        std::ofstream cfgFile(tmpFile, std::ios::out);

-        if (!cfgFile.good())

-        {

-            phosphor::logging::log<phosphor::logging::level::ERR>(

-                "Failed to open override.conf_tmp file");

-            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::

-                                        Error::InternalFailure>();

-        }

-

-        // Write the socket header

-        cfgFile << "[Socket]\n";

-        // Listen

-        cfgFile << "Listen" << protocol << "="

-                << "\n";

-        cfgFile << "Listen" << protocol << "=" << portNum << "\n";

-        cfgFile.close();

-

-        if (std::rename(tmpFile.c_str(), ovrCfgFile.c_str()) != 0)

-        {

-            phosphor::logging::log<phosphor::logging::level::ERR>(

-                "Failed to rename tmp file as override.conf");

-            std::remove(tmpFile.c_str());

-            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::

-                                        Error::InternalFailure>();

-        }

-    }

-

-    if (updatedFlag & ((1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |

-                       (1 << static_cast<uint8_t>(UpdatedProp::enabledState))))

-    {

-        std::vector<std::string> unitFiles;

-        if (socketObjectPath.empty())

-        {

-            unitFiles = {getServiceUnitName()};

-        }

-        else

-        {

-            unitFiles = {getSocketUnitName(), getServiceUnitName()};

-        }

-        systemdUnitFilesStateChange(conn, yield, unitFiles, stateValue,

-                                    unitMaskedState, unitEnabledState);

-    }

-    return;

-}

-void ServiceConfig::restartUnitConfig(boost::asio::yield_context yield)

-{

-    if (!updatedFlag || isMaskedOut())

-    {

-        // No updates. Just return.

-        return;

-    }

-

-    if (unitRunningState)

-    {

-        if (!socketObjectPath.empty())

-        {

-            systemdUnitAction(conn, yield, getSocketUnitName(),

-                              sysdRestartUnit);

-        }

-        systemdUnitAction(conn, yield, getServiceUnitName(), sysdRestartUnit);

-    }

-

-    // Reset the flag

-    updatedFlag = 0;

-

-    phosphor::logging::log<phosphor::logging::level::INFO>(

-        "Applied new settings",

-        phosphor::logging::entry("OBJPATH=%s", objPath.c_str()));

-

-    queryAndUpdateProperties();

-    return;

-}

-

-void ServiceConfig::startServiceRestartTimer()

-{

-    timer->expires_after(std::chrono::seconds(restartTimeout));

-    timer->async_wait([this](const boost::system::error_code& ec) {

-        if (ec == boost::asio::error::operation_aborted)

-        {

-            // Timer reset.

-            return;

-        }

-        else if (ec)

-        {

-            phosphor::logging::log<phosphor::logging::level::ERR>(

-                "async wait error.");

-            return;

-        }

-        updateInProgress = true;

-        boost::asio::spawn(conn->get_io_context(),

-                           [this](boost::asio::yield_context yield) {

-                               // Stop and apply configuration for all objects

-                               for (auto& srvMgrObj : srvMgrObjects)

-                               {

-                                   auto& srvObj = srvMgrObj.second;

-                                   if (srvObj->updatedFlag)

-                                   {

-                                       srvObj->stopAndApplyUnitConfig(yield);

-                                   }

-                               }

-                               // Do system reload

-                               systemdDaemonReload(conn, yield);

-                               // restart unit config.

-                               for (auto& srvMgrObj : srvMgrObjects)

-                               {

-                                   auto& srvObj = srvMgrObj.second;

-                                   if (srvObj->updatedFlag)

-                                   {

-                                       srvObj->restartUnitConfig(yield);

-                                   }

-                               }

-                               updateInProgress = false;

-                           });

-    });

-}

-

-void ServiceConfig::registerProperties()

-{

-    srvCfgIface = server.add_interface(objPath, serviceConfigIntfName);

-

-    if (!socketObjectPath.empty())

-    {

-        sockAttrIface = server.add_interface(objPath, sockAttrIntfName);

-        sockAttrIface->register_property(

-            sockAttrPropPort, portNum,

-            [this](const uint16_t& req, uint16_t& res) {

-                if (!internalSet)

-                {

-                    if (req == res)

-                    {

-                        return 1;

-                    }

-                    if (updateInProgress)

-                    {

-                        return 0;

-                    }

-                    portNum = req;

-                    updatedFlag |=

-                        (1 << static_cast<uint8_t>(UpdatedProp::port));

-                    startServiceRestartTimer();

-                }

-                res = req;

-                return 1;

-            });

-    }

-

-    srvCfgIface->register_property(

-        srvCfgPropMasked, unitMaskedState, [this](const bool& req, bool& res) {

-            if (!internalSet)

-            {

-                if (req == res)

-                {

-                    return 1;

-                }

-                if (updateInProgress)

-                {

-                    return 0;

-                }

-                unitMaskedState = req;

-                unitEnabledState = !unitMaskedState;

-                unitRunningState = !unitMaskedState;

-                updatedFlag |=

-                    (1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |

-                    (1 << static_cast<uint8_t>(UpdatedProp::enabledState)) |

-                    (1 << static_cast<uint8_t>(UpdatedProp::runningState));

-                internalSet = true;

-                srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);

-                srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);

-                internalSet = false;

-                startServiceRestartTimer();

-            }

-            res = req;

-            return 1;

-        });

-

-    srvCfgIface->register_property(

-        srvCfgPropEnabled, unitEnabledState,

-        [this](const bool& req, bool& res) {

-            if (!internalSet)

-            {

-                if (req == res)

-                {

-                    return 1;

-                }

-                if (updateInProgress)

-                {

-                    return 0;

-                }

-                if (unitMaskedState)

-                { // block updating if masked

-                    phosphor::logging::log<phosphor::logging::level::ERR>(

-                        "Invalid value specified");

-                    return -EINVAL;

-                }

-                unitEnabledState = req;

-                updatedFlag |=

-                    (1 << static_cast<uint8_t>(UpdatedProp::enabledState));

-                startServiceRestartTimer();

-            }

-            res = req;

-            return 1;

-        });

-

-    srvCfgIface->register_property(

-        srvCfgPropRunning, unitRunningState,

-        [this](const bool& req, bool& res) {

-            if (!internalSet)

-            {

-                if (req == res)

-                {

-                    return 1;

-                }

-                if (updateInProgress)

-                {

-                    return 0;

-                }

-                if (unitMaskedState)

-                { // block updating if masked

-                    phosphor::logging::log<phosphor::logging::level::ERR>(

-                        "Invalid value specified");

-                    return -EINVAL;

-                }

-                unitRunningState = req;

-                updatedFlag |=

-                    (1 << static_cast<uint8_t>(UpdatedProp::runningState));

-                startServiceRestartTimer();

-            }

-            res = req;

-            return 1;

-        });

-

-    srvCfgIface->initialize();

-    if (!socketObjectPath.empty())

-    {

-        sockAttrIface->initialize();

-    }

-    return;

-}

-

-} // namespace service

-} // namespace phosphor

+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "srvcfg_manager.hpp"
+
+#include <boost/asio/spawn.hpp>
+
+#include <fstream>
+#include <regex>
+
+extern std::unique_ptr<boost::asio::steady_timer> timer;
+extern std::map<std::string, std::shared_ptr<phosphor::service::ServiceConfig>>
+    srvMgrObjects;
+static bool updateInProgress = false;
+
+namespace phosphor
+{
+namespace service
+{
+
+static constexpr const char* overrideConfFileName = "override.conf";
+static constexpr const size_t restartTimeout = 15; // seconds
+
+static constexpr const char* systemd1UnitBasePath =
+    "/org/freedesktop/systemd1/unit/";
+static constexpr const char* systemdOverrideUnitBasePath =
+    "/etc/systemd/system/";
+
+void ServiceConfig::updateSocketProperties(
+    const boost::container::flat_map<std::string, VariantType>& propertyMap)
+{
+    auto listenIt = propertyMap.find("Listen");
+    if (listenIt != propertyMap.end())
+    {
+        auto listenVal =
+            std::get<std::vector<std::tuple<std::string, std::string>>>(
+                listenIt->second);
+        if (listenVal.size())
+        {
+            protocol = std::get<0>(listenVal[0]);
+            std::string port = std::get<1>(listenVal[0]);
+            auto tmp = std::stoul(port.substr(port.find_last_of(":") + 1),
+                                  nullptr, 10);
+            if (tmp > std::numeric_limits<uint16_t>::max())
+            {
+                throw std::out_of_range("Out of range");
+            }
+            portNum = tmp;
+            if (sockAttrIface && sockAttrIface->is_initialized())
+            {
+                internalSet = true;
+                sockAttrIface->set_property(sockAttrPropPort, portNum);
+                internalSet = false;
+            }
+        }
+    }
+}
+
+void ServiceConfig::updateServiceProperties(
+    const boost::container::flat_map<std::string, VariantType>& propertyMap)
+{
+    auto stateIt = propertyMap.find("UnitFileState");
+    if (stateIt != propertyMap.end())
+    {
+        stateValue = std::get<std::string>(stateIt->second);
+        unitEnabledState = unitMaskedState = false;
+        if (stateValue == stateMasked)
+        {
+            unitMaskedState = true;
+        }
+        else if (stateValue == stateEnabled)
+        {
+            unitEnabledState = true;
+        }
+        if (srvCfgIface && srvCfgIface->is_initialized())
+        {
+            internalSet = true;
+            srvCfgIface->set_property(srvCfgPropMasked, unitMaskedState);
+            srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
+            internalSet = false;
+        }
+    }
+    auto subStateIt = propertyMap.find("SubState");
+    if (subStateIt != propertyMap.end())
+    {
+        subStateValue = std::get<std::string>(subStateIt->second);
+        if (subStateValue == subStateRunning)
+        {
+            unitRunningState = true;
+        }
+        if (srvCfgIface && srvCfgIface->is_initialized())
+        {
+            internalSet = true;
+            srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
+            internalSet = false;
+        }
+    }
+}
+
+void ServiceConfig::queryAndUpdateProperties()
+{
+    conn->async_method_call(
+        [this](boost::system::error_code ec,
+               const boost::container::flat_map<std::string, VariantType>&
+                   propertyMap) {
+            if (ec)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "async_method_call error: Failed to service unit "
+                    "properties");
+                return;
+            }
+            try
+            {
+                updateServiceProperties(propertyMap);
+                if (!socketObjectPath.empty())
+                {
+                    conn->async_method_call(
+                        [this](boost::system::error_code ec,
+                               const boost::container::flat_map<
+                                   std::string, VariantType>& propertyMap) {
+                            if (ec)
+                            {
+                                phosphor::logging::log<
+                                    phosphor::logging::level::ERR>(
+                                    "async_method_call error: Failed to get "
+                                    "all property");
+                                return;
+                            }
+                            try
+                            {
+                                updateSocketProperties(propertyMap);
+                                if (!srvCfgIface)
+                                {
+                                    registerProperties();
+                                }
+                            }
+                            catch (const std::exception& e)
+                            {
+                                phosphor::logging::log<
+                                    phosphor::logging::level::ERR>(
+                                    "Exception in getting socket properties",
+                                    phosphor::logging::entry("WHAT=%s",
+                                                             e.what()));
+                                return;
+                            }
+                        },
+                        sysdService, socketObjectPath, dBusPropIntf,
+                        dBusGetAllMethod, sysdSocketIntf);
+                }
+                else if (!srvCfgIface)
+                {
+                    registerProperties();
+                }
+            }
+            catch (const std::exception& e)
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Exception in getting socket properties",
+                    phosphor::logging::entry("WHAT=%s", e.what()));
+                return;
+            }
+        },
+        sysdService, serviceObjectPath, dBusPropIntf, dBusGetAllMethod,
+        sysdUnitIntf);
+    return;
+}
+
+void ServiceConfig::createSocketOverrideConf()
+{
+    if (!socketObjectPath.empty())
+    {
+        std::string socketUnitName(instantiatedUnitName + ".socket");
+        /// Check override socket directory exist, if not create it.
+        std::filesystem::path ovrUnitFileDir(systemdOverrideUnitBasePath);
+        ovrUnitFileDir += socketUnitName;
+        ovrUnitFileDir += ".d";
+        if (!std::filesystem::exists(ovrUnitFileDir))
+        {
+            if (!std::filesystem::create_directories(ovrUnitFileDir))
+            {
+                phosphor::logging::log<phosphor::logging::level::ERR>(
+                    "Unable to create the directory.",
+                    phosphor::logging::entry("DIR=%s", ovrUnitFileDir.c_str()));
+                phosphor::logging::elog<sdbusplus::xyz::openbmc_project::
+                                            Common::Error::InternalFailure>();
+            }
+        }
+        overrideConfDir = std::string(ovrUnitFileDir);
+    }
+}
+
+ServiceConfig::ServiceConfig(
+    sdbusplus::asio::object_server& srv_,
+    std::shared_ptr<sdbusplus::asio::connection>& conn_,
+    const std::string& objPath_, const std::string& baseUnitName_,
+    const std::string& instanceName_, const std::string& serviceObjPath_,
+    const std::string& socketObjPath_) :
+    conn(conn_),
+    server(srv_), objPath(objPath_), baseUnitName(baseUnitName_),
+    instanceName(instanceName_), serviceObjectPath(serviceObjPath_),
+    socketObjectPath(socketObjPath_)
+{
+    instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");
+    updatedFlag = 0;
+    queryAndUpdateProperties();
+    return;
+}
+
+std::string ServiceConfig::getSocketUnitName()
+{
+    return instantiatedUnitName + ".socket";
+}
+
+std::string ServiceConfig::getServiceUnitName()
+{
+    return instantiatedUnitName + ".service";
+}
+
+bool ServiceConfig::isMaskedOut()
+{
+    // return true  if state is masked & no request to update the maskedState
+    return (
+        stateValue == "masked" &&
+        !(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::maskedState))));
+}
+
+void ServiceConfig::stopAndApplyUnitConfig(boost::asio::yield_context yield)
+{
+    if (!updatedFlag || isMaskedOut())
+    {
+        // No updates / masked - Just return.
+        return;
+    }
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Applying new settings.",
+        phosphor::logging::entry("OBJPATH=%s", objPath.c_str()));
+    if (subStateValue == "running")
+    {
+        if (!socketObjectPath.empty())
+        {
+            systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);
+        }
+        systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
+    }
+
+    if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))
+    {
+        createSocketOverrideConf();
+        // Create override config file and write data.
+        std::string ovrCfgFile{overrideConfDir + "/" + overrideConfFileName};
+        std::string tmpFile{ovrCfgFile + "_tmp"};
+        std::ofstream cfgFile(tmpFile, std::ios::out);
+        if (!cfgFile.good())
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Failed to open override.conf_tmp file");
+            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
+                                        Error::InternalFailure>();
+        }
+
+        // Write the socket header
+        cfgFile << "[Socket]\n";
+        // Listen
+        cfgFile << "Listen" << protocol << "="
+                << "\n";
+        cfgFile << "Listen" << protocol << "=" << portNum << "\n";
+        cfgFile.close();
+
+        if (std::rename(tmpFile.c_str(), ovrCfgFile.c_str()) != 0)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Failed to rename tmp file as override.conf");
+            std::remove(tmpFile.c_str());
+            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
+                                        Error::InternalFailure>();
+        }
+    }
+
+    if (updatedFlag & ((1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
+                       (1 << static_cast<uint8_t>(UpdatedProp::enabledState))))
+    {
+        std::vector<std::string> unitFiles;
+        if (socketObjectPath.empty())
+        {
+            unitFiles = {getServiceUnitName()};
+        }
+        else
+        {
+            unitFiles = {getSocketUnitName(), getServiceUnitName()};
+        }
+        systemdUnitFilesStateChange(conn, yield, unitFiles, stateValue,
+                                    unitMaskedState, unitEnabledState);
+    }
+    return;
+}
+void ServiceConfig::restartUnitConfig(boost::asio::yield_context yield)
+{
+    if (!updatedFlag || isMaskedOut())
+    {
+        // No updates. Just return.
+        return;
+    }
+
+    if (unitRunningState)
+    {
+        if (!socketObjectPath.empty())
+        {
+            systemdUnitAction(conn, yield, getSocketUnitName(),
+                              sysdRestartUnit);
+        }
+        systemdUnitAction(conn, yield, getServiceUnitName(), sysdRestartUnit);
+    }
+
+    // Reset the flag
+    updatedFlag = 0;
+
+    phosphor::logging::log<phosphor::logging::level::INFO>(
+        "Applied new settings",
+        phosphor::logging::entry("OBJPATH=%s", objPath.c_str()));
+
+    queryAndUpdateProperties();
+    return;
+}
+
+void ServiceConfig::startServiceRestartTimer()
+{
+    timer->expires_after(std::chrono::seconds(restartTimeout));
+    timer->async_wait([this](const boost::system::error_code& ec) {
+        if (ec == boost::asio::error::operation_aborted)
+        {
+            // Timer reset.
+            return;
+        }
+        else if (ec)
+        {
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "async wait error.");
+            return;
+        }
+        updateInProgress = true;
+        boost::asio::spawn(conn->get_io_context(),
+                           [this](boost::asio::yield_context yield) {
+                               // Stop and apply configuration for all objects
+                               for (auto& srvMgrObj : srvMgrObjects)
+                               {
+                                   auto& srvObj = srvMgrObj.second;
+                                   if (srvObj->updatedFlag)
+                                   {
+                                       srvObj->stopAndApplyUnitConfig(yield);
+                                   }
+                               }
+                               // Do system reload
+                               systemdDaemonReload(conn, yield);
+                               // restart unit config.
+                               for (auto& srvMgrObj : srvMgrObjects)
+                               {
+                                   auto& srvObj = srvMgrObj.second;
+                                   if (srvObj->updatedFlag)
+                                   {
+                                       srvObj->restartUnitConfig(yield);
+                                   }
+                               }
+                               updateInProgress = false;
+                           });
+    });
+}
+
+void ServiceConfig::registerProperties()
+{
+    srvCfgIface = server.add_interface(objPath, serviceConfigIntfName);
+
+    if (!socketObjectPath.empty())
+    {
+        sockAttrIface = server.add_interface(objPath, sockAttrIntfName);
+        sockAttrIface->register_property(
+            sockAttrPropPort, portNum,
+            [this](const uint16_t& req, uint16_t& res) {
+                if (!internalSet)
+                {
+                    if (req == res)
+                    {
+                        return 1;
+                    }
+                    if (updateInProgress)
+                    {
+                        return 0;
+                    }
+                    portNum = req;
+                    updatedFlag |=
+                        (1 << static_cast<uint8_t>(UpdatedProp::port));
+                    startServiceRestartTimer();
+                }
+                res = req;
+                return 1;
+            });
+    }
+
+    srvCfgIface->register_property(
+        srvCfgPropMasked, unitMaskedState, [this](const bool& req, bool& res) {
+            if (!internalSet)
+            {
+                if (req == res)
+                {
+                    return 1;
+                }
+                if (updateInProgress)
+                {
+                    return 0;
+                }
+                unitMaskedState = req;
+                unitEnabledState = !unitMaskedState;
+                unitRunningState = !unitMaskedState;
+                updatedFlag |=
+                    (1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
+                    (1 << static_cast<uint8_t>(UpdatedProp::enabledState)) |
+                    (1 << static_cast<uint8_t>(UpdatedProp::runningState));
+                internalSet = true;
+                srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
+                srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
+                internalSet = false;
+                startServiceRestartTimer();
+            }
+            res = req;
+            return 1;
+        });
+
+    srvCfgIface->register_property(
+        srvCfgPropEnabled, unitEnabledState,
+        [this](const bool& req, bool& res) {
+            if (!internalSet)
+            {
+                if (req == res)
+                {
+                    return 1;
+                }
+                if (updateInProgress)
+                {
+                    return 0;
+                }
+                if (unitMaskedState)
+                { // block updating if masked
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Invalid value specified");
+                    return -EINVAL;
+                }
+                unitEnabledState = req;
+                updatedFlag |=
+                    (1 << static_cast<uint8_t>(UpdatedProp::enabledState));
+                startServiceRestartTimer();
+            }
+            res = req;
+            return 1;
+        });
+
+    srvCfgIface->register_property(
+        srvCfgPropRunning, unitRunningState,
+        [this](const bool& req, bool& res) {
+            if (!internalSet)
+            {
+                if (req == res)
+                {
+                    return 1;
+                }
+                if (updateInProgress)
+                {
+                    return 0;
+                }
+                if (unitMaskedState)
+                { // block updating if masked
+                    phosphor::logging::log<phosphor::logging::level::ERR>(
+                        "Invalid value specified");
+                    return -EINVAL;
+                }
+                unitRunningState = req;
+                updatedFlag |=
+                    (1 << static_cast<uint8_t>(UpdatedProp::runningState));
+                startServiceRestartTimer();
+            }
+            res = req;
+            return 1;
+        });
+
+    srvCfgIface->initialize();
+    if (!socketObjectPath.empty())
+    {
+        sockAttrIface->initialize();
+    }
+    return;
+}
+
+} // namespace service
+} // namespace phosphor
diff --git a/src/utils.cpp b/src/utils.cpp
index 775c39e..b4ed9f7 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -1,134 +1,134 @@
-/*

-// Copyright (c) 2018 Intel Corporation

-//

-// Licensed under the Apache License, Version 2.0 (the "License");

-// you may not use this file except in compliance with the License.

-// You may obtain a copy of the License at

-//

-//      http://www.apache.org/licenses/LICENSE-2.0

-//

-// Unless required by applicable law or agreed to in writing, software

-// distributed under the License is distributed on an "AS IS" BASIS,

-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-// See the License for the specific language governing permissions and

-// limitations under the License.

-*/

-#include "utils.hpp"

-

-static inline void checkAndThrowInternalFailure(boost::system::error_code& ec,

-                                                const std::string& msg)

-{

-    if (ec)

-    {

-        std::string msgToLog = ec.message() + (msg.empty() ? "" : " - " + msg);

-        phosphor::logging::log<phosphor::logging::level::ERR>(msgToLog.c_str());

-        phosphor::logging::elog<

-            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();

-    }

-    return;

-}

-

-void systemdDaemonReload(

-    const std::shared_ptr<sdbusplus::asio::connection>& conn,

-    boost::asio::yield_context yield)

-{

-    boost::system::error_code ec;

-    conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath, sysdMgrIntf,

-                              sysdReloadMethod);

-    checkAndThrowInternalFailure(ec, "daemon-reload operation failed");

-    return;

-}

-

-static inline uint32_t getJobId(const std::string& path)

-{

-    auto pos = path.rfind("/");

-    if (pos == std::string::npos)

-    {

-        phosphor::logging::log<phosphor::logging::level::ERR>(

-            "Unable to get job id from job path");

-        phosphor::logging::elog<

-            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();

-    }

-    return static_cast<uint32_t>(std::stoul(path.substr(pos + 1)));

-}

-

-void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,

-                       boost::asio::yield_context yield,

-                       const std::string& unitName,

-                       const std::string& actionMethod)

-{

-    boost::system::error_code ec;

-    auto jobPath = conn->yield_method_call<sdbusplus::message::object_path>(

-        yield, ec, sysdService, sysdObjPath, sysdMgrIntf, actionMethod,

-        unitName, sysdReplaceMode);

-    checkAndThrowInternalFailure(ec,

-                                 "Systemd operation failed, " + actionMethod);

-    // Query the job till it doesn't exist anymore.

-    // this way we guarantee that queued job id is done.

-    // this is needed to make sure dependency list on units are

-    // properly handled.

-    while (1)

-    {

-        ec.clear();

-        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,

-                                  sysdMgrIntf, sysdGetJobMethod,

-                                  getJobId(jobPath.str));

-        if (ec)

-        {

-            if (ec.value() == boost::system::errc::no_such_file_or_directory)

-            {

-                // Queued job is done, return now

-                return;

-            }

-            phosphor::logging::log<phosphor::logging::level::ERR>(

-                "Systemd operation failed for job query");

-            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::

-                                        Error::InternalFailure>();

-        }

-        boost::asio::steady_timer sleepTimer(conn->get_io_context());

-        sleepTimer.expires_after(std::chrono::milliseconds(20));

-        ec.clear();

-        sleepTimer.async_wait(yield[ec]);

-        checkAndThrowInternalFailure(ec, "Systemd operation timer error");

-    }

-    return;

-}

-

-void systemdUnitFilesStateChange(

-    const std::shared_ptr<sdbusplus::asio::connection>& conn,

-    boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,

-    const std::string& unitState, bool maskedState, bool enabledState)

-{

-    boost::system::error_code ec;

-

-    if (unitState == stateMasked && !maskedState)

-    {

-        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,

-                                  sysdMgrIntf, "UnmaskUnitFiles", unitFiles,

-                                  false);

-        checkAndThrowInternalFailure(ec, "Systemd UnmaskUnitFiles() failed.");

-    }

-    else if (unitState != stateMasked && maskedState)

-    {

-        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,

-                                  sysdMgrIntf, "MaskUnitFiles", unitFiles,

-                                  false, false);

-        checkAndThrowInternalFailure(ec, "Systemd MaskUnitFiles() failed.");

-    }

-    ec.clear();

-    if (unitState != stateEnabled && enabledState)

-    {

-        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,

-                                  sysdMgrIntf, "EnableUnitFiles", unitFiles,

-                                  false, false);

-        checkAndThrowInternalFailure(ec, "Systemd EnableUnitFiles() failed.");

-    }

-    else if (unitState != stateDisabled && !enabledState)

-    {

-        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,

-                                  sysdMgrIntf, "DisableUnitFiles", unitFiles,

-                                  false);

-        checkAndThrowInternalFailure(ec, "Systemd DisableUnitFiles() failed.");

-    }

-    return;

-}

+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#include "utils.hpp"
+
+static inline void checkAndThrowInternalFailure(boost::system::error_code& ec,
+                                                const std::string& msg)
+{
+    if (ec)
+    {
+        std::string msgToLog = ec.message() + (msg.empty() ? "" : " - " + msg);
+        phosphor::logging::log<phosphor::logging::level::ERR>(msgToLog.c_str());
+        phosphor::logging::elog<
+            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
+    }
+    return;
+}
+
+void systemdDaemonReload(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::yield_context yield)
+{
+    boost::system::error_code ec;
+    conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
+                              sysdReloadMethod);
+    checkAndThrowInternalFailure(ec, "daemon-reload operation failed");
+    return;
+}
+
+static inline uint32_t getJobId(const std::string& path)
+{
+    auto pos = path.rfind("/");
+    if (pos == std::string::npos)
+    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Unable to get job id from job path");
+        phosphor::logging::elog<
+            sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
+    }
+    return static_cast<uint32_t>(std::stoul(path.substr(pos + 1)));
+}
+
+void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,
+                       boost::asio::yield_context yield,
+                       const std::string& unitName,
+                       const std::string& actionMethod)
+{
+    boost::system::error_code ec;
+    auto jobPath = conn->yield_method_call<sdbusplus::message::object_path>(
+        yield, ec, sysdService, sysdObjPath, sysdMgrIntf, actionMethod,
+        unitName, sysdReplaceMode);
+    checkAndThrowInternalFailure(ec,
+                                 "Systemd operation failed, " + actionMethod);
+    // Query the job till it doesn't exist anymore.
+    // this way we guarantee that queued job id is done.
+    // this is needed to make sure dependency list on units are
+    // properly handled.
+    while (1)
+    {
+        ec.clear();
+        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
+                                  sysdMgrIntf, sysdGetJobMethod,
+                                  getJobId(jobPath.str));
+        if (ec)
+        {
+            if (ec.value() == boost::system::errc::no_such_file_or_directory)
+            {
+                // Queued job is done, return now
+                return;
+            }
+            phosphor::logging::log<phosphor::logging::level::ERR>(
+                "Systemd operation failed for job query");
+            phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
+                                        Error::InternalFailure>();
+        }
+        boost::asio::steady_timer sleepTimer(conn->get_io_context());
+        sleepTimer.expires_after(std::chrono::milliseconds(20));
+        ec.clear();
+        sleepTimer.async_wait(yield[ec]);
+        checkAndThrowInternalFailure(ec, "Systemd operation timer error");
+    }
+    return;
+}
+
+void systemdUnitFilesStateChange(
+    const std::shared_ptr<sdbusplus::asio::connection>& conn,
+    boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,
+    const std::string& unitState, bool maskedState, bool enabledState)
+{
+    boost::system::error_code ec;
+
+    if (unitState == stateMasked && !maskedState)
+    {
+        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
+                                  sysdMgrIntf, "UnmaskUnitFiles", unitFiles,
+                                  false);
+        checkAndThrowInternalFailure(ec, "Systemd UnmaskUnitFiles() failed.");
+    }
+    else if (unitState != stateMasked && maskedState)
+    {
+        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
+                                  sysdMgrIntf, "MaskUnitFiles", unitFiles,
+                                  false, false);
+        checkAndThrowInternalFailure(ec, "Systemd MaskUnitFiles() failed.");
+    }
+    ec.clear();
+    if (unitState != stateEnabled && enabledState)
+    {
+        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
+                                  sysdMgrIntf, "EnableUnitFiles", unitFiles,
+                                  false, false);
+        checkAndThrowInternalFailure(ec, "Systemd EnableUnitFiles() failed.");
+    }
+    else if (unitState != stateDisabled && !enabledState)
+    {
+        conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
+                                  sysdMgrIntf, "DisableUnitFiles", unitFiles,
+                                  false);
+        checkAndThrowInternalFailure(ec, "Systemd DisableUnitFiles() failed.");
+    }
+    return;
+}