srvcfg-manager State change issue fix.

srvcfg-manager State change is not working as
it need to act on both .service and .socket files.
Also used MaskUnitFiles and UnmaskUnitFiles to
make changes persistent.

Tested By:
 Disabled/Enabled the state and checked  the service
 is stopping/starting properly. Also rebooted system
 and checked persistent behaviour. Checked changing
 port/channel and validated functionality.

Change-Id: Ib0dce95db3926f5d700fb729aae7bdac1caf64e4
Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com>
diff --git a/src/srvcfg_manager.cpp b/src/srvcfg_manager.cpp
index 04d41ca..333c001 100644
--- a/src/srvcfg_manager.cpp
+++ b/src/srvcfg_manager.cpp
@@ -126,6 +126,7 @@
     std::string srvUnitName(sysDUnitName);

     if (srvUnitName == "dropbear")

     {

+        // Dropbear service expects template arguments.

         srvUnitName.append("@");

     }

     srvUnitName.append(".service");

@@ -137,7 +138,15 @@
                     "async_method_call error: Failed to get property");

                 return;

             }

-            stateValue = pValue;

+            if ((pValue == "enabled") || (pValue == "static") ||

+                (pValue == "unmasked"))

+            {

+                stateValue = "enabled";

+            }

+            else if ((pValue == "disabled") || (pValue == "masked"))

+            {

+                stateValue = "disabled";

+            }

             conn->async_method_call(

                 [](boost::system::error_code ec) {

                     if (ec)

@@ -212,6 +221,12 @@
 

 void ServiceConfig::applySystemDServiceConfig()

 {

+    if (updatedFlag)

+    {

+        // No updates. Just return.

+        return;

+    }

+

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

         "Applying new settings.",

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

@@ -261,28 +276,46 @@
             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::

                                         Error::InternalFailure>();

         }

+    }

 

-        // Systemd forcing explicit socket stop before reload...!

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

-        systemdUnitAction(conn, socketUnitName, sysdActionStopUnit);

-

-        std::string srvUnitName(sysDUnitName + ".service");

-        systemdUnitAction(conn, srvUnitName, sysdActionStopUnit);

-

-        // Perform daemon reload to read new settings

-        systemdDaemonReload(conn);

-

-        // Restart the unit

-        systemdUnitAction(conn, socketUnitName, sysdActionStartUnit);

-        systemdUnitAction(conn, srvUnitName, sysdActionStartUnit);

+    std::string socketUnitName(sysDUnitName + ".socket");

+    std::string srvUnitName(sysDUnitName);

+    if (srvUnitName == "dropbear")

+    {

+        // Dropbear service expects template arguments.

+        // Todo: Unit action for service, fails with error

+        // "missing the instance name". Needs to implement

+        // getting all running instances and use it. This

+        // impact runtime but works fine during reboot.

+        srvUnitName.append("@");

+    }

+    srvUnitName.append(".service");

+    // Stop the running service in below scenarios.

+    // 1. State changed from "enabled" to "disabled"

+    // 2. No change in state and existing stateValue is

+    //    "enabled" and there is change in other properties.

+    if (((stateValue == "disabled") &&

+         (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::state)))) ||

+        (!(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::state))) &&

+         (stateValue == "enabled") && (updatedFlag)))

+    {

+        systemdUnitAction(conn, socketUnitName, "StopUnit");

+        systemdUnitAction(conn, srvUnitName, "StopUnit");

     }

 

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

     {

-        if ((stateValue == "enabled") || (stateValue == "disabled"))

-        {

-            systemdUnitFileStateChange(conn, sysDUnitName, stateValue);

-        }

+        std::vector<std::string> unitFiles = {socketUnitName, srvUnitName};

+        systemdUnitFilesStateChange(conn, unitFiles, stateValue);

+    }

+

+    // Perform daemon reload to read new settings

+    systemdDaemonReload(conn);

+

+    if (stateValue == "enabled")

+    {

+        // Restart the socket

+        systemdUnitAction(conn, socketUnitName, "StartUnit");

     }

 

     // Reset the flag

@@ -290,8 +323,8 @@
 

     // All done. Lets reload the properties which are applied on systemd1.

     // TODO: We need to capture the service restart signal and reload data

-    // inside the signal handler. So that we can update the service properties

-    // modified, outside of this service as well.

+    // inside the signal handler. So that we can update the service

+    // properties modified, outside of this service as well.

     syncWithSystemD1Properties();

 

     return;

@@ -330,8 +363,6 @@
 

     iface->register_property(

         "Port", portNum, [this](const uint16_t &req, uint16_t &res) {

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

-                " Inside register_property");

             if (req == res)

             {

                 return 1;

@@ -366,7 +397,7 @@
             {

                 return 1;

             }

-            if ((req != "enabled") && (req != "disabled") && (req != "static"))

+            if ((req != "enabled") && (req != "disabled"))

             {

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

                     "Invalid value specified");