blob: 775c39e413cc2c9bf017da95f3ab35be10df789d [file] [log] [blame]
AppaRao Puli00840472018-10-03 19:37:46 +05301/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#include "utils.hpp"
17
AppaRao Puliee853eb2020-05-29 00:53:20 +053018static inline void checkAndThrowInternalFailure(boost::system::error_code& ec,
19 const std::string& msg)
AppaRao Puli00840472018-10-03 19:37:46 +053020{
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053021 if (ec)
AppaRao Puli00840472018-10-03 19:37:46 +053022 {
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053023 std::string msgToLog = ec.message() + (msg.empty() ? "" : " - " + msg);
24 phosphor::logging::log<phosphor::logging::level::ERR>(msgToLog.c_str());
AppaRao Puli00840472018-10-03 19:37:46 +053025 phosphor::logging::elog<
26 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
27 }
AppaRao Puli00840472018-10-03 19:37:46 +053028 return;
29}
30
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053031void systemdDaemonReload(
AppaRao Puliee853eb2020-05-29 00:53:20 +053032 const std::shared_ptr<sdbusplus::asio::connection>& conn,
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053033 boost::asio::yield_context yield)
AppaRao Puli00840472018-10-03 19:37:46 +053034{
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053035 boost::system::error_code ec;
36 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath, sysdMgrIntf,
37 sysdReloadMethod);
38 checkAndThrowInternalFailure(ec, "daemon-reload operation failed");
39 return;
40}
41
AppaRao Puliee853eb2020-05-29 00:53:20 +053042static inline uint32_t getJobId(const std::string& path)
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053043{
44 auto pos = path.rfind("/");
45 if (pos == std::string::npos)
AppaRao Puli00840472018-10-03 19:37:46 +053046 {
47 phosphor::logging::log<phosphor::logging::level::ERR>(
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053048 "Unable to get job id from job path");
AppaRao Puli00840472018-10-03 19:37:46 +053049 phosphor::logging::elog<
50 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure>();
51 }
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053052 return static_cast<uint32_t>(std::stoul(path.substr(pos + 1)));
53}
AppaRao Puli00840472018-10-03 19:37:46 +053054
AppaRao Puliee853eb2020-05-29 00:53:20 +053055void systemdUnitAction(const std::shared_ptr<sdbusplus::asio::connection>& conn,
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053056 boost::asio::yield_context yield,
AppaRao Puliee853eb2020-05-29 00:53:20 +053057 const std::string& unitName,
58 const std::string& actionMethod)
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053059{
60 boost::system::error_code ec;
61 auto jobPath = conn->yield_method_call<sdbusplus::message::object_path>(
62 yield, ec, sysdService, sysdObjPath, sysdMgrIntf, actionMethod,
63 unitName, sysdReplaceMode);
64 checkAndThrowInternalFailure(ec,
65 "Systemd operation failed, " + actionMethod);
66 // Query the job till it doesn't exist anymore.
67 // this way we guarantee that queued job id is done.
68 // this is needed to make sure dependency list on units are
69 // properly handled.
70 while (1)
71 {
72 ec.clear();
73 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
74 sysdMgrIntf, sysdGetJobMethod,
75 getJobId(jobPath.str));
76 if (ec)
77 {
78 if (ec.value() == boost::system::errc::no_such_file_or_directory)
79 {
80 // Queued job is done, return now
81 return;
82 }
83 phosphor::logging::log<phosphor::logging::level::ERR>(
84 "Systemd operation failed for job query");
85 phosphor::logging::elog<sdbusplus::xyz::openbmc_project::Common::
86 Error::InternalFailure>();
87 }
Richard Marian Thomaiyar33816cf2019-06-14 13:54:50 +053088 boost::asio::steady_timer sleepTimer(conn->get_io_context());
89 sleepTimer.expires_after(std::chrono::milliseconds(20));
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +053090 ec.clear();
91 sleepTimer.async_wait(yield[ec]);
92 checkAndThrowInternalFailure(ec, "Systemd operation timer error");
93 }
AppaRao Puli00840472018-10-03 19:37:46 +053094 return;
95}
96
AppaRao Pulie55cfd62019-02-15 15:35:29 +053097void systemdUnitFilesStateChange(
AppaRao Puliee853eb2020-05-29 00:53:20 +053098 const std::shared_ptr<sdbusplus::asio::connection>& conn,
99 boost::asio::yield_context yield, const std::vector<std::string>& unitFiles,
100 const std::string& unitState, bool maskedState, bool enabledState)
AppaRao Puli00840472018-10-03 19:37:46 +0530101{
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +0530102 boost::system::error_code ec;
AppaRao Puli00840472018-10-03 19:37:46 +0530103
Richard Marian Thomaiyar90f2da32019-05-23 05:37:50 +0530104 if (unitState == stateMasked && !maskedState)
105 {
106 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
107 sysdMgrIntf, "UnmaskUnitFiles", unitFiles,
108 false);
109 checkAndThrowInternalFailure(ec, "Systemd UnmaskUnitFiles() failed.");
110 }
111 else if (unitState != stateMasked && maskedState)
112 {
113 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
114 sysdMgrIntf, "MaskUnitFiles", unitFiles,
115 false, false);
116 checkAndThrowInternalFailure(ec, "Systemd MaskUnitFiles() failed.");
117 }
118 ec.clear();
119 if (unitState != stateEnabled && enabledState)
120 {
121 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
122 sysdMgrIntf, "EnableUnitFiles", unitFiles,
123 false, false);
124 checkAndThrowInternalFailure(ec, "Systemd EnableUnitFiles() failed.");
125 }
126 else if (unitState != stateDisabled && !enabledState)
127 {
128 conn->yield_method_call<>(yield, ec, sysdService, sysdObjPath,
129 sysdMgrIntf, "DisableUnitFiles", unitFiles,
130 false);
131 checkAndThrowInternalFailure(ec, "Systemd DisableUnitFiles() failed.");
132 }
AppaRao Puli00840472018-10-03 19:37:46 +0530133 return;
134}