xref: /openbmc/service-config-manager/src/srvcfg_manager.cpp (revision f476683ce8493f1ae08d09bfaa3d579ffdb316f1)
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         {
6825a0f634SChicago Duan             phosphor::logging::log<phosphor::logging::level::INFO>(
6925a0f634SChicago Duan                 "Enable usb code update");
7025a0f634SChicago Duan             std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
7125a0f634SChicago Duan         }
7225a0f634SChicago Duan         return;
7325a0f634SChicago Duan     }
7425a0f634SChicago Duan 
7525a0f634SChicago Duan     // Disable usb code update
7625a0f634SChicago Duan     if (std::filesystem::exists(emptyUsbCodeUpdateRulesFile))
7725a0f634SChicago Duan     {
7825a0f634SChicago Duan         std::filesystem::remove(emptyUsbCodeUpdateRulesFile);
7925a0f634SChicago Duan     }
8025a0f634SChicago Duan     std::error_code ec;
8125a0f634SChicago Duan     std::filesystem::create_symlink("/dev/null", emptyUsbCodeUpdateRulesFile,
8225a0f634SChicago Duan                                     ec);
8325a0f634SChicago Duan     if (ec)
8425a0f634SChicago Duan     {
8525a0f634SChicago Duan         phosphor::logging::log<phosphor::logging::level::ERR>(
8625a0f634SChicago Duan             "Disable usb code update failed");
8725a0f634SChicago Duan         return;
8825a0f634SChicago Duan     }
8925a0f634SChicago Duan     phosphor::logging::log<phosphor::logging::level::INFO>(
9025a0f634SChicago Duan         "Disable usb code update");
9125a0f634SChicago Duan }
9225a0f634SChicago Duan 
9325a0f634SChicago Duan void ServiceConfig::saveUSBCodeUpdateStateToFile(const bool& maskedState,
9425a0f634SChicago Duan                                                  const bool& enabledState)
9525a0f634SChicago Duan {
9625a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFilePath))
9725a0f634SChicago Duan     {
9825a0f634SChicago Duan         std::filesystem::create_directories(usbCodeUpdateStateFilePath);
9925a0f634SChicago Duan     }
10025a0f634SChicago Duan 
10125a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
10225a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropMasked] = maskedState;
10325a0f634SChicago Duan     usbCodeUpdateState[srvCfgPropEnabled] = enabledState;
10425a0f634SChicago Duan 
10525a0f634SChicago Duan     std::ofstream file(usbCodeUpdateStateFile, std::ios::out);
10625a0f634SChicago Duan     cereal::JSONOutputArchive archive(file);
10725a0f634SChicago Duan     archive(CEREAL_NVP(usbCodeUpdateState));
10825a0f634SChicago Duan }
10925a0f634SChicago Duan 
11025a0f634SChicago Duan void ServiceConfig::getUSBCodeUpdateStateFromFile()
11125a0f634SChicago Duan {
11225a0f634SChicago Duan     if (!std::filesystem::exists(usbCodeUpdateStateFile))
11325a0f634SChicago Duan     {
11425a0f634SChicago Duan         phosphor::logging::log<phosphor::logging::level::INFO>(
11525a0f634SChicago Duan             "usb-code-update-state file does not exist");
11625a0f634SChicago Duan 
11725a0f634SChicago Duan         unitMaskedState = false;
11825a0f634SChicago Duan         unitEnabledState = true;
11925a0f634SChicago Duan         unitRunningState = true;
12025a0f634SChicago Duan         setUSBCodeUpdateState(unitEnabledState);
12125a0f634SChicago Duan         return;
12225a0f634SChicago Duan     }
12325a0f634SChicago Duan 
12425a0f634SChicago Duan     std::ifstream file(usbCodeUpdateStateFile);
12525a0f634SChicago Duan     cereal::JSONInputArchive archive(file);
12625a0f634SChicago Duan     UsbCodeUpdateStateMap usbCodeUpdateState;
12725a0f634SChicago Duan     archive(usbCodeUpdateState);
12825a0f634SChicago Duan 
12925a0f634SChicago Duan     auto iterMask = usbCodeUpdateState.find(srvCfgPropMasked);
13025a0f634SChicago Duan     if (iterMask != usbCodeUpdateState.end())
13125a0f634SChicago Duan     {
13225a0f634SChicago Duan         unitMaskedState = iterMask->second;
13325a0f634SChicago Duan         if (unitMaskedState)
13425a0f634SChicago Duan         {
13525a0f634SChicago Duan             unitEnabledState = !unitMaskedState;
13625a0f634SChicago Duan             unitRunningState = !unitMaskedState;
13725a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
13825a0f634SChicago Duan             return;
13925a0f634SChicago Duan         }
14025a0f634SChicago Duan 
14125a0f634SChicago Duan         auto iterEnable = usbCodeUpdateState.find(srvCfgPropEnabled);
14225a0f634SChicago Duan         if (iterEnable != usbCodeUpdateState.end())
14325a0f634SChicago Duan         {
14425a0f634SChicago Duan             unitEnabledState = iterEnable->second;
14525a0f634SChicago Duan             unitRunningState = iterEnable->second;
14625a0f634SChicago Duan             setUSBCodeUpdateState(unitEnabledState);
14725a0f634SChicago Duan         }
14825a0f634SChicago Duan     }
14925a0f634SChicago Duan }
15025a0f634SChicago Duan #endif
15125a0f634SChicago Duan 
15290f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateSocketProperties(
15390f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
1540084047dSAppaRao Puli {
15590f2da3fSRichard Marian Thomaiyar     auto listenIt = propertyMap.find("Listen");
15690f2da3fSRichard Marian Thomaiyar     if (listenIt != propertyMap.end())
1570084047dSAppaRao Puli     {
15890f2da3fSRichard Marian Thomaiyar         auto listenVal =
15990f2da3fSRichard Marian Thomaiyar             std::get<std::vector<std::tuple<std::string, std::string>>>(
16090f2da3fSRichard Marian Thomaiyar                 listenIt->second);
16190f2da3fSRichard Marian Thomaiyar         if (listenVal.size())
1620084047dSAppaRao Puli         {
1630084047dSAppaRao Puli             protocol = std::get<0>(listenVal[0]);
1640084047dSAppaRao Puli             std::string port = std::get<1>(listenVal[0]);
1650084047dSAppaRao Puli             auto tmp = std::stoul(port.substr(port.find_last_of(":") + 1),
1660084047dSAppaRao Puli                                   nullptr, 10);
1670084047dSAppaRao Puli             if (tmp > std::numeric_limits<uint16_t>::max())
1680084047dSAppaRao Puli             {
1690084047dSAppaRao Puli                 throw std::out_of_range("Out of range");
1700084047dSAppaRao Puli             }
1710084047dSAppaRao Puli             portNum = tmp;
17283241c09STom Joseph             if (sockAttrIface && sockAttrIface->is_initialized())
17390f2da3fSRichard Marian Thomaiyar             {
17490f2da3fSRichard Marian Thomaiyar                 internalSet = true;
17583241c09STom Joseph                 sockAttrIface->set_property(sockAttrPropPort, portNum);
17690f2da3fSRichard Marian Thomaiyar                 internalSet = false;
17790f2da3fSRichard Marian Thomaiyar             }
17890f2da3fSRichard Marian Thomaiyar         }
17990f2da3fSRichard Marian Thomaiyar     }
18090f2da3fSRichard Marian Thomaiyar }
18190f2da3fSRichard Marian Thomaiyar 
18290f2da3fSRichard Marian Thomaiyar void ServiceConfig::updateServiceProperties(
18390f2da3fSRichard Marian Thomaiyar     const boost::container::flat_map<std::string, VariantType>& propertyMap)
18490f2da3fSRichard Marian Thomaiyar {
18590f2da3fSRichard Marian Thomaiyar     auto stateIt = propertyMap.find("UnitFileState");
18690f2da3fSRichard Marian Thomaiyar     if (stateIt != propertyMap.end())
18790f2da3fSRichard Marian Thomaiyar     {
18890f2da3fSRichard Marian Thomaiyar         stateValue = std::get<std::string>(stateIt->second);
18990f2da3fSRichard Marian Thomaiyar         unitEnabledState = unitMaskedState = false;
19090f2da3fSRichard Marian Thomaiyar         if (stateValue == stateMasked)
19190f2da3fSRichard Marian Thomaiyar         {
19290f2da3fSRichard Marian Thomaiyar             unitMaskedState = true;
19390f2da3fSRichard Marian Thomaiyar         }
19490f2da3fSRichard Marian Thomaiyar         else if (stateValue == stateEnabled)
19590f2da3fSRichard Marian Thomaiyar         {
19690f2da3fSRichard Marian Thomaiyar             unitEnabledState = true;
19790f2da3fSRichard Marian Thomaiyar         }
19883241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
19990f2da3fSRichard Marian Thomaiyar         {
20090f2da3fSRichard Marian Thomaiyar             internalSet = true;
20183241c09STom Joseph             srvCfgIface->set_property(srvCfgPropMasked, unitMaskedState);
20283241c09STom Joseph             srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
20390f2da3fSRichard Marian Thomaiyar             internalSet = false;
20490f2da3fSRichard Marian Thomaiyar         }
20590f2da3fSRichard Marian Thomaiyar     }
20690f2da3fSRichard Marian Thomaiyar     auto subStateIt = propertyMap.find("SubState");
20790f2da3fSRichard Marian Thomaiyar     if (subStateIt != propertyMap.end())
20890f2da3fSRichard Marian Thomaiyar     {
20990f2da3fSRichard Marian Thomaiyar         subStateValue = std::get<std::string>(subStateIt->second);
210a19b5093SGeorge Liu         if (subStateValue == subStateRunning ||
211a19b5093SGeorge Liu             subStateValue == subStateListening)
21290f2da3fSRichard Marian Thomaiyar         {
21390f2da3fSRichard Marian Thomaiyar             unitRunningState = true;
21490f2da3fSRichard Marian Thomaiyar         }
21583241c09STom Joseph         if (srvCfgIface && srvCfgIface->is_initialized())
21690f2da3fSRichard Marian Thomaiyar         {
21790f2da3fSRichard Marian Thomaiyar             internalSet = true;
21883241c09STom Joseph             srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
21990f2da3fSRichard Marian Thomaiyar             internalSet = false;
22090f2da3fSRichard Marian Thomaiyar         }
22190f2da3fSRichard Marian Thomaiyar     }
22225a0f634SChicago Duan 
22325a0f634SChicago Duan #ifdef USB_CODE_UPDATE
22425a0f634SChicago Duan     if (objPath == usbCodeUpdateObjectPath)
22525a0f634SChicago Duan     {
22625a0f634SChicago Duan         getUSBCodeUpdateStateFromFile();
22725a0f634SChicago Duan     }
22825a0f634SChicago Duan #endif
22990f2da3fSRichard Marian Thomaiyar }
23090f2da3fSRichard Marian Thomaiyar 
23190f2da3fSRichard Marian Thomaiyar void ServiceConfig::queryAndUpdateProperties()
23290f2da3fSRichard Marian Thomaiyar {
233a19b5093SGeorge Liu     std::string objectPath =
234*f476683cSJiaqing Zhao         isSocketActivatedService ? socketObjectPath : serviceObjectPath;
235a19b5093SGeorge Liu     if (objectPath.empty())
236a19b5093SGeorge Liu     {
237a19b5093SGeorge Liu         return;
238a19b5093SGeorge Liu     }
239a19b5093SGeorge Liu 
24090f2da3fSRichard Marian Thomaiyar     conn->async_method_call(
24190f2da3fSRichard Marian Thomaiyar         [this](boost::system::error_code ec,
242ee853eb2SAppaRao Puli                const boost::container::flat_map<std::string, VariantType>&
243ee853eb2SAppaRao Puli                    propertyMap) {
24490f2da3fSRichard Marian Thomaiyar             if (ec)
24590f2da3fSRichard Marian Thomaiyar             {
246cb267c8fSGeorge Liu                 lg2::error(
247cb267c8fSGeorge Liu                     "async_method_call error: Failed to service unit properties: {EC}",
248cb267c8fSGeorge Liu                     "EC", ec.value());
24990f2da3fSRichard Marian Thomaiyar                 return;
25090f2da3fSRichard Marian Thomaiyar             }
25190f2da3fSRichard Marian Thomaiyar             try
25290f2da3fSRichard Marian Thomaiyar             {
25390f2da3fSRichard Marian Thomaiyar                 updateServiceProperties(propertyMap);
25490f2da3fSRichard Marian Thomaiyar                 if (!socketObjectPath.empty())
25590f2da3fSRichard Marian Thomaiyar                 {
25690f2da3fSRichard Marian Thomaiyar                     conn->async_method_call(
25790f2da3fSRichard Marian Thomaiyar                         [this](boost::system::error_code ec,
25890f2da3fSRichard Marian Thomaiyar                                const boost::container::flat_map<
25990f2da3fSRichard Marian Thomaiyar                                    std::string, VariantType>& propertyMap) {
26090f2da3fSRichard Marian Thomaiyar                             if (ec)
26190f2da3fSRichard Marian Thomaiyar                             {
262cb267c8fSGeorge Liu                                 lg2::error(
263cb267c8fSGeorge Liu                                     "async_method_call error: Failed to get all property: {EC}",
264cb267c8fSGeorge Liu                                     "EC", ec.value());
26590f2da3fSRichard Marian Thomaiyar                                 return;
26690f2da3fSRichard Marian Thomaiyar                             }
26790f2da3fSRichard Marian Thomaiyar                             try
26890f2da3fSRichard Marian Thomaiyar                             {
26990f2da3fSRichard Marian Thomaiyar                                 updateSocketProperties(propertyMap);
27083241c09STom Joseph                                 if (!srvCfgIface)
27190f2da3fSRichard Marian Thomaiyar                                 {
27290f2da3fSRichard Marian Thomaiyar                                     registerProperties();
27390f2da3fSRichard Marian Thomaiyar                                 }
27490f2da3fSRichard Marian Thomaiyar                             }
27590f2da3fSRichard Marian Thomaiyar                             catch (const std::exception& e)
27690f2da3fSRichard Marian Thomaiyar                             {
277cb267c8fSGeorge Liu                                 lg2::error(
278cb267c8fSGeorge Liu                                     "Exception in getting socket properties: {ERROR}",
279cb267c8fSGeorge Liu                                     "ERROR", e);
28090f2da3fSRichard Marian Thomaiyar                                 return;
28190f2da3fSRichard Marian Thomaiyar                             }
28290f2da3fSRichard Marian Thomaiyar                         },
28390f2da3fSRichard Marian Thomaiyar                         sysdService, socketObjectPath, dBusPropIntf,
28490f2da3fSRichard Marian Thomaiyar                         dBusGetAllMethod, sysdSocketIntf);
28590f2da3fSRichard Marian Thomaiyar                 }
28683241c09STom Joseph                 else if (!srvCfgIface)
28790f2da3fSRichard Marian Thomaiyar                 {
28890f2da3fSRichard Marian Thomaiyar                     registerProperties();
28990f2da3fSRichard Marian Thomaiyar                 }
2900084047dSAppaRao Puli             }
2910084047dSAppaRao Puli             catch (const std::exception& e)
2920084047dSAppaRao Puli             {
293cb267c8fSGeorge Liu                 lg2::error("Exception in getting socket properties: {ERROR}",
294cb267c8fSGeorge Liu                            "ERROR", e);
2950084047dSAppaRao Puli                 return;
2960084047dSAppaRao Puli             }
2970084047dSAppaRao Puli         },
298a19b5093SGeorge Liu         sysdService, objectPath, dBusPropIntf, dBusGetAllMethod, sysdUnitIntf);
2990084047dSAppaRao Puli     return;
3000084047dSAppaRao Puli }
3010084047dSAppaRao Puli 
30290f2da3fSRichard Marian Thomaiyar void ServiceConfig::createSocketOverrideConf()
3030084047dSAppaRao Puli {
30490f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
3050084047dSAppaRao Puli     {
30690f2da3fSRichard Marian Thomaiyar         std::string socketUnitName(instantiatedUnitName + ".socket");
3070084047dSAppaRao Puli         /// Check override socket directory exist, if not create it.
30882e9557eSTom Joseph         std::filesystem::path ovrUnitFileDir(systemdOverrideUnitBasePath);
3090084047dSAppaRao Puli         ovrUnitFileDir += socketUnitName;
3100084047dSAppaRao Puli         ovrUnitFileDir += ".d";
31182e9557eSTom Joseph         if (!std::filesystem::exists(ovrUnitFileDir))
3120084047dSAppaRao Puli         {
31382e9557eSTom Joseph             if (!std::filesystem::create_directories(ovrUnitFileDir))
3140084047dSAppaRao Puli             {
315cb267c8fSGeorge Liu                 lg2::error("Unable to create the {DIR} directory.", "DIR",
316cb267c8fSGeorge Liu                            ovrUnitFileDir);
31790f2da3fSRichard Marian Thomaiyar                 phosphor::logging::elog<sdbusplus::xyz::openbmc_project::
31890f2da3fSRichard Marian Thomaiyar                                             Common::Error::InternalFailure>();
31990f2da3fSRichard Marian Thomaiyar             }
32090f2da3fSRichard Marian Thomaiyar         }
32190f2da3fSRichard Marian Thomaiyar         overrideConfDir = std::string(ovrUnitFileDir);
3220084047dSAppaRao Puli     }
3230084047dSAppaRao Puli }
3240084047dSAppaRao Puli 
32590f2da3fSRichard Marian Thomaiyar ServiceConfig::ServiceConfig(
32690f2da3fSRichard Marian Thomaiyar     sdbusplus::asio::object_server& srv_,
32790f2da3fSRichard Marian Thomaiyar     std::shared_ptr<sdbusplus::asio::connection>& conn_,
32890f2da3fSRichard Marian Thomaiyar     const std::string& objPath_, const std::string& baseUnitName_,
32990f2da3fSRichard Marian Thomaiyar     const std::string& instanceName_, const std::string& serviceObjPath_,
33090f2da3fSRichard Marian Thomaiyar     const std::string& socketObjPath_) :
33182e9557eSTom Joseph     conn(conn_),
33282e9557eSTom Joseph     server(srv_), objPath(objPath_), baseUnitName(baseUnitName_),
33390f2da3fSRichard Marian Thomaiyar     instanceName(instanceName_), serviceObjectPath(serviceObjPath_),
33490f2da3fSRichard Marian Thomaiyar     socketObjectPath(socketObjPath_)
33590f2da3fSRichard Marian Thomaiyar {
336*f476683cSJiaqing Zhao     isSocketActivatedService = serviceObjectPath.empty();
33790f2da3fSRichard Marian Thomaiyar     instantiatedUnitName = baseUnitName + addInstanceName(instanceName, "@");
3380084047dSAppaRao Puli     updatedFlag = 0;
33990f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
3400084047dSAppaRao Puli     return;
3410084047dSAppaRao Puli }
3420084047dSAppaRao Puli 
34390f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getSocketUnitName()
3440084047dSAppaRao Puli {
34590f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".socket";
346e55cfd6eSAppaRao Puli }
347e55cfd6eSAppaRao Puli 
34890f2da3fSRichard Marian Thomaiyar std::string ServiceConfig::getServiceUnitName()
34990f2da3fSRichard Marian Thomaiyar {
35090f2da3fSRichard Marian Thomaiyar     return instantiatedUnitName + ".service";
35190f2da3fSRichard Marian Thomaiyar }
35290f2da3fSRichard Marian Thomaiyar 
35390f2da3fSRichard Marian Thomaiyar bool ServiceConfig::isMaskedOut()
35490f2da3fSRichard Marian Thomaiyar {
35590f2da3fSRichard Marian Thomaiyar     // return true  if state is masked & no request to update the maskedState
35690f2da3fSRichard Marian Thomaiyar     return (
35790f2da3fSRichard Marian Thomaiyar         stateValue == "masked" &&
35890f2da3fSRichard Marian Thomaiyar         !(updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::maskedState))));
35990f2da3fSRichard Marian Thomaiyar }
36090f2da3fSRichard Marian Thomaiyar 
36190f2da3fSRichard Marian Thomaiyar void ServiceConfig::stopAndApplyUnitConfig(boost::asio::yield_context yield)
36290f2da3fSRichard Marian Thomaiyar {
36390f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
36490f2da3fSRichard Marian Thomaiyar     {
36590f2da3fSRichard Marian Thomaiyar         // No updates / masked - Just return.
36690f2da3fSRichard Marian Thomaiyar         return;
36790f2da3fSRichard Marian Thomaiyar     }
368cb267c8fSGeorge Liu     lg2::info("Applying new settings: {OBJPATH}", "OBJPATH", objPath);
369a19b5093SGeorge Liu     if (subStateValue == subStateRunning || subStateValue == subStateListening)
3700084047dSAppaRao Puli     {
37190f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
37290f2da3fSRichard Marian Thomaiyar         {
37390f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(), sysdStopUnit);
37490f2da3fSRichard Marian Thomaiyar         }
375*f476683cSJiaqing Zhao         if (!isSocketActivatedService)
376a19b5093SGeorge Liu         {
37790f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getServiceUnitName(), sysdStopUnit);
37890f2da3fSRichard Marian Thomaiyar         }
379a19b5093SGeorge Liu         else
380a19b5093SGeorge Liu         {
381*f476683cSJiaqing Zhao             // For socket-activated service, each connection will spawn a
382*f476683cSJiaqing Zhao             // service instance from template. Need to find all spawned service
383*f476683cSJiaqing Zhao             // `<unitName>@<attribute>.service` and stop them through the
384*f476683cSJiaqing Zhao             // systemdUnitAction method
385a19b5093SGeorge Liu             boost::system::error_code ec;
386a19b5093SGeorge Liu             auto listUnits =
387a19b5093SGeorge Liu                 conn->yield_method_call<std::vector<ListUnitsType>>(
388a19b5093SGeorge Liu                     yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
389a19b5093SGeorge Liu                     "ListUnits");
390a19b5093SGeorge Liu 
391a19b5093SGeorge Liu             checkAndThrowInternalFailure(
392a19b5093SGeorge Liu                 ec, "yield_method_call error: ListUnits failed");
393a19b5093SGeorge Liu 
394a19b5093SGeorge Liu             for (const auto& unit : listUnits)
395a19b5093SGeorge Liu             {
396a19b5093SGeorge Liu                 const auto& service =
397a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::name)>(unit);
398a19b5093SGeorge Liu                 const auto& status =
399a19b5093SGeorge Liu                     std::get<static_cast<int>(ListUnitElements::subState)>(
400a19b5093SGeorge Liu                         unit);
401*f476683cSJiaqing Zhao                 if (service.find(baseUnitName + "@") != std::string::npos &&
402a19b5093SGeorge Liu                     service.find(".service") != std::string::npos &&
403a19b5093SGeorge Liu                     status == subStateRunning)
404a19b5093SGeorge Liu                 {
405a19b5093SGeorge Liu                     systemdUnitAction(conn, yield, service, sysdStopUnit);
406a19b5093SGeorge Liu                 }
407a19b5093SGeorge Liu             }
408a19b5093SGeorge Liu         }
409a19b5093SGeorge Liu     }
41090f2da3fSRichard Marian Thomaiyar 
41190f2da3fSRichard Marian Thomaiyar     if (updatedFlag & (1 << static_cast<uint8_t>(UpdatedProp::port)))
41290f2da3fSRichard Marian Thomaiyar     {
41390f2da3fSRichard Marian Thomaiyar         createSocketOverrideConf();
4140084047dSAppaRao Puli         // Create override config file and write data.
41590f2da3fSRichard Marian Thomaiyar         std::string ovrCfgFile{overrideConfDir + "/" + overrideConfFileName};
4160084047dSAppaRao Puli         std::string tmpFile{ovrCfgFile + "_tmp"};
4170084047dSAppaRao Puli         std::ofstream cfgFile(tmpFile, std::ios::out);
4180084047dSAppaRao Puli         if (!cfgFile.good())
4190084047dSAppaRao Puli         {
420cb267c8fSGeorge Liu             lg2::error("Failed to open the {TMPFILE} file.", "TMPFILE",
421cb267c8fSGeorge Liu                        tmpFile);
4220084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4230084047dSAppaRao Puli                                         Error::InternalFailure>();
4240084047dSAppaRao Puli         }
4250084047dSAppaRao Puli 
4260084047dSAppaRao Puli         // Write the socket header
4270084047dSAppaRao Puli         cfgFile << "[Socket]\n";
4280084047dSAppaRao Puli         // Listen
4290084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "="
4300084047dSAppaRao Puli                 << "\n";
4310084047dSAppaRao Puli         cfgFile << "Listen" << protocol << "=" << portNum << "\n";
4320084047dSAppaRao Puli         cfgFile.close();
4330084047dSAppaRao Puli 
4340084047dSAppaRao Puli         if (std::rename(tmpFile.c_str(), ovrCfgFile.c_str()) != 0)
4350084047dSAppaRao Puli         {
436cb267c8fSGeorge Liu             lg2::error("Failed to rename {TMPFILE} file as {OVERCFGFILE} file.",
437cb267c8fSGeorge Liu                        "TMPFILE", tmpFile, "OVERCFGFILE", ovrCfgFile);
4380084047dSAppaRao Puli             std::remove(tmpFile.c_str());
4390084047dSAppaRao Puli             phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
4400084047dSAppaRao Puli                                         Error::InternalFailure>();
4410084047dSAppaRao Puli         }
442e55cfd6eSAppaRao Puli     }
4430084047dSAppaRao Puli 
44490f2da3fSRichard Marian Thomaiyar     if (updatedFlag & ((1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
44590f2da3fSRichard Marian Thomaiyar                        (1 << static_cast<uint8_t>(UpdatedProp::enabledState))))
446e55cfd6eSAppaRao Puli     {
44790f2da3fSRichard Marian Thomaiyar         std::vector<std::string> unitFiles;
44890f2da3fSRichard Marian Thomaiyar         if (socketObjectPath.empty())
44990f2da3fSRichard Marian Thomaiyar         {
45090f2da3fSRichard Marian Thomaiyar             unitFiles = {getServiceUnitName()};
451e55cfd6eSAppaRao Puli         }
452*f476683cSJiaqing Zhao         else if (serviceObjectPath.empty())
453a19b5093SGeorge Liu         {
454a19b5093SGeorge Liu             unitFiles = {getSocketUnitName()};
455a19b5093SGeorge Liu         }
45690f2da3fSRichard Marian Thomaiyar         else
457e55cfd6eSAppaRao Puli         {
45890f2da3fSRichard Marian Thomaiyar             unitFiles = {getSocketUnitName(), getServiceUnitName()};
45990f2da3fSRichard Marian Thomaiyar         }
46090f2da3fSRichard Marian Thomaiyar         systemdUnitFilesStateChange(conn, yield, unitFiles, stateValue,
46190f2da3fSRichard Marian Thomaiyar                                     unitMaskedState, unitEnabledState);
46290f2da3fSRichard Marian Thomaiyar     }
46390f2da3fSRichard Marian Thomaiyar     return;
46490f2da3fSRichard Marian Thomaiyar }
46590f2da3fSRichard Marian Thomaiyar void ServiceConfig::restartUnitConfig(boost::asio::yield_context yield)
46690f2da3fSRichard Marian Thomaiyar {
46790f2da3fSRichard Marian Thomaiyar     if (!updatedFlag || isMaskedOut())
46890f2da3fSRichard Marian Thomaiyar     {
46990f2da3fSRichard Marian Thomaiyar         // No updates. Just return.
47090f2da3fSRichard Marian Thomaiyar         return;
4710084047dSAppaRao Puli     }
4720084047dSAppaRao Puli 
47390f2da3fSRichard Marian Thomaiyar     if (unitRunningState)
4740084047dSAppaRao Puli     {
47590f2da3fSRichard Marian Thomaiyar         if (!socketObjectPath.empty())
47690f2da3fSRichard Marian Thomaiyar         {
47790f2da3fSRichard Marian Thomaiyar             systemdUnitAction(conn, yield, getSocketUnitName(),
47890f2da3fSRichard Marian Thomaiyar                               sysdRestartUnit);
4790084047dSAppaRao Puli         }
480*f476683cSJiaqing Zhao         if (!serviceObjectPath.empty())
481a19b5093SGeorge Liu         {
482a19b5093SGeorge Liu             systemdUnitAction(conn, yield, getServiceUnitName(),
483a19b5093SGeorge Liu                               sysdRestartUnit);
484a19b5093SGeorge Liu         }
4850084047dSAppaRao Puli     }
4860084047dSAppaRao Puli 
4870084047dSAppaRao Puli     // Reset the flag
4880084047dSAppaRao Puli     updatedFlag = 0;
4890084047dSAppaRao Puli 
490cb267c8fSGeorge Liu     lg2::info("Applied new settings: {OBJPATH}", "OBJPATH", objPath);
4910084047dSAppaRao Puli 
49290f2da3fSRichard Marian Thomaiyar     queryAndUpdateProperties();
4930084047dSAppaRao Puli     return;
4940084047dSAppaRao Puli }
4950084047dSAppaRao Puli 
4960084047dSAppaRao Puli void ServiceConfig::startServiceRestartTimer()
4970084047dSAppaRao Puli {
49833816cf9SRichard Marian Thomaiyar     timer->expires_after(std::chrono::seconds(restartTimeout));
4990084047dSAppaRao Puli     timer->async_wait([this](const boost::system::error_code& ec) {
5000084047dSAppaRao Puli         if (ec == boost::asio::error::operation_aborted)
5010084047dSAppaRao Puli         {
5020084047dSAppaRao Puli             // Timer reset.
5030084047dSAppaRao Puli             return;
5040084047dSAppaRao Puli         }
5050084047dSAppaRao Puli         else if (ec)
5060084047dSAppaRao Puli         {
507cb267c8fSGeorge Liu             lg2::error("async wait error: {EC}", "EC", ec.value());
5080084047dSAppaRao Puli             return;
5090084047dSAppaRao Puli         }
51090f2da3fSRichard Marian Thomaiyar         updateInProgress = true;
51190f2da3fSRichard Marian Thomaiyar         boost::asio::spawn(conn->get_io_context(),
51290f2da3fSRichard Marian Thomaiyar                            [this](boost::asio::yield_context yield) {
51390f2da3fSRichard Marian Thomaiyar                                // Stop and apply configuration for all objects
5140084047dSAppaRao Puli                                for (auto& srvMgrObj : srvMgrObjects)
5150084047dSAppaRao Puli                                {
5160084047dSAppaRao Puli                                    auto& srvObj = srvMgrObj.second;
5170084047dSAppaRao Puli                                    if (srvObj->updatedFlag)
5180084047dSAppaRao Puli                                    {
51990f2da3fSRichard Marian Thomaiyar                                        srvObj->stopAndApplyUnitConfig(yield);
5200084047dSAppaRao Puli                                    }
5210084047dSAppaRao Puli                                }
52290f2da3fSRichard Marian Thomaiyar                                // Do system reload
52390f2da3fSRichard Marian Thomaiyar                                systemdDaemonReload(conn, yield);
52490f2da3fSRichard Marian Thomaiyar                                // restart unit config.
52590f2da3fSRichard Marian Thomaiyar                                for (auto& srvMgrObj : srvMgrObjects)
52690f2da3fSRichard Marian Thomaiyar                                {
52790f2da3fSRichard Marian Thomaiyar                                    auto& srvObj = srvMgrObj.second;
52890f2da3fSRichard Marian Thomaiyar                                    if (srvObj->updatedFlag)
52990f2da3fSRichard Marian Thomaiyar                                    {
53090f2da3fSRichard Marian Thomaiyar                                        srvObj->restartUnitConfig(yield);
53190f2da3fSRichard Marian Thomaiyar                                    }
53290f2da3fSRichard Marian Thomaiyar                                }
53390f2da3fSRichard Marian Thomaiyar                                updateInProgress = false;
53490f2da3fSRichard Marian Thomaiyar                            });
5350084047dSAppaRao Puli     });
5360084047dSAppaRao Puli }
5370084047dSAppaRao Puli 
5380084047dSAppaRao Puli void ServiceConfig::registerProperties()
5390084047dSAppaRao Puli {
54083241c09STom Joseph     srvCfgIface = server.add_interface(objPath, serviceConfigIntfName);
5410084047dSAppaRao Puli 
54290f2da3fSRichard Marian Thomaiyar     if (!socketObjectPath.empty())
54390f2da3fSRichard Marian Thomaiyar     {
54483241c09STom Joseph         sockAttrIface = server.add_interface(objPath, sockAttrIntfName);
54583241c09STom Joseph         sockAttrIface->register_property(
54683241c09STom Joseph             sockAttrPropPort, portNum,
54790f2da3fSRichard Marian Thomaiyar             [this](const uint16_t& req, uint16_t& res) {
54890f2da3fSRichard Marian Thomaiyar                 if (!internalSet)
54990f2da3fSRichard Marian Thomaiyar                 {
5500084047dSAppaRao Puli                     if (req == res)
5510084047dSAppaRao Puli                     {
5520084047dSAppaRao Puli                         return 1;
5530084047dSAppaRao Puli                     }
55490f2da3fSRichard Marian Thomaiyar                     if (updateInProgress)
55590f2da3fSRichard Marian Thomaiyar                     {
55690f2da3fSRichard Marian Thomaiyar                         return 0;
55790f2da3fSRichard Marian Thomaiyar                     }
5580084047dSAppaRao Puli                     portNum = req;
55990f2da3fSRichard Marian Thomaiyar                     updatedFlag |=
56090f2da3fSRichard Marian Thomaiyar                         (1 << static_cast<uint8_t>(UpdatedProp::port));
5610084047dSAppaRao Puli                     startServiceRestartTimer();
56290f2da3fSRichard Marian Thomaiyar                 }
56390f2da3fSRichard Marian Thomaiyar                 res = req;
56490f2da3fSRichard Marian Thomaiyar                 return 1;
56590f2da3fSRichard Marian Thomaiyar             });
56690f2da3fSRichard Marian Thomaiyar     }
56790f2da3fSRichard Marian Thomaiyar 
56883241c09STom Joseph     srvCfgIface->register_property(
56990f2da3fSRichard Marian Thomaiyar         srvCfgPropMasked, unitMaskedState, [this](const bool& req, bool& res) {
57090f2da3fSRichard Marian Thomaiyar             if (!internalSet)
57190f2da3fSRichard Marian Thomaiyar             {
57225a0f634SChicago Duan #ifdef USB_CODE_UPDATE
57325a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
57425a0f634SChicago Duan                 {
57525a0f634SChicago Duan                     unitMaskedState = req;
57625a0f634SChicago Duan                     unitEnabledState = !unitMaskedState;
57725a0f634SChicago Duan                     unitRunningState = !unitMaskedState;
57825a0f634SChicago Duan                     internalSet = true;
57925a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
58025a0f634SChicago Duan                                               unitEnabledState);
58125a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
58225a0f634SChicago Duan                                               unitRunningState);
58325a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropMasked,
58425a0f634SChicago Duan                                               unitMaskedState);
58525a0f634SChicago Duan                     internalSet = false;
58625a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
58725a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
58825a0f634SChicago Duan                                                  unitEnabledState);
58925a0f634SChicago Duan                     return 1;
59025a0f634SChicago Duan                 }
59125a0f634SChicago Duan #endif
59290f2da3fSRichard Marian Thomaiyar                 if (req == res)
59390f2da3fSRichard Marian Thomaiyar                 {
59490f2da3fSRichard Marian Thomaiyar                     return 1;
59590f2da3fSRichard Marian Thomaiyar                 }
59690f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
59790f2da3fSRichard Marian Thomaiyar                 {
59890f2da3fSRichard Marian Thomaiyar                     return 0;
59990f2da3fSRichard Marian Thomaiyar                 }
60090f2da3fSRichard Marian Thomaiyar                 unitMaskedState = req;
60190f2da3fSRichard Marian Thomaiyar                 unitEnabledState = !unitMaskedState;
60290f2da3fSRichard Marian Thomaiyar                 unitRunningState = !unitMaskedState;
60390f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
60490f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::maskedState)) |
60590f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState)) |
60690f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
60790f2da3fSRichard Marian Thomaiyar                 internalSet = true;
60883241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropEnabled, unitEnabledState);
60983241c09STom Joseph                 srvCfgIface->set_property(srvCfgPropRunning, unitRunningState);
61090f2da3fSRichard Marian Thomaiyar                 internalSet = false;
61190f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
61290f2da3fSRichard Marian Thomaiyar             }
6130084047dSAppaRao Puli             res = req;
6140084047dSAppaRao Puli             return 1;
6150084047dSAppaRao Puli         });
6160084047dSAppaRao Puli 
61783241c09STom Joseph     srvCfgIface->register_property(
61890f2da3fSRichard Marian Thomaiyar         srvCfgPropEnabled, unitEnabledState,
61990f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
62090f2da3fSRichard Marian Thomaiyar             if (!internalSet)
62190f2da3fSRichard Marian Thomaiyar             {
62225a0f634SChicago Duan #ifdef USB_CODE_UPDATE
62325a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
62425a0f634SChicago Duan                 {
62525a0f634SChicago Duan                     if (unitMaskedState)
62625a0f634SChicago Duan                     { // block updating if masked
62725a0f634SChicago Duan                         phosphor::logging::log<phosphor::logging::level::ERR>(
62825a0f634SChicago Duan                             "Invalid value specified");
62925a0f634SChicago Duan                         return -EINVAL;
63025a0f634SChicago Duan                     }
63125a0f634SChicago Duan                     unitEnabledState = req;
63225a0f634SChicago Duan                     unitRunningState = req;
63325a0f634SChicago Duan                     internalSet = true;
63425a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
63525a0f634SChicago Duan                                               unitEnabledState);
63625a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
63725a0f634SChicago Duan                                               unitRunningState);
63825a0f634SChicago Duan                     internalSet = false;
63925a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
64025a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
64125a0f634SChicago Duan                                                  unitEnabledState);
64225a0f634SChicago Duan                     res = req;
64325a0f634SChicago Duan                     return 1;
64425a0f634SChicago Duan                 }
64525a0f634SChicago Duan #endif
6460084047dSAppaRao Puli                 if (req == res)
6470084047dSAppaRao Puli                 {
6480084047dSAppaRao Puli                     return 1;
6490084047dSAppaRao Puli                 }
65090f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
6510084047dSAppaRao Puli                 {
65290f2da3fSRichard Marian Thomaiyar                     return 0;
6530084047dSAppaRao Puli                 }
65490f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
65590f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
656cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
6570084047dSAppaRao Puli                     return -EINVAL;
6580084047dSAppaRao Puli                 }
65990f2da3fSRichard Marian Thomaiyar                 unitEnabledState = req;
66090f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
66190f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::enabledState));
6620084047dSAppaRao Puli                 startServiceRestartTimer();
66390f2da3fSRichard Marian Thomaiyar             }
66490f2da3fSRichard Marian Thomaiyar             res = req;
66590f2da3fSRichard Marian Thomaiyar             return 1;
66690f2da3fSRichard Marian Thomaiyar         });
66790f2da3fSRichard Marian Thomaiyar 
66883241c09STom Joseph     srvCfgIface->register_property(
66990f2da3fSRichard Marian Thomaiyar         srvCfgPropRunning, unitRunningState,
67090f2da3fSRichard Marian Thomaiyar         [this](const bool& req, bool& res) {
67190f2da3fSRichard Marian Thomaiyar             if (!internalSet)
67290f2da3fSRichard Marian Thomaiyar             {
67325a0f634SChicago Duan #ifdef USB_CODE_UPDATE
67425a0f634SChicago Duan                 if (objPath == usbCodeUpdateObjectPath)
67525a0f634SChicago Duan                 {
67625a0f634SChicago Duan                     if (unitMaskedState)
67725a0f634SChicago Duan                     { // block updating if masked
67825a0f634SChicago Duan                         phosphor::logging::log<phosphor::logging::level::ERR>(
67925a0f634SChicago Duan                             "Invalid value specified");
68025a0f634SChicago Duan                         return -EINVAL;
68125a0f634SChicago Duan                     }
68225a0f634SChicago Duan                     unitEnabledState = req;
68325a0f634SChicago Duan                     unitRunningState = req;
68425a0f634SChicago Duan                     internalSet = true;
68525a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropEnabled,
68625a0f634SChicago Duan                                               unitEnabledState);
68725a0f634SChicago Duan                     srvCfgIface->set_property(srvCfgPropRunning,
68825a0f634SChicago Duan                                               unitRunningState);
68925a0f634SChicago Duan                     internalSet = false;
69025a0f634SChicago Duan                     setUSBCodeUpdateState(unitEnabledState);
69125a0f634SChicago Duan                     saveUSBCodeUpdateStateToFile(unitMaskedState,
69225a0f634SChicago Duan                                                  unitEnabledState);
69325a0f634SChicago Duan                     res = req;
69425a0f634SChicago Duan                     return 1;
69525a0f634SChicago Duan                 }
69625a0f634SChicago Duan #endif
69790f2da3fSRichard Marian Thomaiyar                 if (req == res)
69890f2da3fSRichard Marian Thomaiyar                 {
69990f2da3fSRichard Marian Thomaiyar                     return 1;
70090f2da3fSRichard Marian Thomaiyar                 }
70190f2da3fSRichard Marian Thomaiyar                 if (updateInProgress)
70290f2da3fSRichard Marian Thomaiyar                 {
70390f2da3fSRichard Marian Thomaiyar                     return 0;
70490f2da3fSRichard Marian Thomaiyar                 }
70590f2da3fSRichard Marian Thomaiyar                 if (unitMaskedState)
70690f2da3fSRichard Marian Thomaiyar                 { // block updating if masked
707cb267c8fSGeorge Liu                     lg2::error("Invalid value specified");
70890f2da3fSRichard Marian Thomaiyar                     return -EINVAL;
70990f2da3fSRichard Marian Thomaiyar                 }
71090f2da3fSRichard Marian Thomaiyar                 unitRunningState = req;
71190f2da3fSRichard Marian Thomaiyar                 updatedFlag |=
71290f2da3fSRichard Marian Thomaiyar                     (1 << static_cast<uint8_t>(UpdatedProp::runningState));
71390f2da3fSRichard Marian Thomaiyar                 startServiceRestartTimer();
71490f2da3fSRichard Marian Thomaiyar             }
7150084047dSAppaRao Puli             res = req;
7160084047dSAppaRao Puli             return 1;
7170084047dSAppaRao Puli         });
7180084047dSAppaRao Puli 
71983241c09STom Joseph     srvCfgIface->initialize();
72083241c09STom Joseph     if (!socketObjectPath.empty())
72183241c09STom Joseph     {
72283241c09STom Joseph         sockAttrIface->initialize();
72383241c09STom Joseph     }
7240084047dSAppaRao Puli     return;
7250084047dSAppaRao Puli }
7260084047dSAppaRao Puli 
7270084047dSAppaRao Puli } // namespace service
7280084047dSAppaRao Puli } // namespace phosphor
729