xref: /openbmc/service-config-manager/src/srvcfg_manager.cpp (revision b5aabea410ec241bfe23b90ef3bc4ae51cd57c52)
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 
5725a0f634SChicago Duan using UsbCodeUpdateStateMap = std::unordered_map<std::string, bool>;
5825a0f634SChicago Duan 
setUSBCodeUpdateState(const bool & state)5925a0f634SChicago Duan void ServiceConfig::setUSBCodeUpdateState(const bool& state)
6025a0f634SChicago Duan {
6125a0f634SChicago Duan     // Enable usb code update
6225a0f634SChicago Duan     if (state)
6325a0f634SChicago Duan     {
6425a0f634SChicago Duan         if (std::filesystem::exists(emptyUsbCodeUpdateRulesFile))
6525a0f634SChicago Duan         {
66f27f431fSJiaqing Zhao             lg2::info("Enable usb code update");
6725a0f634SChicago Duan             std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
6825a0f634SChicago Duan         }
6925a0f634SChicago Duan         return;
7025a0f634SChicago Duan     }
7125a0f634SChicago Duan 
7225a0f634SChicago Duan     // Disable usb code update
7325a0f634SChicago Duan     if (std::filesystem::exists(emptyUsbCodeUpdateRulesFile))
7425a0f634SChicago Duan     {
7525a0f634SChicago Duan         std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
7625a0f634SChicago Duan     }
7725a0f634SChicago Duan     std::error_code ec;
7825a0f634SChicago Duan     std::filesystem::create_symlink("/dev/null", emptyUsbCodeUpdateRulesFile,
7925a0f634SChicago Duan                                     ec);
8025a0f634SChicago Duan     if (ec)
8125a0f634SChicago Duan     {
82f27f431fSJiaqing Zhao         lg2::error("Disable usb code update failed");
8325a0f634SChicago Duan         return;
8425a0f634SChicago Duan     }
85f27f431fSJiaqing Zhao     lg2::info("Disable usb code update");
8625a0f634SChicago Duan }
8725a0f634SChicago Duan 
saveUSBCodeUpdateStateToFile(const bool & maskedState,const bool & enabledState)8825a0f634SChicago Duan void ServiceConfig::saveUSBCodeUpdateStateToFile(const bool& maskedState,
8925a0f634SChicago Duan                                                  const bool& enabledState)
9025a0f634SChicago Duan {
9125a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFilePath))
9225a0f634SChicago Duan     {
9325a0f634SChicago Duan         std::filesystem::create_directories(usbCodeUpdateStateFilePath);
9425a0f634SChicago Duan     }
9525a0f634SChicago Duan 
9625a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
9725a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropMasked] = maskedState;
9825a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropEnabled] = enabledState;
9925a0f634SChicago Duan 
10025a0f634SChicago Duan     std::ofstream file(usbCodeUpdateStateFile, std::ios::out);
10125a0f634SChicago Duan     cereal::JSONOutputArchive archive(file);
10225a0f634SChicago Duan     archive(CEREAL_NVP(usbCodeUpdateState));
10325a0f634SChicago Duan }
10425a0f634SChicago Duan 
getUSBCodeUpdateStateFromFile()10525a0f634SChicago Duan void ServiceConfig::getUSBCodeUpdateStateFromFile()
10625a0f634SChicago Duan {
10725a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFile))
10825a0f634SChicago Duan     {
109f27f431fSJiaqing Zhao         lg2::info("usb-code-update-state file does not exist");
11025a0f634SChicago Duan 
11125a0f634SChicago Duan         unitMaskedState = false;
11225a0f634SChicago Duan         unitEnabledState = true;
11325a0f634SChicago Duan         unitRunningState = true;
11425a0f634SChicago Duan         setUSBCodeUpdateState(unitEnabledState);
11525a0f634SChicago Duan         return;
11625a0f634SChicago Duan     }
11725a0f634SChicago Duan 
11825a0f634SChicago Duan     std::ifstream file(usbCodeUpdateStateFile);
11925a0f634SChicago Duan     cereal::JSONInputArchive archive(file);
12025a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
12125a0f634SChicago Duan     archive(usbCodeUpdateState);
12225a0f634SChicago Duan 
12325a0f634SChicago Duan     auto iterMask = usbCodeUpdateState.find(srvCfgPropMasked);
12425a0f634SChicago Duan     if (iterMask != usbCodeUpdateState.end())
12525a0f634SChicago Duan     {
12625a0f634SChicago Duan         unitMaskedState = iterMask->second;
12725a0f634SChicago Duan         if (unitMaskedState)
12825a0f634SChicago Duan         {
12925a0f634SChicago Duan             unitEnabledState = !unitMaskedState;
13025a0f634SChicago Duan             unitRunningState = !unitMaskedState;
13125a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
13225a0f634SChicago Duan             return;
13325a0f634SChicago Duan         }
13425a0f634SChicago Duan 
13525a0f634SChicago Duan         auto iterEnable = usbCodeUpdateState.find(srvCfgPropEnabled);
13625a0f634SChicago Duan         if (iterEnable != usbCodeUpdateState.end())
13725a0f634SChicago Duan         {
13825a0f634SChicago Duan             unitEnabledState = iterEnable->second;
13925a0f634SChicago Duan             unitRunningState = iterEnable->second;
14025a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
14125a0f634SChicago Duan         }
14225a0f634SChicago Duan     }
14325a0f634SChicago Duan }
14425a0f634SChicago Duan #endif
14525a0f634SChicago Duan 
updateSocketProperties(const boost::container::flat_map<std::string,VariantType> & propertyMap)14690f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateSocketProperties(
14790f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
1480084047dSAppaRao Puli {
14990f2da3fSRichard Marian Thomaiyar     auto listenIt = propertyMap.find("Listen");
15090f2da3fSRichard Marian Thomaiyar     if (listenIt != propertyMap.end())
1510084047dSAppaRao Puli     {
15290f2da3fSRichard Marian Thomaiyar         auto listenVal =
15390f2da3fSRichard Marian Thomaiyar             std::get<std::vector<std::tuple<std::string, std::string>>>(
15490f2da3fSRichard Marian Thomaiyar                 listenIt->second);
15590f2da3fSRichard Marian Thomaiyar         if (listenVal.size())
1560084047dSAppaRao Puli         {
1570084047dSAppaRao Puli             protocol = std::get<0>(listenVal[0]);
1580084047dSAppaRao Puli             std::string port = std::get<1>(listenVal[0]);
1590084047dSAppaRao Puli             auto tmp = std::stoul(port.substr(port.find_last_of(":") + 1),
1600084047dSAppaRao Puli                                   nullptr, 10);
1610084047dSAppaRao Puli             if (tmp > std::numeric_limits<uint16_t>::max())
1620084047dSAppaRao Puli             {
1630084047dSAppaRao Puli                 throw std::out_of_range("Out of range");
1640084047dSAppaRao Puli             }
1650084047dSAppaRao Puli             portNum = tmp;
16683241c09STom Joseph             if (sockAttrIface && sockAttrIface->is_initialized())
16790f2da3fSRichard Marian Thomaiyar             {
16890f2da3fSRichard Marian Thomaiyar                 internalSet = true;
16983241c09STom Joseph                 sockAttrIface->set_property(sockAttrPropPort, portNum);
17090f2da3fSRichard Marian Thomaiyar                 internalSet = false;
17190f2da3fSRichard Marian Thomaiyar             }
17290f2da3fSRichard Marian Thomaiyar         }
17390f2da3fSRichard Marian Thomaiyar     }
17490f2da3fSRichard Marian Thomaiyar }
17590f2da3fSRichard Marian Thomaiyar 
updateServiceProperties(const boost::container::flat_map<std::string,VariantType> & propertyMap)17690f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateServiceProperties(
17790f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
17890f2da3fSRichard Marian Thomaiyar {
17990f2da3fSRichard Marian Thomaiyar     auto stateIt = propertyMap.find("UnitFileState");
18090f2da3fSRichard Marian Thomaiyar     if (stateIt != propertyMap.end())
18190f2da3fSRichard Marian Thomaiyar     {
18290f2da3fSRichard Marian Thomaiyar         stateValue = std::get<std::string>(stateIt->second);
18390f2da3fSRichard Marian Thomaiyar         unitEnabledState = unitMaskedState = false;
18490f2da3fSRichard Marian Thomaiyar         if (stateValue == stateMasked)
18590f2da3fSRichard Marian Thomaiyar         {
18690f2da3fSRichard Marian Thomaiyar             unitMaskedState = true;
18790f2da3fSRichard Marian Thomaiyar         }
18890f2da3fSRichard Marian Thomaiyar         else if (stateValue == stateEnabled)
18990f2da3fSRichard Marian Thomaiyar         {
19090f2da3fSRichard Marian Thomaiyar             unitEnabledState = true;
19190f2da3fSRichard Marian Thomaiyar         }
19283241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
19390f2da3fSRichard Marian Thomaiyar         {
19490f2da3fSRichard Marian Thomaiyar             internalSet = true;
19583241c09STom Joseph             srvCfgIface->set_property(srvCfgPropMasked, unitMaskedState);
19683241c09STom Joseph             srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
19790f2da3fSRichard Marian Thomaiyar             internalSet = false;
19890f2da3fSRichard Marian Thomaiyar         }
19990f2da3fSRichard Marian Thomaiyar     }
20090f2da3fSRichard Marian Thomaiyar     auto subStateIt = propertyMap.find("SubState");
20190f2da3fSRichard Marian Thomaiyar     if (subStateIt != propertyMap.end())
20290f2da3fSRichard Marian Thomaiyar     {
20390f2da3fSRichard Marian Thomaiyar         subStateValue = std::get<std::string>(subStateIt->second);
204a19b5093SGeorge Liu         if (subStateValue == subStateRunning ||
205a19b5093SGeorge Liu             subStateValue == subStateListening)
20690f2da3fSRichard Marian Thomaiyar         {
20790f2da3fSRichard Marian Thomaiyar             unitRunningState = true;
20890f2da3fSRichard Marian Thomaiyar         }
20983241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
21090f2da3fSRichard Marian Thomaiyar         {
21190f2da3fSRichard Marian Thomaiyar             internalSet = true;
21283241c09STom Joseph             srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
21390f2da3fSRichard Marian Thomaiyar             internalSet = false;
21490f2da3fSRichard Marian Thomaiyar         }
21590f2da3fSRichard Marian Thomaiyar     }
21625a0f634SChicago Duan 
21725a0f634SChicago Duan #ifdef USB_CODE_UPDATE
218430d7ea5SJiaqing Zhao     if (baseUnitName == usbCodeUpdateUnitName)
21925a0f634SChicago Duan     {
22025a0f634SChicago Duan         getUSBCodeUpdateStateFromFile();
22125a0f634SChicago Duan     }
22225a0f634SChicago Duan #endif
22390f2da3fSRichard Marian Thomaiyar }
22490f2da3fSRichard Marian Thomaiyar 
queryAndUpdateProperties()22590f2da3fSRichard Marian Thomaiyar void ServiceConfig::queryAndUpdateProperties()
22690f2da3fSRichard Marian Thomaiyar {
227de879726SPatrick Williams     std::string objectPath =
228de879726SPatrick Williams         isSocketActivatedService ? socketObjectPath : serviceObjectPath;
229a19b5093SGeorge Liu     if (objectPath.empty())
230a19b5093SGeorge Liu     {
231a19b5093SGeorge Liu         return;
232a19b5093SGeorge Liu     }
233a19b5093SGeorge Liu 
23490f2da3fSRichard Marian Thomaiyar     conn->async_method_call(
23590f2da3fSRichard Marian Thomaiyar         [this](boost::system::error_code ec,
236ee853eb2SAppaRao Puli                const boost::container::flat_map<std::string, VariantType>&
237ee853eb2SAppaRao Puli                    propertyMap) {
23890f2da3fSRichard Marian Thomaiyar             if (ec)
23990f2da3fSRichard Marian Thomaiyar             {
240cb267c8fSGeorge Liu                 lg2::error(
241cb267c8fSGeorge Liu                     "async_method_call error: Failed to service unit properties: {EC}",
242cb267c8fSGeorge Liu                     "EC", ec.value());
24390f2da3fSRichard Marian Thomaiyar                 return;
24490f2da3fSRichard Marian Thomaiyar             }
24590f2da3fSRichard Marian Thomaiyar             try
24690f2da3fSRichard Marian Thomaiyar             {
24790f2da3fSRichard Marian Thomaiyar                 updateServiceProperties(propertyMap);
24890f2da3fSRichard Marian Thomaiyar                 if (!socketObjectPath.empty())
24990f2da3fSRichard Marian Thomaiyar                 {
25090f2da3fSRichard Marian Thomaiyar                     conn->async_method_call(
25190f2da3fSRichard Marian Thomaiyar                         [this](boost::system::error_code ec,
25290f2da3fSRichard Marian Thomaiyar                                const boost::container::flat_map<
25390f2da3fSRichard Marian Thomaiyar                                    std::string, VariantType>& propertyMap) {
25490f2da3fSRichard Marian Thomaiyar                             if (ec)
25590f2da3fSRichard Marian Thomaiyar                             {
256cb267c8fSGeorge Liu                                 lg2::error(
257cb267c8fSGeorge Liu                                     "async_method_call error: Failed to get all property: {EC}",
258cb267c8fSGeorge Liu                                     "EC", ec.value());
25990f2da3fSRichard Marian Thomaiyar                                 return;
26090f2da3fSRichard Marian Thomaiyar                             }
26190f2da3fSRichard Marian Thomaiyar                             try
26290f2da3fSRichard Marian Thomaiyar                             {
26390f2da3fSRichard Marian Thomaiyar                                 updateSocketProperties(propertyMap);
26483241c09STom Joseph                                 if (!srvCfgIface)
26590f2da3fSRichard Marian Thomaiyar                                 {
26690f2da3fSRichard Marian Thomaiyar                                     registerProperties();
26790f2da3fSRichard Marian Thomaiyar                                 }
26890f2da3fSRichard Marian Thomaiyar                             }
26990f2da3fSRichard Marian Thomaiyar                             catch (const std::exception& e)
27090f2da3fSRichard Marian Thomaiyar                             {
271cb267c8fSGeorge Liu                                 lg2::error(
272cb267c8fSGeorge Liu                                     "Exception in getting socket properties: {ERROR}",
273cb267c8fSGeorge Liu                                     "ERROR", e);
27490f2da3fSRichard Marian Thomaiyar                                 return;
27590f2da3fSRichard Marian Thomaiyar                             }
27690f2da3fSRichard Marian Thomaiyar                         },
27790f2da3fSRichard Marian Thomaiyar                         sysdService, socketObjectPath, dBusPropIntf,
27890f2da3fSRichard Marian Thomaiyar                         dBusGetAllMethod, sysdSocketIntf);
27990f2da3fSRichard Marian Thomaiyar                 }
28083241c09STom Joseph                 else if (!srvCfgIface)
28190f2da3fSRichard Marian Thomaiyar                 {
28290f2da3fSRichard Marian Thomaiyar                     registerProperties();
28390f2da3fSRichard Marian Thomaiyar                 }
2840084047dSAppaRao Puli             }
2850084047dSAppaRao Puli             catch (const std::exception& e)
2860084047dSAppaRao Puli             {
287cb267c8fSGeorge Liu                 lg2::error("Exception in getting socket properties: {ERROR}",
288cb267c8fSGeorge Liu                            "ERROR", e);
2890084047dSAppaRao Puli                 return;
2900084047dSAppaRao Puli             }
2910084047dSAppaRao Puli         },
292a19b5093SGeorge Liu         sysdService, objectPath, dBusPropIntf, dBusGetAllMethod, sysdUnitIntf);
2930084047dSAppaRao Puli     return;
2940084047dSAppaRao Puli }
2950084047dSAppaRao Puli 
createSocketOverrideConf()29690f2da3fSRichard Marian Thomaiyar void ServiceConfig::createSocketOverrideConf()
2970084047dSAppaRao Puli {
29890f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
2990084047dSAppaRao Puli     {
30090f2da3fSRichard Marian Thomaiyar         std::string socketUnitName(instantiatedUnitName + ".socket");
3010084047dSAppaRao Puli         /// Check override socket directory exist, if not create it.
30282e9557eSTom Joseph         std::filesystem::path ovrUnitFileDir(systemdOverrideUnitBasePath);
3030084047dSAppaRao Puli         ovrUnitFileDir += socketUnitName;
3040084047dSAppaRao Puli         ovrUnitFileDir += ".d";
30582e9557eSTom Joseph         if (!std::filesystem::exists(ovrUnitFileDir))
3060084047dSAppaRao Puli         {
30782e9557eSTom Joseph             if (!std::filesystem::create_directories(ovrUnitFileDir))
3080084047dSAppaRao Puli             {
309cb267c8fSGeorge Liu                 lg2::error("Unable to create the {DIR} directory.", "DIR",
310cb267c8fSGeorge Liu                            ovrUnitFileDir);
31190f2da3fSRichard Marian Thomaiyar                 phosphor::logging::elog<sdbusplus::xyz::openbmc_project::
31290f2da3fSRichard Marian Thomaiyar                                             Common::Error::InternalFailure>();
31390f2da3fSRichard Marian Thomaiyar             }
31490f2da3fSRichard Marian Thomaiyar         }
31590f2da3fSRichard Marian Thomaiyar         overrideConfDir = std::string(ovrUnitFileDir);
3160084047dSAppaRao Puli     }
3170084047dSAppaRao Puli }
3180084047dSAppaRao Puli 
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_)31990f2da3fSRichard Marian Thomaiyar ServiceConfig::ServiceConfig(
32090f2da3fSRichard Marian Thomaiyar     sdbusplus::asio::object_server& srv_,
32190f2da3fSRichard Marian Thomaiyar     std::shared_ptr<sdbusplus::asio::connection>& conn_,
32290f2da3fSRichard Marian Thomaiyar     const std::string& objPath_, const std::string& baseUnitName_,
32390f2da3fSRichard Marian Thomaiyar     const std::string& instanceName_, const std::string& serviceObjPath_,
32490f2da3fSRichard Marian Thomaiyar     const std::string& socketObjPath_) :
325de879726SPatrick Williams     conn(conn_), server(srv_), objPath(objPath_), baseUnitName(baseUnitName_),
32690f2da3fSRichard Marian Thomaiyar     instanceName(instanceName_), serviceObjectPath(serviceObjPath_),
32790f2da3fSRichard Marian Thomaiyar     socketObjectPath(socketObjPath_)
32890f2da3fSRichard Marian Thomaiyar {
329f476683cSJiaqing Zhao     isSocketActivatedService = serviceObjectPath.empty();
33090f2da3fSRichard Marian Thomaiyar     instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");
3310084047dSAppaRao Puli     updatedFlag = 0;
33290f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
3330084047dSAppaRao Puli     return;
3340084047dSAppaRao Puli }
3350084047dSAppaRao Puli 
getSocketUnitName()33690f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getSocketUnitName()
3370084047dSAppaRao Puli {
33890f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".socket";
339e55cfd6eSAppaRao Puli }
340e55cfd6eSAppaRao Puli 
getServiceUnitName()34190f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getServiceUnitName()
34290f2da3fSRichard Marian Thomaiyar {
34390f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".service";
34490f2da3fSRichard Marian Thomaiyar }
34590f2da3fSRichard Marian Thomaiyar 
isMaskedOut()34690f2da3fSRichard Marian Thomaiyar bool ServiceConfig::isMaskedOut()
34790f2da3fSRichard Marian Thomaiyar {
34890f2da3fSRichard Marian Thomaiyar     // return true  if state is masked & no request to update the maskedState
34990f2da3fSRichard Marian Thomaiyar     return (
35090f2da3fSRichard Marian Thomaiyar         stateValue == "masked" &&
35190f2da3fSRichard Marian Thomaiyar         !(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::maskedState))));
35290f2da3fSRichard Marian Thomaiyar }
35390f2da3fSRichard Marian Thomaiyar 
stopAndApplyUnitConfig(boost::asio::yield_context yield)35490f2da3fSRichard Marian Thomaiyar void ServiceConfig::stopAndApplyUnitConfig(boost::asio::yield_context yield)
35590f2da3fSRichard Marian Thomaiyar {
35690f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
35790f2da3fSRichard Marian Thomaiyar     {
35890f2da3fSRichard Marian Thomaiyar         // No updates / masked - Just return.
35990f2da3fSRichard Marian Thomaiyar         return;
36090f2da3fSRichard Marian Thomaiyar     }
361cb267c8fSGeorge Liu     lg2::info("Applying new settings: {OBJPATH}", "OBJPATH", objPath);
362a19b5093SGeorge Liu     if (subStateValue == subStateRunning || subStateValue == subStateListening)
3630084047dSAppaRao Puli     {
36490f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
36590f2da3fSRichard Marian Thomaiyar         {
36690f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);
36790f2da3fSRichard Marian Thomaiyar         }
368f476683cSJiaqing Zhao         if (!isSocketActivatedService)
369a19b5093SGeorge Liu         {
37090f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
37190f2da3fSRichard Marian Thomaiyar         }
372a19b5093SGeorge Liu         else
373a19b5093SGeorge Liu         {
374f476683cSJiaqing Zhao             // For socket-activated service, each connection will spawn a
375f476683cSJiaqing Zhao             // service instance from template. Need to find all spawned service
376f476683cSJiaqing Zhao             // `<unitName>@<attribute>.service` and stop them through the
377f476683cSJiaqing Zhao             // systemdUnitAction method
378a19b5093SGeorge Liu             boost::system::error_code ec;
379a19b5093SGeorge Liu             auto listUnits =
380a19b5093SGeorge Liu                 conn->yield_method_call<std::vector<ListUnitsType>>(
381a19b5093SGeorge Liu                     yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
382a19b5093SGeorge Liu                     "ListUnits");
383a19b5093SGeorge Liu 
384a19b5093SGeorge Liu             checkAndThrowInternalFailure(
385a19b5093SGeorge Liu                 ec, "yield_method_call error: ListUnits failed");
386a19b5093SGeorge Liu 
387a19b5093SGeorge Liu             for (const auto& unit : listUnits)
388a19b5093SGeorge Liu             {
389a19b5093SGeorge Liu                 const auto& service =
390a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::name)>(unit);
391a19b5093SGeorge Liu                 const auto& status =
392a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::subState)>(
393a19b5093SGeorge Liu                         unit);
394f476683cSJiaqing Zhao                 if (service.find(baseUnitName + "@") != std::string::npos &&
395a19b5093SGeorge Liu                     service.find(".service") != std::string::npos &&
396a19b5093SGeorge Liu                     status == subStateRunning)
397a19b5093SGeorge Liu                 {
398a19b5093SGeorge Liu                     systemdUnitAction(conn, yield, service, sysdStopUnit);
399a19b5093SGeorge Liu                 }
400a19b5093SGeorge Liu             }
401a19b5093SGeorge Liu         }
402a19b5093SGeorge Liu     }
40390f2da3fSRichard Marian Thomaiyar 
40490f2da3fSRichard Marian Thomaiyar     if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))
40590f2da3fSRichard Marian Thomaiyar     {
40690f2da3fSRichard Marian Thomaiyar         createSocketOverrideConf();
4070084047dSAppaRao Puli         // Create override config file and write data.
40890f2da3fSRichard Marian Thomaiyar         std::string ovrCfgFile{overrideConfDir + "/" + overrideConfFileName};
4090084047dSAppaRao Puli         std::string tmpFile{ovrCfgFile + "_tmp"};
4100084047dSAppaRao Puli         std::ofstream cfgFile(tmpFile, std::ios::out);
4110084047dSAppaRao Puli         if (!cfgFile.good())
4120084047dSAppaRao Puli         {
413cb267c8fSGeorge Liu             lg2::error("Failed to open the {TMPFILE} file.", "TMPFILE",
414cb267c8fSGeorge Liu                        tmpFile);
4150084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4160084047dSAppaRao Puli                                         Error::InternalFailure>();
4170084047dSAppaRao Puli         }
4180084047dSAppaRao Puli 
4190084047dSAppaRao Puli         // Write the socket header
4200084047dSAppaRao Puli         cfgFile << "[Socket]\n";
4210084047dSAppaRao Puli         // Listen
4220084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "="
4230084047dSAppaRao Puli                 << "\n";
4240084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "=" << portNum << "\n";
4250084047dSAppaRao Puli         cfgFile.close();
4260084047dSAppaRao Puli 
4270084047dSAppaRao Puli         if (std::rename(tmpFile.c_str(), ovrCfgFile.c_str()) != 0)
4280084047dSAppaRao Puli         {
429cb267c8fSGeorge Liu             lg2::error("Failed to rename {TMPFILE} file as {OVERCFGFILE} file.",
430cb267c8fSGeorge Liu                        "TMPFILE", tmpFile, "OVERCFGFILE", ovrCfgFile);
4310084047dSAppaRao Puli             std::remove(tmpFile.c_str());
4320084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4330084047dSAppaRao Puli                                         Error::InternalFailure>();
4340084047dSAppaRao Puli         }
435e55cfd6eSAppaRao Puli     }
4360084047dSAppaRao Puli 
43790f2da3fSRichard Marian Thomaiyar     if (updatedFlag & ((1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
43890f2da3fSRichard Marian Thomaiyar                        (1 << static_cast<uint8_t>(UpdatedProp::enabledState))))
439e55cfd6eSAppaRao Puli     {
44090f2da3fSRichard Marian Thomaiyar         std::vector<std::string> unitFiles;
44190f2da3fSRichard Marian Thomaiyar         if (socketObjectPath.empty())
44290f2da3fSRichard Marian Thomaiyar         {
44390f2da3fSRichard Marian Thomaiyar             unitFiles = {getServiceUnitName()};
444e55cfd6eSAppaRao Puli         }
445f476683cSJiaqing Zhao         else if (serviceObjectPath.empty())
446a19b5093SGeorge Liu         {
447a19b5093SGeorge Liu             unitFiles = {getSocketUnitName()};
448a19b5093SGeorge Liu         }
44990f2da3fSRichard Marian Thomaiyar         else
450e55cfd6eSAppaRao Puli         {
45190f2da3fSRichard Marian Thomaiyar             unitFiles = {getSocketUnitName(), getServiceUnitName()};
45290f2da3fSRichard Marian Thomaiyar         }
45390f2da3fSRichard Marian Thomaiyar         systemdUnitFilesStateChange(conn, yield, unitFiles, stateValue,
45490f2da3fSRichard Marian Thomaiyar                                     unitMaskedState, unitEnabledState);
45590f2da3fSRichard Marian Thomaiyar     }
45690f2da3fSRichard Marian Thomaiyar     return;
45790f2da3fSRichard Marian Thomaiyar }
restartUnitConfig(boost::asio::yield_context yield)45890f2da3fSRichard Marian Thomaiyar void ServiceConfig::restartUnitConfig(boost::asio::yield_context yield)
45990f2da3fSRichard Marian Thomaiyar {
46090f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
46190f2da3fSRichard Marian Thomaiyar     {
46290f2da3fSRichard Marian Thomaiyar         // No updates. Just return.
46390f2da3fSRichard Marian Thomaiyar         return;
4640084047dSAppaRao Puli     }
4650084047dSAppaRao Puli 
46690f2da3fSRichard Marian Thomaiyar     if (unitRunningState)
4670084047dSAppaRao Puli     {
46890f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
46990f2da3fSRichard Marian Thomaiyar         {
47090f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(),
47190f2da3fSRichard Marian Thomaiyar                               sysdRestartUnit);
4720084047dSAppaRao Puli         }
473f476683cSJiaqing Zhao         if (!serviceObjectPath.empty())
474a19b5093SGeorge Liu         {
475a19b5093SGeorge Liu             systemdUnitAction(conn, yield, getServiceUnitName(),
476a19b5093SGeorge Liu                               sysdRestartUnit);
477a19b5093SGeorge Liu         }
4780084047dSAppaRao Puli     }
4790084047dSAppaRao Puli 
4800084047dSAppaRao Puli     // Reset the flag
4810084047dSAppaRao Puli     updatedFlag = 0;
4820084047dSAppaRao Puli 
483cb267c8fSGeorge Liu     lg2::info("Applied new settings: {OBJPATH}", "OBJPATH", objPath);
4840084047dSAppaRao Puli 
48590f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
4860084047dSAppaRao Puli     return;
4870084047dSAppaRao Puli }
4880084047dSAppaRao Puli 
startServiceRestartTimer()4890084047dSAppaRao Puli void ServiceConfig::startServiceRestartTimer()
4900084047dSAppaRao Puli {
49133816cf9SRichard Marian Thomaiyar     timer->expires_after(std::chrono::seconds(restartTimeout));
4920084047dSAppaRao Puli     timer->async_wait([this](const boost::system::error_code& ec) {
4930084047dSAppaRao Puli         if (ec == boost::asio::error::operation_aborted)
4940084047dSAppaRao Puli         {
4950084047dSAppaRao Puli             // Timer reset.
4960084047dSAppaRao Puli             return;
4970084047dSAppaRao Puli         }
4980084047dSAppaRao Puli         else if (ec)
4990084047dSAppaRao Puli         {
500cb267c8fSGeorge Liu             lg2::error("async wait error: {EC}", "EC", ec.value());
5010084047dSAppaRao Puli             return;
5020084047dSAppaRao Puli         }
50390f2da3fSRichard Marian Thomaiyar         updateInProgress = true;
50490f2da3fSRichard Marian Thomaiyar         boost::asio::spawn(conn->get_io_context(),
50590f2da3fSRichard Marian Thomaiyar                            [this](boost::asio::yield_context yield) {
50690f2da3fSRichard Marian Thomaiyar                                // Stop and apply configuration for all objects
5070084047dSAppaRao Puli                                for (auto& srvMgrObj : srvMgrObjects)
5080084047dSAppaRao Puli                                {
5090084047dSAppaRao Puli                                    auto& srvObj = srvMgrObj.second;
5100084047dSAppaRao Puli                                    if (srvObj->updatedFlag)
5110084047dSAppaRao Puli                                    {
51290f2da3fSRichard Marian Thomaiyar                                        srvObj->stopAndApplyUnitConfig(yield);
5130084047dSAppaRao Puli                                    }
5140084047dSAppaRao Puli                                }
51590f2da3fSRichard Marian Thomaiyar                                // Do system reload
51690f2da3fSRichard Marian Thomaiyar                                systemdDaemonReload(conn, yield);
51790f2da3fSRichard Marian Thomaiyar                                // restart unit config.
51890f2da3fSRichard Marian Thomaiyar                                for (auto& srvMgrObj : srvMgrObjects)
51990f2da3fSRichard Marian Thomaiyar                                {
52090f2da3fSRichard Marian Thomaiyar                                    auto& srvObj = srvMgrObj.second;
52190f2da3fSRichard Marian Thomaiyar                                    if (srvObj->updatedFlag)
52290f2da3fSRichard Marian Thomaiyar                                    {
52390f2da3fSRichard Marian Thomaiyar                                        srvObj->restartUnitConfig(yield);
52490f2da3fSRichard Marian Thomaiyar                                    }
52590f2da3fSRichard Marian Thomaiyar                                }
52690f2da3fSRichard Marian Thomaiyar                                updateInProgress = false;
527*b5aabea4SJayanth Othayoth                            },
528*b5aabea4SJayanth Othayoth                            {});
5290084047dSAppaRao Puli     });
5300084047dSAppaRao Puli }
5310084047dSAppaRao Puli 
registerProperties()5320084047dSAppaRao Puli void ServiceConfig::registerProperties()
5330084047dSAppaRao Puli {
53483241c09STom Joseph     srvCfgIface = server.add_interface(objPath, serviceConfigIntfName);
5350084047dSAppaRao Puli 
53690f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
53790f2da3fSRichard Marian Thomaiyar     {
53883241c09STom Joseph         sockAttrIface = server.add_interface(objPath, sockAttrIntfName);
53983241c09STom Joseph         sockAttrIface->register_property(
54083241c09STom Joseph             sockAttrPropPort, portNum,
54190f2da3fSRichard Marian Thomaiyar             [this](const uint16_t& req, uint16_t& res) {
54290f2da3fSRichard Marian Thomaiyar                 if (!internalSet)
54390f2da3fSRichard Marian Thomaiyar                 {
5440084047dSAppaRao Puli                     if (req == res)
5450084047dSAppaRao Puli                     {
5460084047dSAppaRao Puli                         return 1;
5470084047dSAppaRao Puli                     }
54890f2da3fSRichard Marian Thomaiyar                     if (updateInProgress)
54990f2da3fSRichard Marian Thomaiyar                     {
55090f2da3fSRichard Marian Thomaiyar                         return 0;
55190f2da3fSRichard Marian Thomaiyar                     }
5520084047dSAppaRao Puli                     portNum = req;
553de879726SPatrick Williams                     updatedFlag |=
554de879726SPatrick Williams                         (1 << static_cast<uint8_t>(UpdatedProp::port));
5550084047dSAppaRao Puli                     startServiceRestartTimer();
55690f2da3fSRichard Marian Thomaiyar                 }
55790f2da3fSRichard Marian Thomaiyar                 res = req;
55890f2da3fSRichard Marian Thomaiyar                 return 1;
55990f2da3fSRichard Marian Thomaiyar             });
56090f2da3fSRichard Marian Thomaiyar     }
56190f2da3fSRichard Marian Thomaiyar 
562de879726SPatrick Williams     srvCfgIface->register_property(
563de879726SPatrick Williams         srvCfgPropMasked, unitMaskedState, [this](const bool& req, bool& res) {
56490f2da3fSRichard Marian Thomaiyar             if (!internalSet)
56590f2da3fSRichard Marian Thomaiyar             {
56625a0f634SChicago Duan #ifdef USB_CODE_UPDATE
567430d7ea5SJiaqing Zhao                 if (baseUnitName == usbCodeUpdateUnitName)
56825a0f634SChicago Duan                 {
56925a0f634SChicago Duan                     unitMaskedState = req;
57025a0f634SChicago Duan                     unitEnabledState = !unitMaskedState;
57125a0f634SChicago Duan                     unitRunningState = !unitMaskedState;
57225a0f634SChicago Duan                     internalSet = true;
573de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropEnabled,
574de879726SPatrick Williams                                               unitEnabledState);
575de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropRunning,
576de879726SPatrick Williams                                               unitRunningState);
577de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropMasked,
578de879726SPatrick Williams                                               unitMaskedState);
57925a0f634SChicago Duan                     internalSet = false;
58025a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
581de879726SPatrick Williams                     saveUSBCodeUpdateStateToFile(unitMaskedState,
582de879726SPatrick Williams                                                  unitEnabledState);
58325a0f634SChicago Duan                     return 1;
58425a0f634SChicago Duan                 }
58525a0f634SChicago Duan #endif
58690f2da3fSRichard Marian Thomaiyar                 if (req == res)
58790f2da3fSRichard Marian Thomaiyar                 {
58890f2da3fSRichard Marian Thomaiyar                     return 1;
58990f2da3fSRichard Marian Thomaiyar                 }
59090f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
59190f2da3fSRichard Marian Thomaiyar                 {
59290f2da3fSRichard Marian Thomaiyar                     return 0;
59390f2da3fSRichard Marian Thomaiyar                 }
59490f2da3fSRichard Marian Thomaiyar                 unitMaskedState = req;
59590f2da3fSRichard Marian Thomaiyar                 unitEnabledState = !unitMaskedState;
59690f2da3fSRichard Marian Thomaiyar                 unitRunningState = !unitMaskedState;
59790f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
59890f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
59990f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState)) |
60090f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
60190f2da3fSRichard Marian Thomaiyar                 internalSet = true;
60283241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
60383241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
60490f2da3fSRichard Marian Thomaiyar                 internalSet = false;
60590f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
60690f2da3fSRichard Marian Thomaiyar             }
6070084047dSAppaRao Puli             res = req;
6080084047dSAppaRao Puli             return 1;
6090084047dSAppaRao Puli         });
6100084047dSAppaRao Puli 
611de879726SPatrick Williams     srvCfgIface->register_property(
612de879726SPatrick Williams         srvCfgPropEnabled, unitEnabledState,
61390f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
61490f2da3fSRichard Marian Thomaiyar             if (!internalSet)
61590f2da3fSRichard Marian Thomaiyar             {
61625a0f634SChicago Duan #ifdef USB_CODE_UPDATE
617430d7ea5SJiaqing Zhao                 if (baseUnitName == usbCodeUpdateUnitName)
61825a0f634SChicago Duan                 {
61925a0f634SChicago Duan                     if (unitMaskedState)
62025a0f634SChicago Duan                     { // block updating if masked
621f27f431fSJiaqing Zhao                         lg2::error("Invalid value specified");
62225a0f634SChicago Duan                         return -EINVAL;
62325a0f634SChicago Duan                     }
62425a0f634SChicago Duan                     unitEnabledState = req;
62525a0f634SChicago Duan                     unitRunningState = req;
62625a0f634SChicago Duan                     internalSet = true;
627de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropEnabled,
628de879726SPatrick Williams                                               unitEnabledState);
629de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropRunning,
630de879726SPatrick Williams                                               unitRunningState);
63125a0f634SChicago Duan                     internalSet = false;
63225a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
633de879726SPatrick Williams                     saveUSBCodeUpdateStateToFile(unitMaskedState,
634de879726SPatrick Williams                                                  unitEnabledState);
63525a0f634SChicago Duan                     res = req;
63625a0f634SChicago Duan                     return 1;
63725a0f634SChicago Duan                 }
63825a0f634SChicago Duan #endif
6390084047dSAppaRao Puli                 if (req == res)
6400084047dSAppaRao Puli                 {
6410084047dSAppaRao Puli                     return 1;
6420084047dSAppaRao Puli                 }
64390f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
6440084047dSAppaRao Puli                 {
64590f2da3fSRichard Marian Thomaiyar                     return 0;
6460084047dSAppaRao Puli                 }
64790f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
64890f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
649cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
6500084047dSAppaRao Puli                     return -EINVAL;
6510084047dSAppaRao Puli                 }
65290f2da3fSRichard Marian Thomaiyar                 unitEnabledState = req;
653de879726SPatrick Williams                 updatedFlag |=
654de879726SPatrick Williams                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState));
6550084047dSAppaRao Puli                 startServiceRestartTimer();
65690f2da3fSRichard Marian Thomaiyar             }
65790f2da3fSRichard Marian Thomaiyar             res = req;
65890f2da3fSRichard Marian Thomaiyar             return 1;
65990f2da3fSRichard Marian Thomaiyar         });
66090f2da3fSRichard Marian Thomaiyar 
661de879726SPatrick Williams     srvCfgIface->register_property(
662de879726SPatrick Williams         srvCfgPropRunning, unitRunningState,
66390f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
66490f2da3fSRichard Marian Thomaiyar             if (!internalSet)
66590f2da3fSRichard Marian Thomaiyar             {
66625a0f634SChicago Duan #ifdef USB_CODE_UPDATE
667430d7ea5SJiaqing Zhao                 if (baseUnitName == usbCodeUpdateUnitName)
66825a0f634SChicago Duan                 {
66925a0f634SChicago Duan                     if (unitMaskedState)
67025a0f634SChicago Duan                     { // block updating if masked
671f27f431fSJiaqing Zhao                         lg2::error("Invalid value specified");
67225a0f634SChicago Duan                         return -EINVAL;
67325a0f634SChicago Duan                     }
67425a0f634SChicago Duan                     unitEnabledState = req;
67525a0f634SChicago Duan                     unitRunningState = req;
67625a0f634SChicago Duan                     internalSet = true;
677de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropEnabled,
678de879726SPatrick Williams                                               unitEnabledState);
679de879726SPatrick Williams                     srvCfgIface->set_property(srvCfgPropRunning,
680de879726SPatrick Williams                                               unitRunningState);
68125a0f634SChicago Duan                     internalSet = false;
68225a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
683de879726SPatrick Williams                     saveUSBCodeUpdateStateToFile(unitMaskedState,
684de879726SPatrick Williams                                                  unitEnabledState);
68525a0f634SChicago Duan                     res = req;
68625a0f634SChicago Duan                     return 1;
68725a0f634SChicago Duan                 }
68825a0f634SChicago Duan #endif
68990f2da3fSRichard Marian Thomaiyar                 if (req == res)
69090f2da3fSRichard Marian Thomaiyar                 {
69190f2da3fSRichard Marian Thomaiyar                     return 1;
69290f2da3fSRichard Marian Thomaiyar                 }
69390f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
69490f2da3fSRichard Marian Thomaiyar                 {
69590f2da3fSRichard Marian Thomaiyar                     return 0;
69690f2da3fSRichard Marian Thomaiyar                 }
69790f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
69890f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
699cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
70090f2da3fSRichard Marian Thomaiyar                     return -EINVAL;
70190f2da3fSRichard Marian Thomaiyar                 }
70290f2da3fSRichard Marian Thomaiyar                 unitRunningState = req;
703de879726SPatrick Williams                 updatedFlag |=
704de879726SPatrick Williams                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
70590f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
70690f2da3fSRichard Marian Thomaiyar             }
7070084047dSAppaRao Puli             res = req;
7080084047dSAppaRao Puli             return 1;
7090084047dSAppaRao Puli         });
7100084047dSAppaRao Puli 
71183241c09STom Joseph     srvCfgIface->initialize();
71283241c09STom Joseph     if (!socketObjectPath.empty())
71383241c09STom Joseph     {
71483241c09STom Joseph         sockAttrIface->initialize();
71583241c09STom Joseph     }
7160084047dSAppaRao Puli     return;
7170084047dSAppaRao Puli }
7180084047dSAppaRao Puli 
7190084047dSAppaRao Puli } // namespace service
7200084047dSAppaRao Puli } // namespace phosphor
721