Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 1 | /** |
| 2 | * Copyright © 2016 IBM 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 | */ |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 16 | #include "manager.hpp" |
Patrick Venture | a680d1e | 2018-10-14 13:34:26 -0700 | [diff] [blame] | 17 | |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 18 | #include "errors.hpp" |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 19 | |
Patrick Venture | a680d1e | 2018-10-14 13:34:26 -0700 | [diff] [blame] | 20 | #include <algorithm> |
| 21 | #include <chrono> |
| 22 | #include <exception> |
Kun Yi | e6b21c7 | 2019-03-27 09:53:51 -0700 | [diff] [blame] | 23 | #include <filesystem> |
Patrick Venture | a680d1e | 2018-10-14 13:34:26 -0700 | [diff] [blame] | 24 | #include <iostream> |
Patrick Venture | a680d1e | 2018-10-14 13:34:26 -0700 | [diff] [blame] | 25 | |
Brad Bishop | 2442498 | 2017-01-13 16:37:14 -0500 | [diff] [blame] | 26 | using namespace std::literals::chrono_literals; |
| 27 | |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 28 | namespace phosphor |
| 29 | { |
| 30 | namespace inventory |
| 31 | { |
| 32 | namespace manager |
| 33 | { |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 34 | /** @brief Fowrarding signal callback. |
| 35 | * |
| 36 | * Extracts per-signal specific context and forwards the call to the manager |
| 37 | * instance. |
| 38 | */ |
George Liu | 23314a5 | 2022-04-13 18:26:03 +0800 | [diff] [blame] | 39 | auto _signal(sd_bus_message* m, void* data, sd_bus_error* /* e */) noexcept |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 40 | { |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 41 | try |
| 42 | { |
Patrick Williams | 563306f | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 43 | auto msg = sdbusplus::message_t(m); |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 44 | auto& args = *static_cast<Manager::SigArg*>(data); |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 45 | sd_bus_message_ref(m); |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 46 | auto& mgr = *std::get<0>(args); |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 47 | mgr.handleEvent(msg, static_cast<const DbusSignal&>(*std::get<1>(args)), |
| 48 | *std::get<2>(args)); |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 49 | } |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 50 | catch (const std::exception& e) |
| 51 | { |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 52 | std::cerr << e.what() << std::endl; |
| 53 | } |
| 54 | |
| 55 | return 0; |
| 56 | } |
| 57 | |
Patrick Williams | 563306f | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 58 | Manager::Manager(sdbusplus::bus_t&& bus, const char* root) : |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 59 | ServerObject<ManagerIface>(bus, root), _root(root), _bus(std::move(bus)), |
| 60 | _manager(_bus, root), |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 61 | #ifdef CREATE_ASSOCIATIONS |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 62 | _associations(_bus), |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 63 | #endif |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 64 | _status(ManagerStatus::STARTING) |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 65 | { |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 66 | for (auto& group : _events) |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 67 | { |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 68 | for (auto pEvent : std::get<std::vector<EventBasePtr>>(group)) |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 69 | { |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 70 | if (pEvent->type != Event::Type::DBUS_SIGNAL) |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 71 | { |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 72 | continue; |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 73 | } |
Brad Bishop | 4f20a3e | 2016-11-29 15:21:46 -0500 | [diff] [blame] | 74 | |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 75 | // Create a callback context for this event group. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 76 | auto dbusEvent = static_cast<DbusSignal*>(pEvent.get()); |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 77 | |
| 78 | // Go ahead and store an iterator pointing at |
| 79 | // the event data to avoid lookups later since |
| 80 | // additional signal callbacks aren't added |
| 81 | // after the manager is constructed. |
| 82 | _sigargs.emplace_back( |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 83 | std::make_unique<SigArg>(this, dbusEvent, &group)); |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 84 | |
| 85 | // Register our callback and the context for |
| 86 | // each signal event. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 87 | _matches.emplace_back(_bus, dbusEvent->signature, _signal, |
| 88 | _sigargs.back().get()); |
Brad Bishop | 68c8083 | 2016-11-29 16:41:32 -0500 | [diff] [blame] | 89 | } |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 90 | } |
| 91 | |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 92 | // Restore any persistent inventory |
| 93 | restore(); |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 94 | } |
| 95 | |
| 96 | void Manager::shutdown() noexcept |
| 97 | { |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 98 | _status = ManagerStatus::STOPPING; |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 99 | } |
| 100 | |
Brad Bishop | 20c9435 | 2020-12-06 20:23:56 -0500 | [diff] [blame] | 101 | void Manager::run(const char* busname) |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 102 | { |
Patrick Williams | 563306f | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 103 | sdbusplus::message_t unusedMsg{nullptr}; |
Brad Bishop | 3e4a19a | 2017-01-21 22:17:09 -0500 | [diff] [blame] | 104 | |
| 105 | // Run startup events. |
| 106 | for (auto& group : _events) |
| 107 | { |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 108 | for (auto pEvent : std::get<std::vector<EventBasePtr>>(group)) |
Brad Bishop | 3e4a19a | 2017-01-21 22:17:09 -0500 | [diff] [blame] | 109 | { |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 110 | if (pEvent->type == Event::Type::STARTUP) |
Brad Bishop | 3e4a19a | 2017-01-21 22:17:09 -0500 | [diff] [blame] | 111 | { |
| 112 | handleEvent(unusedMsg, *pEvent, group); |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 117 | _status = ManagerStatus::RUNNING; |
Brad Bishop | 20c9435 | 2020-12-06 20:23:56 -0500 | [diff] [blame] | 118 | _bus.request_name(busname); |
Brad Bishop | 4627a9c | 2020-12-06 19:26:57 -0500 | [diff] [blame] | 119 | |
| 120 | while (_status != ManagerStatus::STOPPING) |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 121 | { |
| 122 | try |
| 123 | { |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 124 | _bus.process_discard(); |
Brad Bishop | 2442498 | 2017-01-13 16:37:14 -0500 | [diff] [blame] | 125 | _bus.wait((5000000us).count()); |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 126 | } |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 127 | catch (const std::exception& e) |
| 128 | { |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 129 | std::cerr << e.what() << std::endl; |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | |
Patrick Williams | d8fba8b | 2024-08-16 15:20:15 -0400 | [diff] [blame^] | 134 | void Manager::updateInterfaces( |
| 135 | const sdbusplus::message::object_path& path, const Object& interfaces, |
| 136 | ObjectReferences::iterator pos, bool newObject, bool restoreFromCache) |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 137 | { |
| 138 | auto& refaces = pos->second; |
| 139 | auto ifaceit = interfaces.cbegin(); |
| 140 | auto opsit = _makers.cbegin(); |
| 141 | auto refaceit = refaces.begin(); |
| 142 | std::vector<std::string> signals; |
| 143 | |
| 144 | while (ifaceit != interfaces.cend()) |
| 145 | { |
| 146 | try |
| 147 | { |
| 148 | // Find the binding ops for this interface. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 149 | opsit = std::lower_bound(opsit, _makers.cend(), ifaceit->first, |
| 150 | compareFirst(_makers.key_comp())); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 151 | |
| 152 | if (opsit == _makers.cend() || opsit->first != ifaceit->first) |
| 153 | { |
| 154 | // This interface is not supported. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 155 | throw InterfaceError("Encountered unsupported interface.", |
| 156 | ifaceit->first); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | // Find the binding insertion point or the binding to update. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 160 | refaceit = std::lower_bound(refaceit, refaces.end(), ifaceit->first, |
| 161 | compareFirst(refaces.key_comp())); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 162 | |
| 163 | if (refaceit == refaces.end() || refaceit->first != ifaceit->first) |
| 164 | { |
| 165 | // Add the new interface. |
Brad Bishop | 02763c6 | 2018-12-12 22:02:07 -0500 | [diff] [blame] | 166 | auto& ctor = std::get<MakeInterfaceType>(opsit->second); |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 167 | // skipSignal = true here to avoid getting PropertiesChanged |
| 168 | // signals while the interface is constructed. We'll emit an |
| 169 | // ObjectManager signal for this interface below. |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 170 | refaceit = refaces.insert( |
Brad Bishop | e96f2aa | 2020-12-06 19:09:09 -0500 | [diff] [blame] | 171 | refaceit, std::make_pair(ifaceit->first, |
| 172 | ctor(_bus, path.str.c_str(), |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 173 | ifaceit->second, true))); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 174 | signals.push_back(ifaceit->first); |
| 175 | } |
| 176 | else |
| 177 | { |
| 178 | // Set the new property values. |
Brad Bishop | 02763c6 | 2018-12-12 22:02:07 -0500 | [diff] [blame] | 179 | auto& assign = std::get<AssignInterfaceType>(opsit->second); |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 180 | assign(ifaceit->second, refaceit->second, |
| 181 | _status != ManagerStatus::RUNNING); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 182 | } |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 183 | if (!restoreFromCache) |
| 184 | { |
Brad Bishop | 02763c6 | 2018-12-12 22:02:07 -0500 | [diff] [blame] | 185 | auto& serialize = |
| 186 | std::get<SerializeInterfaceType<SerialOps>>(opsit->second); |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 187 | serialize(path, ifaceit->first, refaceit->second); |
| 188 | } |
| 189 | else |
| 190 | { |
Brad Bishop | 02763c6 | 2018-12-12 22:02:07 -0500 | [diff] [blame] | 191 | auto& deserialize = |
| 192 | std::get<DeserializeInterfaceType<SerialOps>>( |
| 193 | opsit->second); |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 194 | deserialize(path, ifaceit->first, refaceit->second); |
| 195 | } |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 196 | } |
| 197 | catch (const InterfaceError& e) |
| 198 | { |
| 199 | // Reset the binding ops iterator since we are |
| 200 | // at the end. |
| 201 | opsit = _makers.cbegin(); |
| 202 | e.log(); |
| 203 | } |
| 204 | |
| 205 | ++ifaceit; |
| 206 | } |
| 207 | |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 208 | if (_status == ManagerStatus::RUNNING) |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 209 | { |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 210 | if (newObject) |
| 211 | { |
| 212 | _bus.emit_object_added(path.str.c_str()); |
| 213 | } |
| 214 | else if (!signals.empty()) |
| 215 | { |
| 216 | _bus.emit_interfaces_added(path.str.c_str(), signals); |
| 217 | } |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 218 | } |
| 219 | } |
| 220 | |
| 221 | void Manager::updateObjects( |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 222 | const std::map<sdbusplus::message::object_path, Object>& objs, |
| 223 | bool restoreFromCache) |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 224 | { |
| 225 | auto objit = objs.cbegin(); |
| 226 | auto refit = _refs.begin(); |
| 227 | std::string absPath; |
| 228 | bool newObj; |
| 229 | |
| 230 | while (objit != objs.cend()) |
| 231 | { |
| 232 | // Find the insertion point or the object to update. |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 233 | refit = std::lower_bound(refit, _refs.end(), objit->first, |
| 234 | compareFirst(RelPathCompare(_root))); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 235 | |
| 236 | absPath.assign(_root); |
| 237 | absPath.append(objit->first); |
| 238 | |
| 239 | newObj = false; |
| 240 | if (refit == _refs.end() || refit->first != absPath) |
| 241 | { |
| 242 | refit = _refs.insert( |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 243 | refit, std::make_pair(absPath, decltype(_refs)::mapped_type())); |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 244 | newObj = true; |
| 245 | } |
| 246 | |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 247 | updateInterfaces(absPath, objit->second, refit, newObj, |
| 248 | restoreFromCache); |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 249 | #ifdef CREATE_ASSOCIATIONS |
Matt Spinler | 59521e8 | 2021-02-11 13:41:06 -0600 | [diff] [blame] | 250 | if (!_associations.pendingCondition() && newObj) |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 251 | { |
Brad Bishop | 23a8d93 | 2020-12-06 19:40:13 -0500 | [diff] [blame] | 252 | _associations.createAssociations(absPath, |
Brad Bishop | ee294d6 | 2021-01-13 16:14:29 -0500 | [diff] [blame] | 253 | _status != ManagerStatus::RUNNING); |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 254 | } |
Matt Spinler | 59521e8 | 2021-02-11 13:41:06 -0600 | [diff] [blame] | 255 | else if (!restoreFromCache && |
| 256 | _associations.conditionMatch(objit->first, objit->second)) |
| 257 | { |
| 258 | // The objit path/interface/property matched a pending condition. |
| 259 | // Now the associations are valid so attempt to create them against |
| 260 | // all existing objects. If this was the restoreFromCache path, |
| 261 | // objit doesn't contain property values so don't bother checking. |
| 262 | std::for_each(_refs.begin(), _refs.end(), [this](const auto& ref) { |
| 263 | _associations.createAssociations( |
| 264 | ref.first, _status != ManagerStatus::RUNNING); |
| 265 | }); |
| 266 | } |
Matt Spinler | 852db67 | 2019-03-06 13:46:14 -0600 | [diff] [blame] | 267 | #endif |
Brad Bishop | 79ccaf7 | 2017-01-22 16:00:50 -0500 | [diff] [blame] | 268 | ++objit; |
| 269 | } |
| 270 | } |
| 271 | |
Brad Bishop | 03f4cd9 | 2017-02-03 15:17:21 -0500 | [diff] [blame] | 272 | void Manager::notify(std::map<sdbusplus::message::object_path, Object> objs) |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 273 | { |
Brad Bishop | cda036f | 2017-02-15 10:06:48 -0500 | [diff] [blame] | 274 | updateObjects(objs); |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 275 | } |
| 276 | |
Patrick Williams | 563306f | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 277 | void Manager::handleEvent(sdbusplus::message_t& msg, const Event& event, |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 278 | const EventInfo& info) |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 279 | { |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 280 | auto& actions = std::get<1>(info); |
Brad Bishop | 3d57f50 | 2016-10-19 12:18:41 -0400 | [diff] [blame] | 281 | |
Brad Bishop | 48547a8 | 2017-01-19 15:12:50 -0500 | [diff] [blame] | 282 | for (auto& f : event) |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 283 | { |
Brad Bishop | 07934a6 | 2017-02-08 23:34:59 -0500 | [diff] [blame] | 284 | if (!f(_bus, msg, *this)) |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 285 | { |
Brad Bishop | 064c94a | 2017-01-21 21:33:30 -0500 | [diff] [blame] | 286 | return; |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 287 | } |
Brad Bishop | 3d57f50 | 2016-10-19 12:18:41 -0400 | [diff] [blame] | 288 | } |
Brad Bishop | 064c94a | 2017-01-21 21:33:30 -0500 | [diff] [blame] | 289 | for (auto& action : actions) |
| 290 | { |
Brad Bishop | 07934a6 | 2017-02-08 23:34:59 -0500 | [diff] [blame] | 291 | action(_bus, *this); |
Brad Bishop | 064c94a | 2017-01-21 21:33:30 -0500 | [diff] [blame] | 292 | } |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 293 | } |
| 294 | |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 295 | void Manager::destroyObjects(const std::vector<const char*>& paths) |
Brad Bishop | 656a7d0 | 2016-10-19 22:20:02 -0400 | [diff] [blame] | 296 | { |
Brad Bishop | a5cc34c | 2017-02-03 20:57:36 -0500 | [diff] [blame] | 297 | std::string p; |
| 298 | |
Brad Bishop | 7b7e712 | 2017-01-21 21:21:46 -0500 | [diff] [blame] | 299 | for (const auto& path : paths) |
| 300 | { |
Brad Bishop | a5cc34c | 2017-02-03 20:57:36 -0500 | [diff] [blame] | 301 | p.assign(_root); |
| 302 | p.append(path); |
| 303 | _bus.emit_object_removed(p.c_str()); |
| 304 | _refs.erase(p); |
Brad Bishop | 7b7e712 | 2017-01-21 21:21:46 -0500 | [diff] [blame] | 305 | } |
Brad Bishop | 656a7d0 | 2016-10-19 22:20:02 -0400 | [diff] [blame] | 306 | } |
| 307 | |
Brad Bishop | eb68a68 | 2017-01-22 00:58:54 -0500 | [diff] [blame] | 308 | void Manager::createObjects( |
| 309 | const std::map<sdbusplus::message::object_path, Object>& objs) |
| 310 | { |
Brad Bishop | cda036f | 2017-02-15 10:06:48 -0500 | [diff] [blame] | 311 | updateObjects(objs); |
Brad Bishop | eb68a68 | 2017-01-22 00:58:54 -0500 | [diff] [blame] | 312 | } |
| 313 | |
Brad Bishop | 25d54b5 | 2018-11-21 12:57:51 -0500 | [diff] [blame] | 314 | std::any& Manager::getInterfaceHolder(const char* path, const char* interface) |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 315 | { |
Brad Bishop | 25d54b5 | 2018-11-21 12:57:51 -0500 | [diff] [blame] | 316 | return const_cast<std::any&>( |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 317 | const_cast<const Manager*>(this)->getInterfaceHolder(path, interface)); |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 318 | } |
| 319 | |
Patrick Williams | d8fba8b | 2024-08-16 15:20:15 -0400 | [diff] [blame^] | 320 | const std::any& |
| 321 | Manager::getInterfaceHolder(const char* path, const char* interface) const |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 322 | { |
| 323 | std::string p{path}; |
| 324 | auto oit = _refs.find(_root + p); |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 325 | if (oit == _refs.end()) |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 326 | throw std::runtime_error(_root + p + " was not found"); |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 327 | |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 328 | auto& obj = oit->second; |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 329 | auto iit = obj.find(interface); |
Brad Bishop | 7b33777 | 2017-01-12 16:11:24 -0500 | [diff] [blame] | 330 | if (iit == obj.end()) |
Brad Bishop | 615b2a8 | 2018-03-29 10:32:41 -0400 | [diff] [blame] | 331 | throw std::runtime_error("interface was not found"); |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 332 | |
Brad Bishop | 150147a | 2017-02-08 23:57:46 -0500 | [diff] [blame] | 333 | return iit->second; |
Brad Bishop | b83a21e | 2016-11-30 13:43:37 -0500 | [diff] [blame] | 334 | } |
| 335 | |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 336 | void Manager::restore() |
| 337 | { |
Kun Yi | e6b21c7 | 2019-03-27 09:53:51 -0700 | [diff] [blame] | 338 | namespace fs = std::filesystem; |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 339 | |
| 340 | if (!fs::exists(fs::path(PIM_PERSIST_PATH))) |
| 341 | { |
| 342 | return; |
| 343 | } |
| 344 | |
Patrick Williams | d8fba8b | 2024-08-16 15:20:15 -0400 | [diff] [blame^] | 345 | static const std::string remove = |
| 346 | std::string(PIM_PERSIST_PATH) + INVENTORY_ROOT; |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 347 | |
| 348 | std::map<sdbusplus::message::object_path, Object> objects; |
| 349 | for (const auto& dirent : |
| 350 | fs::recursive_directory_iterator(PIM_PERSIST_PATH)) |
| 351 | { |
| 352 | const auto& path = dirent.path(); |
| 353 | if (fs::is_regular_file(path)) |
| 354 | { |
| 355 | auto ifaceName = path.filename().string(); |
| 356 | auto objPath = path.parent_path().string(); |
| 357 | objPath.erase(0, remove.length()); |
| 358 | auto objit = objects.find(objPath); |
| 359 | Interface propertyMap{}; |
| 360 | if (objects.end() != objit) |
| 361 | { |
| 362 | auto& object = objit->second; |
| 363 | object.emplace(std::move(ifaceName), std::move(propertyMap)); |
| 364 | } |
| 365 | else |
| 366 | { |
| 367 | Object object; |
| 368 | object.emplace(std::move(ifaceName), std::move(propertyMap)); |
| 369 | objects.emplace(std::move(objPath), std::move(object)); |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | if (!objects.empty()) |
| 374 | { |
| 375 | auto restoreFromCache = true; |
| 376 | updateObjects(objects, restoreFromCache); |
Matt Spinler | 59521e8 | 2021-02-11 13:41:06 -0600 | [diff] [blame] | 377 | |
| 378 | #ifdef CREATE_ASSOCIATIONS |
| 379 | // There may be conditional associations waiting to be loaded |
| 380 | // based on certain path/interface/property values. Now that |
| 381 | // _refs contains all objects with their property values, check |
| 382 | // which property values the conditions need and set them in the |
| 383 | // condition structure entries, using the actualValue field. Then |
| 384 | // the associations manager can check if the conditions are met. |
| 385 | if (_associations.pendingCondition()) |
| 386 | { |
| 387 | ObjectReferences::iterator refIt; |
| 388 | InterfaceComposite::iterator ifaceIt; |
| 389 | |
| 390 | auto& conditions = _associations.getConditions(); |
| 391 | for (auto& condition : conditions) |
| 392 | { |
| 393 | refIt = _refs.find(_root + condition.path); |
| 394 | if (refIt != _refs.end()) |
| 395 | { |
| 396 | ifaceIt = refIt->second.find(condition.interface); |
| 397 | } |
| 398 | |
| 399 | if ((refIt != _refs.end()) && (ifaceIt != refIt->second.end())) |
| 400 | { |
| 401 | const auto& maker = _makers.find(condition.interface); |
| 402 | if (maker != _makers.end()) |
| 403 | { |
| 404 | auto& getProperty = |
| 405 | std::get<GetPropertyValueType>(maker->second); |
| 406 | |
Patrick Williams | d8fba8b | 2024-08-16 15:20:15 -0400 | [diff] [blame^] | 407 | condition.actualValue = |
| 408 | getProperty(condition.property, ifaceIt->second); |
Matt Spinler | 59521e8 | 2021-02-11 13:41:06 -0600 | [diff] [blame] | 409 | } |
| 410 | } |
| 411 | } |
| 412 | |
| 413 | // Check if a property value in a condition matches an |
| 414 | // actual property value just saved. If one did, now the |
| 415 | // associations file is valid so create its associations. |
| 416 | if (_associations.conditionMatch()) |
| 417 | { |
Patrick Williams | d8fba8b | 2024-08-16 15:20:15 -0400 | [diff] [blame^] | 418 | std::for_each( |
| 419 | _refs.begin(), _refs.end(), [this](const auto& ref) { |
| 420 | _associations.createAssociations( |
| 421 | ref.first, _status != ManagerStatus::RUNNING); |
| 422 | }); |
Matt Spinler | 59521e8 | 2021-02-11 13:41:06 -0600 | [diff] [blame] | 423 | } |
| 424 | } |
| 425 | #endif |
Deepak Kodihalli | b28990f | 2017-08-08 07:19:34 -0500 | [diff] [blame] | 426 | } |
| 427 | } |
| 428 | |
Brad Bishop | 49aefb3 | 2016-10-19 11:54:14 -0400 | [diff] [blame] | 429 | } // namespace manager |
| 430 | } // namespace inventory |
| 431 | } // namespace phosphor |
| 432 | |
| 433 | // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 |