xref: /openbmc/service-config-manager/src/srvcfg_manager.cpp (revision f27f431faa0c40c0253e50cddd92ffcb99081604)
10084047dSAppaRao Puli /*
20084047dSAppaRao Puli // Copyright (c) 2018 Intel Corporation
30084047dSAppaRao Puli //
40084047dSAppaRao Puli // Licensed under the Apache License, Version 2.0 (the "License");
50084047dSAppaRao Puli // you may not use this file except in compliance with the License.
60084047dSAppaRao Puli // You may obtain a copy of the License at
70084047dSAppaRao Puli //
80084047dSAppaRao Puli //      http://www.apache.org/licenses/LICENSE-2.0
90084047dSAppaRao Puli //
100084047dSAppaRao Puli // Unless required by applicable law or agreed to in writing, software
110084047dSAppaRao Puli // distributed under the License is distributed on an "AS IS" BASIS,
120084047dSAppaRao Puli // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130084047dSAppaRao Puli // See the License for the specific language governing permissions and
140084047dSAppaRao Puli // limitations under the License.
150084047dSAppaRao Puli */
16ee853eb2SAppaRao Puli #include "srvcfg_manager.hpp"
17ee853eb2SAppaRao Puli 
18ee853eb2SAppaRao Puli #include <boost/asio/spawn.hpp>
19ee853eb2SAppaRao Puli 
2025a0f634SChicago Duan #ifdef USB_CODE_UPDATE
2125a0f634SChicago Duan #include <cereal/archives/json.hpp>
2225a0f634SChicago Duan #include <cereal/types/tuple.hpp>
2325a0f634SChicago Duan #include <cereal/types/unordered_map.hpp>
2425a0f634SChicago Duan 
2525a0f634SChicago Duan #include <cstdio>
2625a0f634SChicago Duan #endif
2725a0f634SChicago Duan 
280084047dSAppaRao Puli #include <fstream>
290084047dSAppaRao Puli #include <regex>
300084047dSAppaRao Puli 
3133816cf9SRichard Marian Thomaiyar extern std::unique_ptr<boost::asio::steady_timer> timer;
320084047dSAppaRao Puli extern std::map<std::string, std::shared_ptr<phosphor::service::ServiceConfig>>
330084047dSAppaRao Puli     srvMgrObjects;
3490f2da3fSRichard Marian Thomaiyar static bool updateInProgress = false;
350084047dSAppaRao Puli 
360084047dSAppaRao Puli namespace phosphor
370084047dSAppaRao Puli {
380084047dSAppaRao Puli namespace service
390084047dSAppaRao Puli {
400084047dSAppaRao Puli 
410084047dSAppaRao Puli static constexpr const char* overrideConfFileName = "override.conf";
420084047dSAppaRao Puli static constexpr const size_t restartTimeout = 15; // seconds
430084047dSAppaRao Puli 
440084047dSAppaRao Puli static constexpr const char* systemd1UnitBasePath =
450084047dSAppaRao Puli     "/org/freedesktop/systemd1/unit/";
460084047dSAppaRao Puli static constexpr const char* systemdOverrideUnitBasePath =
470084047dSAppaRao Puli     "/etc/systemd/system/";
480084047dSAppaRao Puli 
4925a0f634SChicago Duan #ifdef USB_CODE_UPDATE
5025a0f634SChicago Duan static constexpr const char* usbCodeUpdateStateFilePath =
5125a0f634SChicago Duan     "/var/lib/srvcfg_manager";
5225a0f634SChicago Duan static constexpr const char* usbCodeUpdateStateFile =
5325a0f634SChicago Duan     "/var/lib/srvcfg_manager/usb-code-update-state";
5425a0f634SChicago Duan static constexpr const char* emptyUsbCodeUpdateRulesFile =
5525a0f634SChicago Duan     "/etc/udev/rules.d/70-bmc-usb.rules";
5625a0f634SChicago Duan static constexpr const char* usbCodeUpdateObjectPath =
5725a0f634SChicago Duan     "/xyz/openbmc_project/control/service/phosphor_2dusb_2dcode_2dupdate";
5825a0f634SChicago Duan 
5925a0f634SChicago Duan using UsbCodeUpdateStateMap = std::unordered_map<std::string, bool>;
6025a0f634SChicago Duan 
6125a0f634SChicago Duan void ServiceConfig::setUSBCodeUpdateState(const bool& state)
6225a0f634SChicago Duan {
6325a0f634SChicago Duan     // Enable usb code update
6425a0f634SChicago Duan     if (state)
6525a0f634SChicago Duan     {
6625a0f634SChicago Duan         if (std::filesystem::exists(emptyUsbCodeUpdateRulesFile))
6725a0f634SChicago Duan         {
68*f27f431fSJiaqing Zhao             lg2::info("Enable usb code update");
6925a0f634SChicago Duan             std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
7025a0f634SChicago Duan         }
7125a0f634SChicago Duan         return;
7225a0f634SChicago Duan     }
7325a0f634SChicago Duan 
7425a0f634SChicago Duan     // Disable usb code update
7525a0f634SChicago Duan     if (std::filesystem::exists(emptyUsbCodeUpdateRulesFile))
7625a0f634SChicago Duan     {
7725a0f634SChicago Duan         std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
7825a0f634SChicago Duan     }
7925a0f634SChicago Duan     std::error_code ec;
8025a0f634SChicago Duan     std::filesystem::create_symlink("/dev/null", emptyUsbCodeUpdateRulesFile,
8125a0f634SChicago Duan                                     ec);
8225a0f634SChicago Duan     if (ec)
8325a0f634SChicago Duan     {
84*f27f431fSJiaqing Zhao         lg2::error("Disable usb code update failed");
8525a0f634SChicago Duan         return;
8625a0f634SChicago Duan     }
87*f27f431fSJiaqing Zhao     lg2::info("Disable usb code update");
8825a0f634SChicago Duan }
8925a0f634SChicago Duan 
9025a0f634SChicago Duan void ServiceConfig::saveUSBCodeUpdateStateToFile(const bool& maskedState,
9125a0f634SChicago Duan                                                  const bool& enabledState)
9225a0f634SChicago Duan {
9325a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFilePath))
9425a0f634SChicago Duan     {
9525a0f634SChicago Duan         std::filesystem::create_directories(usbCodeUpdateStateFilePath);
9625a0f634SChicago Duan     }
9725a0f634SChicago Duan 
9825a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
9925a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropMasked] = maskedState;
10025a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropEnabled] = enabledState;
10125a0f634SChicago Duan 
10225a0f634SChicago Duan     std::ofstream file(usbCodeUpdateStateFile, std::ios::out);
10325a0f634SChicago Duan     cereal::JSONOutputArchive archive(file);
10425a0f634SChicago Duan     archive(CEREAL_NVP(usbCodeUpdateState));
10525a0f634SChicago Duan }
10625a0f634SChicago Duan 
10725a0f634SChicago Duan void ServiceConfig::getUSBCodeUpdateStateFromFile()
10825a0f634SChicago Duan {
10925a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFile))
11025a0f634SChicago Duan     {
111*f27f431fSJiaqing Zhao         lg2::info("usb-code-update-state file does not exist");
11225a0f634SChicago Duan 
11325a0f634SChicago Duan         unitMaskedState = false;
11425a0f634SChicago Duan         unitEnabledState = true;
11525a0f634SChicago Duan         unitRunningState = true;
11625a0f634SChicago Duan         setUSBCodeUpdateState(unitEnabledState);
11725a0f634SChicago Duan         return;
11825a0f634SChicago Duan     }
11925a0f634SChicago Duan 
12025a0f634SChicago Duan     std::ifstream file(usbCodeUpdateStateFile);
12125a0f634SChicago Duan     cereal::JSONInputArchive archive(file);
12225a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
12325a0f634SChicago Duan     archive(usbCodeUpdateState);
12425a0f634SChicago Duan 
12525a0f634SChicago Duan     auto iterMask = usbCodeUpdateState.find(srvCfgPropMasked);
12625a0f634SChicago Duan     if (iterMask != usbCodeUpdateState.end())
12725a0f634SChicago Duan     {
12825a0f634SChicago Duan         unitMaskedState = iterMask->second;
12925a0f634SChicago Duan         if (unitMaskedState)
13025a0f634SChicago Duan         {
13125a0f634SChicago Duan             unitEnabledState = !unitMaskedState;
13225a0f634SChicago Duan             unitRunningState = !unitMaskedState;
13325a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
13425a0f634SChicago Duan             return;
13525a0f634SChicago Duan         }
13625a0f634SChicago Duan 
13725a0f634SChicago Duan         auto iterEnable = usbCodeUpdateState.find(srvCfgPropEnabled);
13825a0f634SChicago Duan         if (iterEnable != usbCodeUpdateState.end())
13925a0f634SChicago Duan         {
14025a0f634SChicago Duan             unitEnabledState = iterEnable->second;
14125a0f634SChicago Duan             unitRunningState = iterEnable->second;
14225a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
14325a0f634SChicago Duan         }
14425a0f634SChicago Duan     }
14525a0f634SChicago Duan }
14625a0f634SChicago Duan #endif
14725a0f634SChicago Duan 
14890f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateSocketProperties(
14990f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
1500084047dSAppaRao Puli {
15190f2da3fSRichard Marian Thomaiyar     auto listenIt = propertyMap.find("Listen");
15290f2da3fSRichard Marian Thomaiyar     if (listenIt != propertyMap.end())
1530084047dSAppaRao Puli     {
15490f2da3fSRichard Marian Thomaiyar         auto listenVal =
15590f2da3fSRichard Marian Thomaiyar             std::get<std::vector<std::tuple<std::string, std::string>>>(
15690f2da3fSRichard Marian Thomaiyar                 listenIt->second);
15790f2da3fSRichard Marian Thomaiyar         if (listenVal.size())
1580084047dSAppaRao Puli         {
1590084047dSAppaRao Puli             protocol = std::get<0>(listenVal[0]);
1600084047dSAppaRao Puli             std::string port = std::get<1>(listenVal[0]);
1610084047dSAppaRao Puli             auto tmp = std::stoul(port.substr(port.find_last_of(":") + 1),
1620084047dSAppaRao Puli                                   nullptr, 10);
1630084047dSAppaRao Puli             if (tmp > std::numeric_limits<uint16_t>::max())
1640084047dSAppaRao Puli             {
1650084047dSAppaRao Puli                 throw std::out_of_range("Out of range");
1660084047dSAppaRao Puli             }
1670084047dSAppaRao Puli             portNum = tmp;
16883241c09STom Joseph             if (sockAttrIface && sockAttrIface->is_initialized())
16990f2da3fSRichard Marian Thomaiyar             {
17090f2da3fSRichard Marian Thomaiyar                 internalSet = true;
17183241c09STom Joseph                 sockAttrIface->set_property(sockAttrPropPort, portNum);
17290f2da3fSRichard Marian Thomaiyar                 internalSet = false;
17390f2da3fSRichard Marian Thomaiyar             }
17490f2da3fSRichard Marian Thomaiyar         }
17590f2da3fSRichard Marian Thomaiyar     }
17690f2da3fSRichard Marian Thomaiyar }
17790f2da3fSRichard Marian Thomaiyar 
17890f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateServiceProperties(
17990f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
18090f2da3fSRichard Marian Thomaiyar {
18190f2da3fSRichard Marian Thomaiyar     auto stateIt = propertyMap.find("UnitFileState");
18290f2da3fSRichard Marian Thomaiyar     if (stateIt != propertyMap.end())
18390f2da3fSRichard Marian Thomaiyar     {
18490f2da3fSRichard Marian Thomaiyar         stateValue = std::get<std::string>(stateIt->second);
18590f2da3fSRichard Marian Thomaiyar         unitEnabledState = unitMaskedState = false;
18690f2da3fSRichard Marian Thomaiyar         if (stateValue == stateMasked)
18790f2da3fSRichard Marian Thomaiyar         {
18890f2da3fSRichard Marian Thomaiyar             unitMaskedState = true;
18990f2da3fSRichard Marian Thomaiyar         }
19090f2da3fSRichard Marian Thomaiyar         else if (stateValue == stateEnabled)
19190f2da3fSRichard Marian Thomaiyar         {
19290f2da3fSRichard Marian Thomaiyar             unitEnabledState = true;
19390f2da3fSRichard Marian Thomaiyar         }
19483241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
19590f2da3fSRichard Marian Thomaiyar         {
19690f2da3fSRichard Marian Thomaiyar             internalSet = true;
19783241c09STom Joseph             srvCfgIface->set_property(srvCfgPropMasked, unitMaskedState);
19883241c09STom Joseph             srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
19990f2da3fSRichard Marian Thomaiyar             internalSet = false;
20090f2da3fSRichard Marian Thomaiyar         }
20190f2da3fSRichard Marian Thomaiyar     }
20290f2da3fSRichard Marian Thomaiyar     auto subStateIt = propertyMap.find("SubState");
20390f2da3fSRichard Marian Thomaiyar     if (subStateIt != propertyMap.end())
20490f2da3fSRichard Marian Thomaiyar     {
20590f2da3fSRichard Marian Thomaiyar         subStateValue = std::get<std::string>(subStateIt->second);
206a19b5093SGeorge Liu         if (subStateValue == subStateRunning ||
207a19b5093SGeorge Liu             subStateValue == subStateListening)
20890f2da3fSRichard Marian Thomaiyar         {
20990f2da3fSRichard Marian Thomaiyar             unitRunningState = true;
21090f2da3fSRichard Marian Thomaiyar         }
21183241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
21290f2da3fSRichard Marian Thomaiyar         {
21390f2da3fSRichard Marian Thomaiyar             internalSet = true;
21483241c09STom Joseph             srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
21590f2da3fSRichard Marian Thomaiyar             internalSet = false;
21690f2da3fSRichard Marian Thomaiyar         }
21790f2da3fSRichard Marian Thomaiyar     }
21825a0f634SChicago Duan 
21925a0f634SChicago Duan #ifdef USB_CODE_UPDATE
22025a0f634SChicago Duan     if (objPath == usbCodeUpdateObjectPath)
22125a0f634SChicago Duan     {
22225a0f634SChicago Duan         getUSBCodeUpdateStateFromFile();
22325a0f634SChicago Duan     }
22425a0f634SChicago Duan #endif
22590f2da3fSRichard Marian Thomaiyar }
22690f2da3fSRichard Marian Thomaiyar 
22790f2da3fSRichard Marian Thomaiyar void ServiceConfig::queryAndUpdateProperties()
22890f2da3fSRichard Marian Thomaiyar {
229a19b5093SGeorge Liu     std::string objectPath =
230f476683cSJiaqing Zhao         isSocketActivatedService ? socketObjectPath : serviceObjectPath;
231a19b5093SGeorge Liu     if (objectPath.empty())
232a19b5093SGeorge Liu     {
233a19b5093SGeorge Liu         return;
234a19b5093SGeorge Liu     }
235a19b5093SGeorge Liu 
23690f2da3fSRichard Marian Thomaiyar     conn->async_method_call(
23790f2da3fSRichard Marian Thomaiyar         [this](boost::system::error_code ec,
238ee853eb2SAppaRao Puli                const boost::container::flat_map<std::string, VariantType>&
239ee853eb2SAppaRao Puli                    propertyMap) {
24090f2da3fSRichard Marian Thomaiyar             if (ec)
24190f2da3fSRichard Marian Thomaiyar             {
242cb267c8fSGeorge Liu                 lg2::error(
243cb267c8fSGeorge Liu                     "async_method_call error: Failed to service unit properties: {EC}",
244cb267c8fSGeorge Liu                     "EC", ec.value());
24590f2da3fSRichard Marian Thomaiyar                 return;
24690f2da3fSRichard Marian Thomaiyar             }
24790f2da3fSRichard Marian Thomaiyar             try
24890f2da3fSRichard Marian Thomaiyar             {
24990f2da3fSRichard Marian Thomaiyar                 updateServiceProperties(propertyMap);
25090f2da3fSRichard Marian Thomaiyar                 if (!socketObjectPath.empty())
25190f2da3fSRichard Marian Thomaiyar                 {
25290f2da3fSRichard Marian Thomaiyar                     conn->async_method_call(
25390f2da3fSRichard Marian Thomaiyar                         [this](boost::system::error_code ec,
25490f2da3fSRichard Marian Thomaiyar                                const boost::container::flat_map<
25590f2da3fSRichard Marian Thomaiyar                                    std::string, VariantType>& propertyMap) {
25690f2da3fSRichard Marian Thomaiyar                             if (ec)
25790f2da3fSRichard Marian Thomaiyar                             {
258cb267c8fSGeorge Liu                                 lg2::error(
259cb267c8fSGeorge Liu                                     "async_method_call error: Failed to get all property: {EC}",
260cb267c8fSGeorge Liu                                     "EC", ec.value());
26190f2da3fSRichard Marian Thomaiyar                                 return;
26290f2da3fSRichard Marian Thomaiyar                             }
26390f2da3fSRichard Marian Thomaiyar                             try
26490f2da3fSRichard Marian Thomaiyar                             {
26590f2da3fSRichard Marian Thomaiyar                                 updateSocketProperties(propertyMap);
26683241c09STom Joseph                                 if (!srvCfgIface)
26790f2da3fSRichard Marian Thomaiyar                                 {
26890f2da3fSRichard Marian Thomaiyar                                     registerProperties();
26990f2da3fSRichard Marian Thomaiyar                                 }
27090f2da3fSRichard Marian Thomaiyar                             }
27190f2da3fSRichard Marian Thomaiyar                             catch (const std::exception& e)
27290f2da3fSRichard Marian Thomaiyar                             {
273cb267c8fSGeorge Liu                                 lg2::error(
274cb267c8fSGeorge Liu                                     "Exception in getting socket properties: {ERROR}",
275cb267c8fSGeorge Liu                                     "ERROR", e);
27690f2da3fSRichard Marian Thomaiyar                                 return;
27790f2da3fSRichard Marian Thomaiyar                             }
27890f2da3fSRichard Marian Thomaiyar                         },
27990f2da3fSRichard Marian Thomaiyar                         sysdService, socketObjectPath, dBusPropIntf,
28090f2da3fSRichard Marian Thomaiyar                         dBusGetAllMethod, sysdSocketIntf);
28190f2da3fSRichard Marian Thomaiyar                 }
28283241c09STom Joseph                 else if (!srvCfgIface)
28390f2da3fSRichard Marian Thomaiyar                 {
28490f2da3fSRichard Marian Thomaiyar                     registerProperties();
28590f2da3fSRichard Marian Thomaiyar                 }
2860084047dSAppaRao Puli             }
2870084047dSAppaRao Puli             catch (const std::exception& e)
2880084047dSAppaRao Puli             {
289cb267c8fSGeorge Liu                 lg2::error("Exception in getting socket properties: {ERROR}",
290cb267c8fSGeorge Liu                            "ERROR", e);
2910084047dSAppaRao Puli                 return;
2920084047dSAppaRao Puli             }
2930084047dSAppaRao Puli         },
294a19b5093SGeorge Liu         sysdService, objectPath, dBusPropIntf, dBusGetAllMethod, sysdUnitIntf);
2950084047dSAppaRao Puli     return;
2960084047dSAppaRao Puli }
2970084047dSAppaRao Puli 
29890f2da3fSRichard Marian Thomaiyar void ServiceConfig::createSocketOverrideConf()
2990084047dSAppaRao Puli {
30090f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
3010084047dSAppaRao Puli     {
30290f2da3fSRichard Marian Thomaiyar         std::string socketUnitName(instantiatedUnitName + ".socket");
3030084047dSAppaRao Puli         /// Check override socket directory exist, if not create it.
30482e9557eSTom Joseph         std::filesystem::path ovrUnitFileDir(systemdOverrideUnitBasePath);
3050084047dSAppaRao Puli         ovrUnitFileDir += socketUnitName;
3060084047dSAppaRao Puli         ovrUnitFileDir += ".d";
30782e9557eSTom Joseph         if (!std::filesystem::exists(ovrUnitFileDir))
3080084047dSAppaRao Puli         {
30982e9557eSTom Joseph             if (!std::filesystem::create_directories(ovrUnitFileDir))
3100084047dSAppaRao Puli             {
311cb267c8fSGeorge Liu                 lg2::error("Unable to create the {DIR} directory.", "DIR",
312cb267c8fSGeorge Liu                            ovrUnitFileDir);
31390f2da3fSRichard Marian Thomaiyar                 phosphor::logging::elog<sdbusplus::xyz::openbmc_project::
31490f2da3fSRichard Marian Thomaiyar                                             Common::Error::InternalFailure>();
31590f2da3fSRichard Marian Thomaiyar             }
31690f2da3fSRichard Marian Thomaiyar         }
31790f2da3fSRichard Marian Thomaiyar         overrideConfDir = std::string(ovrUnitFileDir);
3180084047dSAppaRao Puli     }
3190084047dSAppaRao Puli }
3200084047dSAppaRao Puli 
32190f2da3fSRichard Marian Thomaiyar ServiceConfig::ServiceConfig(
32290f2da3fSRichard Marian Thomaiyar     sdbusplus::asio::object_server& srv_,
32390f2da3fSRichard Marian Thomaiyar     std::shared_ptr<sdbusplus::asio::connection>& conn_,
32490f2da3fSRichard Marian Thomaiyar     const std::string& objPath_, const std::string& baseUnitName_,
32590f2da3fSRichard Marian Thomaiyar     const std::string& instanceName_, const std::string& serviceObjPath_,
32690f2da3fSRichard Marian Thomaiyar     const std::string& socketObjPath_) :
32782e9557eSTom Joseph     conn(conn_),
32882e9557eSTom Joseph     server(srv_), objPath(objPath_), baseUnitName(baseUnitName_),
32990f2da3fSRichard Marian Thomaiyar     instanceName(instanceName_), serviceObjectPath(serviceObjPath_),
33090f2da3fSRichard Marian Thomaiyar     socketObjectPath(socketObjPath_)
33190f2da3fSRichard Marian Thomaiyar {
332f476683cSJiaqing Zhao     isSocketActivatedService = serviceObjectPath.empty();
33390f2da3fSRichard Marian Thomaiyar     instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");
3340084047dSAppaRao Puli     updatedFlag = 0;
33590f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
3360084047dSAppaRao Puli     return;
3370084047dSAppaRao Puli }
3380084047dSAppaRao Puli 
33990f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getSocketUnitName()
3400084047dSAppaRao Puli {
34190f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".socket";
342e55cfd6eSAppaRao Puli }
343e55cfd6eSAppaRao Puli 
34490f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getServiceUnitName()
34590f2da3fSRichard Marian Thomaiyar {
34690f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".service";
34790f2da3fSRichard Marian Thomaiyar }
34890f2da3fSRichard Marian Thomaiyar 
34990f2da3fSRichard Marian Thomaiyar bool ServiceConfig::isMaskedOut()
35090f2da3fSRichard Marian Thomaiyar {
35190f2da3fSRichard Marian Thomaiyar     // return true  if state is masked & no request to update the maskedState
35290f2da3fSRichard Marian Thomaiyar     return (
35390f2da3fSRichard Marian Thomaiyar         stateValue == "masked" &&
35490f2da3fSRichard Marian Thomaiyar         !(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::maskedState))));
35590f2da3fSRichard Marian Thomaiyar }
35690f2da3fSRichard Marian Thomaiyar 
35790f2da3fSRichard Marian Thomaiyar void ServiceConfig::stopAndApplyUnitConfig(boost::asio::yield_context yield)
35890f2da3fSRichard Marian Thomaiyar {
35990f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
36090f2da3fSRichard Marian Thomaiyar     {
36190f2da3fSRichard Marian Thomaiyar         // No updates / masked - Just return.
36290f2da3fSRichard Marian Thomaiyar         return;
36390f2da3fSRichard Marian Thomaiyar     }
364cb267c8fSGeorge Liu     lg2::info("Applying new settings: {OBJPATH}", "OBJPATH", objPath);
365a19b5093SGeorge Liu     if (subStateValue == subStateRunning || subStateValue == subStateListening)
3660084047dSAppaRao Puli     {
36790f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
36890f2da3fSRichard Marian Thomaiyar         {
36990f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);
37090f2da3fSRichard Marian Thomaiyar         }
371f476683cSJiaqing Zhao         if (!isSocketActivatedService)
372a19b5093SGeorge Liu         {
37390f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
37490f2da3fSRichard Marian Thomaiyar         }
375a19b5093SGeorge Liu         else
376a19b5093SGeorge Liu         {
377f476683cSJiaqing Zhao             // For socket-activated service, each connection will spawn a
378f476683cSJiaqing Zhao             // service instance from template. Need to find all spawned service
379f476683cSJiaqing Zhao             // `<unitName>@<attribute>.service` and stop them through the
380f476683cSJiaqing Zhao             // systemdUnitAction method
381a19b5093SGeorge Liu             boost::system::error_code ec;
382a19b5093SGeorge Liu             auto listUnits =
383a19b5093SGeorge Liu                 conn->yield_method_call<std::vector<ListUnitsType>>(
384a19b5093SGeorge Liu                     yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
385a19b5093SGeorge Liu                     "ListUnits");
386a19b5093SGeorge Liu 
387a19b5093SGeorge Liu             checkAndThrowInternalFailure(
388a19b5093SGeorge Liu                 ec, "yield_method_call error: ListUnits failed");
389a19b5093SGeorge Liu 
390a19b5093SGeorge Liu             for (const auto& unit : listUnits)
391a19b5093SGeorge Liu             {
392a19b5093SGeorge Liu                 const auto& service =
393a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::name)>(unit);
394a19b5093SGeorge Liu                 const auto& status =
395a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::subState)>(
396a19b5093SGeorge Liu                         unit);
397f476683cSJiaqing Zhao                 if (service.find(baseUnitName + "@") != std::string::npos &&
398a19b5093SGeorge Liu                     service.find(".service") != std::string::npos &&
399a19b5093SGeorge Liu                     status == subStateRunning)
400a19b5093SGeorge Liu                 {
401a19b5093SGeorge Liu                     systemdUnitAction(conn, yield, service, sysdStopUnit);
402a19b5093SGeorge Liu                 }
403a19b5093SGeorge Liu             }
404a19b5093SGeorge Liu         }
405a19b5093SGeorge Liu     }
40690f2da3fSRichard Marian Thomaiyar 
40790f2da3fSRichard Marian Thomaiyar     if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))
40890f2da3fSRichard Marian Thomaiyar     {
40990f2da3fSRichard Marian Thomaiyar         createSocketOverrideConf();
4100084047dSAppaRao Puli         // Create override config file and write data.
41190f2da3fSRichard Marian Thomaiyar         std::string ovrCfgFile{overrideConfDir + "/" + overrideConfFileName};
4120084047dSAppaRao Puli         std::string tmpFile{ovrCfgFile + "_tmp"};
4130084047dSAppaRao Puli         std::ofstream cfgFile(tmpFile, std::ios::out);
4140084047dSAppaRao Puli         if (!cfgFile.good())
4150084047dSAppaRao Puli         {
416cb267c8fSGeorge Liu             lg2::error("Failed to open the {TMPFILE} file.", "TMPFILE",
417cb267c8fSGeorge Liu                        tmpFile);
4180084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4190084047dSAppaRao Puli                                         Error::InternalFailure>();
4200084047dSAppaRao Puli         }
4210084047dSAppaRao Puli 
4220084047dSAppaRao Puli         // Write the socket header
4230084047dSAppaRao Puli         cfgFile << "[Socket]\n";
4240084047dSAppaRao Puli         // Listen
4250084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "="
4260084047dSAppaRao Puli                 << "\n";
4270084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "=" << portNum << "\n";
4280084047dSAppaRao Puli         cfgFile.close();
4290084047dSAppaRao Puli 
4300084047dSAppaRao Puli         if (std::rename(tmpFile.c_str(), ovrCfgFile.c_str()) != 0)
4310084047dSAppaRao Puli         {
432cb267c8fSGeorge Liu             lg2::error("Failed to rename {TMPFILE} file as {OVERCFGFILE} file.",
433cb267c8fSGeorge Liu                        "TMPFILE", tmpFile, "OVERCFGFILE", ovrCfgFile);
4340084047dSAppaRao Puli             std::remove(tmpFile.c_str());
4350084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4360084047dSAppaRao Puli                                         Error::InternalFailure>();
4370084047dSAppaRao Puli         }
438e55cfd6eSAppaRao Puli     }
4390084047dSAppaRao Puli 
44090f2da3fSRichard Marian Thomaiyar     if (updatedFlag & ((1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
44190f2da3fSRichard Marian Thomaiyar                        (1 << static_cast<uint8_t>(UpdatedProp::enabledState))))
442e55cfd6eSAppaRao Puli     {
44390f2da3fSRichard Marian Thomaiyar         std::vector<std::string> unitFiles;
44490f2da3fSRichard Marian Thomaiyar         if (socketObjectPath.empty())
44590f2da3fSRichard Marian Thomaiyar         {
44690f2da3fSRichard Marian Thomaiyar             unitFiles = {getServiceUnitName()};
447e55cfd6eSAppaRao Puli         }
448f476683cSJiaqing Zhao         else if (serviceObjectPath.empty())
449a19b5093SGeorge Liu         {
450a19b5093SGeorge Liu             unitFiles = {getSocketUnitName()};
451a19b5093SGeorge Liu         }
45290f2da3fSRichard Marian Thomaiyar         else
453e55cfd6eSAppaRao Puli         {
45490f2da3fSRichard Marian Thomaiyar             unitFiles = {getSocketUnitName(), getServiceUnitName()};
45590f2da3fSRichard Marian Thomaiyar         }
45690f2da3fSRichard Marian Thomaiyar         systemdUnitFilesStateChange(conn, yield, unitFiles, stateValue,
45790f2da3fSRichard Marian Thomaiyar                                     unitMaskedState, unitEnabledState);
45890f2da3fSRichard Marian Thomaiyar     }
45990f2da3fSRichard Marian Thomaiyar     return;
46090f2da3fSRichard Marian Thomaiyar }
46190f2da3fSRichard Marian Thomaiyar void ServiceConfig::restartUnitConfig(boost::asio::yield_context yield)
46290f2da3fSRichard Marian Thomaiyar {
46390f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
46490f2da3fSRichard Marian Thomaiyar     {
46590f2da3fSRichard Marian Thomaiyar         // No updates. Just return.
46690f2da3fSRichard Marian Thomaiyar         return;
4670084047dSAppaRao Puli     }
4680084047dSAppaRao Puli 
46990f2da3fSRichard Marian Thomaiyar     if (unitRunningState)
4700084047dSAppaRao Puli     {
47190f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
47290f2da3fSRichard Marian Thomaiyar         {
47390f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(),
47490f2da3fSRichard Marian Thomaiyar                               sysdRestartUnit);
4750084047dSAppaRao Puli         }
476f476683cSJiaqing Zhao         if (!serviceObjectPath.empty())
477a19b5093SGeorge Liu         {
478a19b5093SGeorge Liu             systemdUnitAction(conn, yield, getServiceUnitName(),
479a19b5093SGeorge Liu                               sysdRestartUnit);
480a19b5093SGeorge Liu         }
4810084047dSAppaRao Puli     }
4820084047dSAppaRao Puli 
4830084047dSAppaRao Puli     // Reset the flag
4840084047dSAppaRao Puli     updatedFlag = 0;
4850084047dSAppaRao Puli 
486cb267c8fSGeorge Liu     lg2::info("Applied new settings: {OBJPATH}", "OBJPATH", objPath);
4870084047dSAppaRao Puli 
48890f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
4890084047dSAppaRao Puli     return;
4900084047dSAppaRao Puli }
4910084047dSAppaRao Puli 
4920084047dSAppaRao Puli void ServiceConfig::startServiceRestartTimer()
4930084047dSAppaRao Puli {
49433816cf9SRichard Marian Thomaiyar     timer->expires_after(std::chrono::seconds(restartTimeout));
4950084047dSAppaRao Puli     timer->async_wait([this](const boost::system::error_code& ec) {
4960084047dSAppaRao Puli         if (ec == boost::asio::error::operation_aborted)
4970084047dSAppaRao Puli         {
4980084047dSAppaRao Puli             // Timer reset.
4990084047dSAppaRao Puli             return;
5000084047dSAppaRao Puli         }
5010084047dSAppaRao Puli         else if (ec)
5020084047dSAppaRao Puli         {
503cb267c8fSGeorge Liu             lg2::error("async wait error: {EC}", "EC", ec.value());
5040084047dSAppaRao Puli             return;
5050084047dSAppaRao Puli         }
50690f2da3fSRichard Marian Thomaiyar         updateInProgress = true;
50790f2da3fSRichard Marian Thomaiyar         boost::asio::spawn(conn->get_io_context(),
50890f2da3fSRichard Marian Thomaiyar                            [this](boost::asio::yield_context yield) {
50990f2da3fSRichard Marian Thomaiyar                                // Stop and apply configuration for all objects
5100084047dSAppaRao Puli                                for (auto& srvMgrObj : srvMgrObjects)
5110084047dSAppaRao Puli                                {
5120084047dSAppaRao Puli                                    auto& srvObj = srvMgrObj.second;
5130084047dSAppaRao Puli                                    if (srvObj->updatedFlag)
5140084047dSAppaRao Puli                                    {
51590f2da3fSRichard Marian Thomaiyar                                        srvObj->stopAndApplyUnitConfig(yield);
5160084047dSAppaRao Puli                                    }
5170084047dSAppaRao Puli                                }
51890f2da3fSRichard Marian Thomaiyar                                // Do system reload
51990f2da3fSRichard Marian Thomaiyar                                systemdDaemonReload(conn, yield);
52090f2da3fSRichard Marian Thomaiyar                                // restart unit config.
52190f2da3fSRichard Marian Thomaiyar                                for (auto& srvMgrObj : srvMgrObjects)
52290f2da3fSRichard Marian Thomaiyar                                {
52390f2da3fSRichard Marian Thomaiyar                                    auto& srvObj = srvMgrObj.second;
52490f2da3fSRichard Marian Thomaiyar                                    if (srvObj->updatedFlag)
52590f2da3fSRichard Marian Thomaiyar                                    {
52690f2da3fSRichard Marian Thomaiyar                                        srvObj->restartUnitConfig(yield);
52790f2da3fSRichard Marian Thomaiyar                                    }
52890f2da3fSRichard Marian Thomaiyar                                }
52990f2da3fSRichard Marian Thomaiyar                                updateInProgress = false;
53090f2da3fSRichard Marian Thomaiyar                            });
5310084047dSAppaRao Puli     });
5320084047dSAppaRao Puli }
5330084047dSAppaRao Puli 
5340084047dSAppaRao Puli void ServiceConfig::registerProperties()
5350084047dSAppaRao Puli {
53683241c09STom Joseph     srvCfgIface = server.add_interface(objPath, serviceConfigIntfName);
5370084047dSAppaRao Puli 
53890f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
53990f2da3fSRichard Marian Thomaiyar     {
54083241c09STom Joseph         sockAttrIface = server.add_interface(objPath, sockAttrIntfName);
54183241c09STom Joseph         sockAttrIface->register_property(
54283241c09STom Joseph             sockAttrPropPort, portNum,
54390f2da3fSRichard Marian Thomaiyar             [this](const uint16_t& req, uint16_t& res) {
54490f2da3fSRichard Marian Thomaiyar                 if (!internalSet)
54590f2da3fSRichard Marian Thomaiyar                 {
5460084047dSAppaRao Puli                     if (req == res)
5470084047dSAppaRao Puli                     {
5480084047dSAppaRao Puli                         return 1;
5490084047dSAppaRao Puli                     }
55090f2da3fSRichard Marian Thomaiyar                     if (updateInProgress)
55190f2da3fSRichard Marian Thomaiyar                     {
55290f2da3fSRichard Marian Thomaiyar                         return 0;
55390f2da3fSRichard Marian Thomaiyar                     }
5540084047dSAppaRao Puli                     portNum = req;
55590f2da3fSRichard Marian Thomaiyar                     updatedFlag |=
55690f2da3fSRichard Marian Thomaiyar                         (1 << static_cast<uint8_t>(UpdatedProp::port));
5570084047dSAppaRao Puli                     startServiceRestartTimer();
55890f2da3fSRichard Marian Thomaiyar                 }
55990f2da3fSRichard Marian Thomaiyar                 res = req;
56090f2da3fSRichard Marian Thomaiyar                 return 1;
56190f2da3fSRichard Marian Thomaiyar             });
56290f2da3fSRichard Marian Thomaiyar     }
56390f2da3fSRichard Marian Thomaiyar 
56483241c09STom Joseph     srvCfgIface->register_property(
56590f2da3fSRichard Marian Thomaiyar         srvCfgPropMasked, unitMaskedState, [this](const bool& req, bool& res) {
56690f2da3fSRichard Marian Thomaiyar             if (!internalSet)
56790f2da3fSRichard Marian Thomaiyar             {
56825a0f634SChicago Duan #ifdef USB_CODE_UPDATE
56925a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
57025a0f634SChicago Duan                 {
57125a0f634SChicago Duan                     unitMaskedState = req;
57225a0f634SChicago Duan                     unitEnabledState = !unitMaskedState;
57325a0f634SChicago Duan                     unitRunningState = !unitMaskedState;
57425a0f634SChicago Duan                     internalSet = true;
57525a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
57625a0f634SChicago Duan                                               unitEnabledState);
57725a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
57825a0f634SChicago Duan                                               unitRunningState);
57925a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropMasked,
58025a0f634SChicago Duan                                               unitMaskedState);
58125a0f634SChicago Duan                     internalSet = false;
58225a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
58325a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
58425a0f634SChicago Duan                                                  unitEnabledState);
58525a0f634SChicago Duan                     return 1;
58625a0f634SChicago Duan                 }
58725a0f634SChicago Duan #endif
58890f2da3fSRichard Marian Thomaiyar                 if (req == res)
58990f2da3fSRichard Marian Thomaiyar                 {
59090f2da3fSRichard Marian Thomaiyar                     return 1;
59190f2da3fSRichard Marian Thomaiyar                 }
59290f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
59390f2da3fSRichard Marian Thomaiyar                 {
59490f2da3fSRichard Marian Thomaiyar                     return 0;
59590f2da3fSRichard Marian Thomaiyar                 }
59690f2da3fSRichard Marian Thomaiyar                 unitMaskedState = req;
59790f2da3fSRichard Marian Thomaiyar                 unitEnabledState = !unitMaskedState;
59890f2da3fSRichard Marian Thomaiyar                 unitRunningState = !unitMaskedState;
59990f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
60090f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
60190f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState)) |
60290f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
60390f2da3fSRichard Marian Thomaiyar                 internalSet = true;
60483241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
60583241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
60690f2da3fSRichard Marian Thomaiyar                 internalSet = false;
60790f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
60890f2da3fSRichard Marian Thomaiyar             }
6090084047dSAppaRao Puli             res = req;
6100084047dSAppaRao Puli             return 1;
6110084047dSAppaRao Puli         });
6120084047dSAppaRao Puli 
61383241c09STom Joseph     srvCfgIface->register_property(
61490f2da3fSRichard Marian Thomaiyar         srvCfgPropEnabled, unitEnabledState,
61590f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
61690f2da3fSRichard Marian Thomaiyar             if (!internalSet)
61790f2da3fSRichard Marian Thomaiyar             {
61825a0f634SChicago Duan #ifdef USB_CODE_UPDATE
61925a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
62025a0f634SChicago Duan                 {
62125a0f634SChicago Duan                     if (unitMaskedState)
62225a0f634SChicago Duan                     { // block updating if masked
623*f27f431fSJiaqing Zhao                         lg2::error("Invalid value specified");
62425a0f634SChicago Duan                         return -EINVAL;
62525a0f634SChicago Duan                     }
62625a0f634SChicago Duan                     unitEnabledState = req;
62725a0f634SChicago Duan                     unitRunningState = req;
62825a0f634SChicago Duan                     internalSet = true;
62925a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
63025a0f634SChicago Duan                                               unitEnabledState);
63125a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
63225a0f634SChicago Duan                                               unitRunningState);
63325a0f634SChicago Duan                     internalSet = false;
63425a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
63525a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
63625a0f634SChicago Duan                                                  unitEnabledState);
63725a0f634SChicago Duan                     res = req;
63825a0f634SChicago Duan                     return 1;
63925a0f634SChicago Duan                 }
64025a0f634SChicago Duan #endif
6410084047dSAppaRao Puli                 if (req == res)
6420084047dSAppaRao Puli                 {
6430084047dSAppaRao Puli                     return 1;
6440084047dSAppaRao Puli                 }
64590f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
6460084047dSAppaRao Puli                 {
64790f2da3fSRichard Marian Thomaiyar                     return 0;
6480084047dSAppaRao Puli                 }
64990f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
65090f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
651cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
6520084047dSAppaRao Puli                     return -EINVAL;
6530084047dSAppaRao Puli                 }
65490f2da3fSRichard Marian Thomaiyar                 unitEnabledState = req;
65590f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
65690f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState));
6570084047dSAppaRao Puli                 startServiceRestartTimer();
65890f2da3fSRichard Marian Thomaiyar             }
65990f2da3fSRichard Marian Thomaiyar             res = req;
66090f2da3fSRichard Marian Thomaiyar             return 1;
66190f2da3fSRichard Marian Thomaiyar         });
66290f2da3fSRichard Marian Thomaiyar 
66383241c09STom Joseph     srvCfgIface->register_property(
66490f2da3fSRichard Marian Thomaiyar         srvCfgPropRunning, unitRunningState,
66590f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
66690f2da3fSRichard Marian Thomaiyar             if (!internalSet)
66790f2da3fSRichard Marian Thomaiyar             {
66825a0f634SChicago Duan #ifdef USB_CODE_UPDATE
66925a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
67025a0f634SChicago Duan                 {
67125a0f634SChicago Duan                     if (unitMaskedState)
67225a0f634SChicago Duan                     { // block updating if masked
673*f27f431fSJiaqing Zhao                         lg2::error("Invalid value specified");
67425a0f634SChicago Duan                         return -EINVAL;
67525a0f634SChicago Duan                     }
67625a0f634SChicago Duan                     unitEnabledState = req;
67725a0f634SChicago Duan                     unitRunningState = req;
67825a0f634SChicago Duan                     internalSet = true;
67925a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
68025a0f634SChicago Duan                                               unitEnabledState);
68125a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
68225a0f634SChicago Duan                                               unitRunningState);
68325a0f634SChicago Duan                     internalSet = false;
68425a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
68525a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
68625a0f634SChicago Duan                                                  unitEnabledState);
68725a0f634SChicago Duan                     res = req;
68825a0f634SChicago Duan                     return 1;
68925a0f634SChicago Duan                 }
69025a0f634SChicago Duan #endif
69190f2da3fSRichard Marian Thomaiyar                 if (req == res)
69290f2da3fSRichard Marian Thomaiyar                 {
69390f2da3fSRichard Marian Thomaiyar                     return 1;
69490f2da3fSRichard Marian Thomaiyar                 }
69590f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
69690f2da3fSRichard Marian Thomaiyar                 {
69790f2da3fSRichard Marian Thomaiyar                     return 0;
69890f2da3fSRichard Marian Thomaiyar                 }
69990f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
70090f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
701cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
70290f2da3fSRichard Marian Thomaiyar                     return -EINVAL;
70390f2da3fSRichard Marian Thomaiyar                 }
70490f2da3fSRichard Marian Thomaiyar                 unitRunningState = req;
70590f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
70690f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
70790f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
70890f2da3fSRichard Marian Thomaiyar             }
7090084047dSAppaRao Puli             res = req;
7100084047dSAppaRao Puli             return 1;
7110084047dSAppaRao Puli         });
7120084047dSAppaRao Puli 
71383241c09STom Joseph     srvCfgIface->initialize();
71483241c09STom Joseph     if (!socketObjectPath.empty())
71583241c09STom Joseph     {
71683241c09STom Joseph         sockAttrIface->initialize();
71783241c09STom Joseph     }
7180084047dSAppaRao Puli     return;
7190084047dSAppaRao Puli }
7200084047dSAppaRao Puli 
7210084047dSAppaRao Puli } // namespace service
7220084047dSAppaRao Puli } // namespace phosphor
723