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");