149aefb31SBrad Bishop /** 249aefb31SBrad Bishop * Copyright © 2016 IBM Corporation 349aefb31SBrad Bishop * 449aefb31SBrad Bishop * Licensed under the Apache License, Version 2.0 (the "License"); 549aefb31SBrad Bishop * you may not use this file except in compliance with the License. 649aefb31SBrad Bishop * You may obtain a copy of the License at 749aefb31SBrad Bishop * 849aefb31SBrad Bishop * http://www.apache.org/licenses/LICENSE-2.0 949aefb31SBrad Bishop * 1049aefb31SBrad Bishop * Unless required by applicable law or agreed to in writing, software 1149aefb31SBrad Bishop * distributed under the License is distributed on an "AS IS" BASIS, 1249aefb31SBrad Bishop * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349aefb31SBrad Bishop * See the License for the specific language governing permissions and 1449aefb31SBrad Bishop * limitations under the License. 1549aefb31SBrad Bishop */ 1649aefb31SBrad Bishop #include "manager.hpp" 17a680d1efSPatrick Venture 1879ccaf77SBrad Bishop #include "errors.hpp" 1949aefb31SBrad Bishop 20a83db30eSBrad Bishop #include <phosphor-logging/log.hpp> 21a83db30eSBrad Bishop 22a680d1efSPatrick Venture #include <algorithm> 23a680d1efSPatrick Venture #include <chrono> 24a680d1efSPatrick Venture #include <exception> 25e6b21c74SKun Yi #include <filesystem> 26a680d1efSPatrick Venture #include <iostream> 27a680d1efSPatrick Venture 2824424983SBrad Bishop using namespace std::literals::chrono_literals; 2924424983SBrad Bishop 3049aefb31SBrad Bishop namespace phosphor 3149aefb31SBrad Bishop { 3249aefb31SBrad Bishop namespace inventory 3349aefb31SBrad Bishop { 3449aefb31SBrad Bishop namespace manager 3549aefb31SBrad Bishop { 3649aefb31SBrad Bishop /** @brief Fowrarding signal callback. 3749aefb31SBrad Bishop * 3849aefb31SBrad Bishop * Extracts per-signal specific context and forwards the call to the manager 3949aefb31SBrad Bishop * instance. 4049aefb31SBrad Bishop */ 4149aefb31SBrad Bishop auto _signal(sd_bus_message* m, void* data, sd_bus_error* e) noexcept 4249aefb31SBrad Bishop { 437b33777bSBrad Bishop try 447b33777bSBrad Bishop { 4549aefb31SBrad Bishop auto msg = sdbusplus::message::message(m); 4649aefb31SBrad Bishop auto& args = *static_cast<Manager::SigArg*>(data); 4749aefb31SBrad Bishop sd_bus_message_ref(m); 4849aefb31SBrad Bishop auto& mgr = *std::get<0>(args); 49615b2a8fSBrad Bishop mgr.handleEvent(msg, static_cast<const DbusSignal&>(*std::get<1>(args)), 5068c80839SBrad Bishop *std::get<2>(args)); 5149aefb31SBrad Bishop } 527b33777bSBrad Bishop catch (const std::exception& e) 537b33777bSBrad Bishop { 5449aefb31SBrad Bishop std::cerr << e.what() << std::endl; 5549aefb31SBrad Bishop } 5649aefb31SBrad Bishop 5749aefb31SBrad Bishop return 0; 5849aefb31SBrad Bishop } 5949aefb31SBrad Bishop 6020c9435cSBrad Bishop Manager::Manager(sdbusplus::bus::bus&& bus, const char* root) : 614627a9ccSBrad Bishop ServerObject<ManagerIface>(bus, root), _root(root), _bus(std::move(bus)), 624627a9ccSBrad Bishop _manager(_bus, root), 63852db67bSMatt Spinler #ifdef CREATE_ASSOCIATIONS 644627a9ccSBrad Bishop _associations(_bus), 65852db67bSMatt Spinler #endif 664627a9ccSBrad Bishop _status(ManagerStatus::STARTING) 6749aefb31SBrad Bishop { 6868c80839SBrad Bishop for (auto& group : _events) 6968c80839SBrad Bishop { 70615b2a8fSBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>(group)) 7168c80839SBrad Bishop { 72615b2a8fSBrad Bishop if (pEvent->type != Event::Type::DBUS_SIGNAL) 737b33777bSBrad Bishop { 744f20a3e3SBrad Bishop continue; 757b33777bSBrad Bishop } 764f20a3e3SBrad Bishop 7768c80839SBrad Bishop // Create a callback context for this event group. 78615b2a8fSBrad Bishop auto dbusEvent = static_cast<DbusSignal*>(pEvent.get()); 7968c80839SBrad Bishop 8068c80839SBrad Bishop // Go ahead and store an iterator pointing at 8168c80839SBrad Bishop // the event data to avoid lookups later since 8268c80839SBrad Bishop // additional signal callbacks aren't added 8368c80839SBrad Bishop // after the manager is constructed. 8449aefb31SBrad Bishop _sigargs.emplace_back( 85615b2a8fSBrad Bishop std::make_unique<SigArg>(this, dbusEvent, &group)); 8668c80839SBrad Bishop 8749aefb31SBrad Bishop // Register our callback and the context for 8868c80839SBrad Bishop // each signal event. 89615b2a8fSBrad Bishop _matches.emplace_back(_bus, dbusEvent->signature, _signal, 901ab880a1SBrad Bishop _sigargs.back().get()); 9149aefb31SBrad Bishop } 9268c80839SBrad Bishop } 9349aefb31SBrad Bishop 94b28990f3SDeepak Kodihalli // Restore any persistent inventory 95b28990f3SDeepak Kodihalli restore(); 9649aefb31SBrad Bishop } 9749aefb31SBrad Bishop 9849aefb31SBrad Bishop void Manager::shutdown() noexcept 9949aefb31SBrad Bishop { 1004627a9ccSBrad Bishop _status = ManagerStatus::STOPPING; 10149aefb31SBrad Bishop } 10249aefb31SBrad Bishop 10320c9435cSBrad Bishop void Manager::run(const char* busname) 10449aefb31SBrad Bishop { 1053e4a19a3SBrad Bishop sdbusplus::message::message unusedMsg{nullptr}; 1063e4a19a3SBrad Bishop 1073e4a19a3SBrad Bishop // Run startup events. 1083e4a19a3SBrad Bishop for (auto& group : _events) 1093e4a19a3SBrad Bishop { 110615b2a8fSBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>(group)) 1113e4a19a3SBrad Bishop { 112615b2a8fSBrad Bishop if (pEvent->type == Event::Type::STARTUP) 1133e4a19a3SBrad Bishop { 1143e4a19a3SBrad Bishop handleEvent(unusedMsg, *pEvent, group); 1153e4a19a3SBrad Bishop } 1163e4a19a3SBrad Bishop } 1173e4a19a3SBrad Bishop } 1183e4a19a3SBrad Bishop 1194627a9ccSBrad Bishop _status = ManagerStatus::RUNNING; 12020c9435cSBrad Bishop _bus.request_name(busname); 1214627a9ccSBrad Bishop 1224627a9ccSBrad Bishop while (_status != ManagerStatus::STOPPING) 1237b33777bSBrad Bishop { 1247b33777bSBrad Bishop try 1257b33777bSBrad Bishop { 12649aefb31SBrad Bishop _bus.process_discard(); 12724424983SBrad Bishop _bus.wait((5000000us).count()); 12849aefb31SBrad Bishop } 1297b33777bSBrad Bishop catch (const std::exception& e) 1307b33777bSBrad Bishop { 13149aefb31SBrad Bishop std::cerr << e.what() << std::endl; 13249aefb31SBrad Bishop } 13349aefb31SBrad Bishop } 13449aefb31SBrad Bishop } 13549aefb31SBrad Bishop 136615b2a8fSBrad Bishop void Manager::updateInterfaces(const sdbusplus::message::object_path& path, 13779ccaf77SBrad Bishop const Object& interfaces, 138615b2a8fSBrad Bishop ObjectReferences::iterator pos, bool newObject, 139b28990f3SDeepak Kodihalli bool restoreFromCache) 14079ccaf77SBrad Bishop { 14179ccaf77SBrad Bishop auto& refaces = pos->second; 14279ccaf77SBrad Bishop auto ifaceit = interfaces.cbegin(); 14379ccaf77SBrad Bishop auto opsit = _makers.cbegin(); 14479ccaf77SBrad Bishop auto refaceit = refaces.begin(); 14579ccaf77SBrad Bishop std::vector<std::string> signals; 14679ccaf77SBrad Bishop 14779ccaf77SBrad Bishop while (ifaceit != interfaces.cend()) 14879ccaf77SBrad Bishop { 14979ccaf77SBrad Bishop try 15079ccaf77SBrad Bishop { 15179ccaf77SBrad Bishop // Find the binding ops for this interface. 152615b2a8fSBrad Bishop opsit = std::lower_bound(opsit, _makers.cend(), ifaceit->first, 15379ccaf77SBrad Bishop compareFirst(_makers.key_comp())); 15479ccaf77SBrad Bishop 15579ccaf77SBrad Bishop if (opsit == _makers.cend() || opsit->first != ifaceit->first) 15679ccaf77SBrad Bishop { 15779ccaf77SBrad Bishop // This interface is not supported. 158615b2a8fSBrad Bishop throw InterfaceError("Encountered unsupported interface.", 15979ccaf77SBrad Bishop ifaceit->first); 16079ccaf77SBrad Bishop } 16179ccaf77SBrad Bishop 16279ccaf77SBrad Bishop // Find the binding insertion point or the binding to update. 163615b2a8fSBrad Bishop refaceit = std::lower_bound(refaceit, refaces.end(), ifaceit->first, 16479ccaf77SBrad Bishop compareFirst(refaces.key_comp())); 16579ccaf77SBrad Bishop 16679ccaf77SBrad Bishop if (refaceit == refaces.end() || refaceit->first != ifaceit->first) 16779ccaf77SBrad Bishop { 16879ccaf77SBrad Bishop // Add the new interface. 16902763c68SBrad Bishop auto& ctor = std::get<MakeInterfaceType>(opsit->second); 17023a8d935SBrad Bishop // skipSignal = true here to avoid getting PropertiesChanged 17123a8d935SBrad Bishop // signals while the interface is constructed. We'll emit an 17223a8d935SBrad Bishop // ObjectManager signal for this interface below. 17379ccaf77SBrad Bishop refaceit = refaces.insert( 174e96f2aa7SBrad Bishop refaceit, std::make_pair(ifaceit->first, 175e96f2aa7SBrad Bishop ctor(_bus, path.str.c_str(), 17623a8d935SBrad Bishop ifaceit->second, true))); 17779ccaf77SBrad Bishop signals.push_back(ifaceit->first); 17879ccaf77SBrad Bishop } 17979ccaf77SBrad Bishop else 18079ccaf77SBrad Bishop { 18179ccaf77SBrad Bishop // Set the new property values. 18202763c68SBrad Bishop auto& assign = std::get<AssignInterfaceType>(opsit->second); 18323a8d935SBrad Bishop assign(ifaceit->second, refaceit->second, 18423a8d935SBrad Bishop _status != ManagerStatus::RUNNING); 18579ccaf77SBrad Bishop } 186b28990f3SDeepak Kodihalli if (!restoreFromCache) 187b28990f3SDeepak Kodihalli { 18802763c68SBrad Bishop auto& serialize = 18902763c68SBrad Bishop std::get<SerializeInterfaceType<SerialOps>>(opsit->second); 1906620e98dSDeepak Kodihalli serialize(path, ifaceit->first, refaceit->second); 19179ccaf77SBrad Bishop } 192b28990f3SDeepak Kodihalli else 193b28990f3SDeepak Kodihalli { 19402763c68SBrad Bishop auto& deserialize = 19502763c68SBrad Bishop std::get<DeserializeInterfaceType<SerialOps>>( 19602763c68SBrad Bishop opsit->second); 197b28990f3SDeepak Kodihalli deserialize(path, ifaceit->first, refaceit->second); 198b28990f3SDeepak Kodihalli } 199b28990f3SDeepak Kodihalli } 20079ccaf77SBrad Bishop catch (const InterfaceError& e) 20179ccaf77SBrad Bishop { 20279ccaf77SBrad Bishop // Reset the binding ops iterator since we are 20379ccaf77SBrad Bishop // at the end. 20479ccaf77SBrad Bishop opsit = _makers.cbegin(); 20579ccaf77SBrad Bishop e.log(); 20679ccaf77SBrad Bishop } 20779ccaf77SBrad Bishop 20879ccaf77SBrad Bishop ++ifaceit; 20979ccaf77SBrad Bishop } 21079ccaf77SBrad Bishop 21123a8d935SBrad Bishop if (_status == ManagerStatus::RUNNING) 21223a8d935SBrad Bishop { 21379ccaf77SBrad Bishop if (newObject) 21479ccaf77SBrad Bishop { 21579ccaf77SBrad Bishop _bus.emit_object_added(path.str.c_str()); 21679ccaf77SBrad Bishop } 21779ccaf77SBrad Bishop else if (!signals.empty()) 21879ccaf77SBrad Bishop { 219a8ff8154SGunnar Mills _bus.emit_interfaces_added(path.str.c_str(), signals); 22079ccaf77SBrad Bishop } 22179ccaf77SBrad Bishop } 22223a8d935SBrad Bishop } 22379ccaf77SBrad Bishop 22479ccaf77SBrad Bishop void Manager::updateObjects( 225b28990f3SDeepak Kodihalli const std::map<sdbusplus::message::object_path, Object>& objs, 226b28990f3SDeepak Kodihalli bool restoreFromCache) 22779ccaf77SBrad Bishop { 22879ccaf77SBrad Bishop auto objit = objs.cbegin(); 22979ccaf77SBrad Bishop auto refit = _refs.begin(); 23079ccaf77SBrad Bishop std::string absPath; 23179ccaf77SBrad Bishop bool newObj; 23279ccaf77SBrad Bishop 23379ccaf77SBrad Bishop while (objit != objs.cend()) 23479ccaf77SBrad Bishop { 23579ccaf77SBrad Bishop // Find the insertion point or the object to update. 236615b2a8fSBrad Bishop refit = std::lower_bound(refit, _refs.end(), objit->first, 23779ccaf77SBrad Bishop compareFirst(RelPathCompare(_root))); 23879ccaf77SBrad Bishop 23979ccaf77SBrad Bishop absPath.assign(_root); 24079ccaf77SBrad Bishop absPath.append(objit->first); 24179ccaf77SBrad Bishop 24279ccaf77SBrad Bishop newObj = false; 24379ccaf77SBrad Bishop if (refit == _refs.end() || refit->first != absPath) 24479ccaf77SBrad Bishop { 24579ccaf77SBrad Bishop refit = _refs.insert( 246615b2a8fSBrad Bishop refit, std::make_pair(absPath, decltype(_refs)::mapped_type())); 24779ccaf77SBrad Bishop newObj = true; 24879ccaf77SBrad Bishop } 24979ccaf77SBrad Bishop 250b28990f3SDeepak Kodihalli updateInterfaces(absPath, objit->second, refit, newObj, 251b28990f3SDeepak Kodihalli restoreFromCache); 252852db67bSMatt Spinler #ifdef CREATE_ASSOCIATIONS 253*59521e87SMatt Spinler if (!_associations.pendingCondition() && newObj) 254852db67bSMatt Spinler { 25523a8d935SBrad Bishop _associations.createAssociations(absPath, 256ee294d68SBrad Bishop _status != ManagerStatus::RUNNING); 257852db67bSMatt Spinler } 258*59521e87SMatt Spinler else if (!restoreFromCache && 259*59521e87SMatt Spinler _associations.conditionMatch(objit->first, objit->second)) 260*59521e87SMatt Spinler { 261*59521e87SMatt Spinler // The objit path/interface/property matched a pending condition. 262*59521e87SMatt Spinler // Now the associations are valid so attempt to create them against 263*59521e87SMatt Spinler // all existing objects. If this was the restoreFromCache path, 264*59521e87SMatt Spinler // objit doesn't contain property values so don't bother checking. 265*59521e87SMatt Spinler std::for_each(_refs.begin(), _refs.end(), [this](const auto& ref) { 266*59521e87SMatt Spinler _associations.createAssociations( 267*59521e87SMatt Spinler ref.first, _status != ManagerStatus::RUNNING); 268*59521e87SMatt Spinler }); 269*59521e87SMatt Spinler } 270852db67bSMatt Spinler #endif 27179ccaf77SBrad Bishop ++objit; 27279ccaf77SBrad Bishop } 27379ccaf77SBrad Bishop } 27479ccaf77SBrad Bishop 27503f4cd95SBrad Bishop void Manager::notify(std::map<sdbusplus::message::object_path, Object> objs) 27649aefb31SBrad Bishop { 277cda036f7SBrad Bishop updateObjects(objs); 27849aefb31SBrad Bishop } 27949aefb31SBrad Bishop 280615b2a8fSBrad Bishop void Manager::handleEvent(sdbusplus::message::message& msg, const Event& event, 28168c80839SBrad Bishop const EventInfo& info) 28249aefb31SBrad Bishop { 28368c80839SBrad Bishop auto& actions = std::get<1>(info); 2843d57f507SBrad Bishop 28548547a85SBrad Bishop for (auto& f : event) 2867b33777bSBrad Bishop { 28707934a64SBrad Bishop if (!f(_bus, msg, *this)) 288064c94a6SBrad Bishop { 289064c94a6SBrad Bishop return; 290064c94a6SBrad Bishop } 291064c94a6SBrad Bishop } 2929007432aSBrad Bishop for (auto& action : actions) 2937b33777bSBrad Bishop { 29407934a64SBrad Bishop action(_bus, *this); 2953d57f507SBrad Bishop } 29649aefb31SBrad Bishop } 29749aefb31SBrad Bishop 298615b2a8fSBrad Bishop void Manager::destroyObjects(const std::vector<const char*>& paths) 2997b7e712cSBrad Bishop { 300a5cc34c2SBrad Bishop std::string p; 301a5cc34c2SBrad Bishop 3027b7e712cSBrad Bishop for (const auto& path : paths) 303656a7d00SBrad Bishop { 304a5cc34c2SBrad Bishop p.assign(_root); 305a5cc34c2SBrad Bishop p.append(path); 306a5cc34c2SBrad Bishop _bus.emit_object_removed(p.c_str()); 307a5cc34c2SBrad Bishop _refs.erase(p); 308656a7d00SBrad Bishop } 3097b7e712cSBrad Bishop } 310656a7d00SBrad Bishop 311eb68a687SBrad Bishop void Manager::createObjects( 312eb68a687SBrad Bishop const std::map<sdbusplus::message::object_path, Object>& objs) 313eb68a687SBrad Bishop { 314cda036f7SBrad Bishop updateObjects(objs); 315eb68a687SBrad Bishop } 316eb68a687SBrad Bishop 31725d54b51SBrad Bishop std::any& Manager::getInterfaceHolder(const char* path, const char* interface) 318b83a21eaSBrad Bishop { 31925d54b51SBrad Bishop return const_cast<std::any&>( 320615b2a8fSBrad Bishop const_cast<const Manager*>(this)->getInterfaceHolder(path, interface)); 321b83a21eaSBrad Bishop } 322b83a21eaSBrad Bishop 32325d54b51SBrad Bishop const std::any& Manager::getInterfaceHolder(const char* path, 324615b2a8fSBrad Bishop const char* interface) const 325b83a21eaSBrad Bishop { 326b83a21eaSBrad Bishop std::string p{path}; 327b83a21eaSBrad Bishop auto oit = _refs.find(_root + p); 328b83a21eaSBrad Bishop if (oit == _refs.end()) 329615b2a8fSBrad Bishop throw std::runtime_error(_root + p + " was not found"); 330b83a21eaSBrad Bishop 331b83a21eaSBrad Bishop auto& obj = oit->second; 332b83a21eaSBrad Bishop auto iit = obj.find(interface); 333b83a21eaSBrad Bishop if (iit == obj.end()) 334615b2a8fSBrad Bishop throw std::runtime_error("interface was not found"); 335b83a21eaSBrad Bishop 336150147aeSBrad Bishop return iit->second; 337b83a21eaSBrad Bishop } 338b83a21eaSBrad Bishop 339b28990f3SDeepak Kodihalli void Manager::restore() 340b28990f3SDeepak Kodihalli { 341e6b21c74SKun Yi namespace fs = std::filesystem; 342b28990f3SDeepak Kodihalli 343b28990f3SDeepak Kodihalli if (!fs::exists(fs::path(PIM_PERSIST_PATH))) 344b28990f3SDeepak Kodihalli { 345b28990f3SDeepak Kodihalli return; 346b28990f3SDeepak Kodihalli } 347b28990f3SDeepak Kodihalli 348b28990f3SDeepak Kodihalli static const std::string remove = 349b28990f3SDeepak Kodihalli std::string(PIM_PERSIST_PATH) + INVENTORY_ROOT; 350b28990f3SDeepak Kodihalli 351b28990f3SDeepak Kodihalli std::map<sdbusplus::message::object_path, Object> objects; 352b28990f3SDeepak Kodihalli for (const auto& dirent : 353b28990f3SDeepak Kodihalli fs::recursive_directory_iterator(PIM_PERSIST_PATH)) 354b28990f3SDeepak Kodihalli { 355b28990f3SDeepak Kodihalli const auto& path = dirent.path(); 356b28990f3SDeepak Kodihalli if (fs::is_regular_file(path)) 357b28990f3SDeepak Kodihalli { 358b28990f3SDeepak Kodihalli auto ifaceName = path.filename().string(); 359b28990f3SDeepak Kodihalli auto objPath = path.parent_path().string(); 360b28990f3SDeepak Kodihalli objPath.erase(0, remove.length()); 361b28990f3SDeepak Kodihalli auto objit = objects.find(objPath); 362b28990f3SDeepak Kodihalli Interface propertyMap{}; 363b28990f3SDeepak Kodihalli if (objects.end() != objit) 364b28990f3SDeepak Kodihalli { 365b28990f3SDeepak Kodihalli auto& object = objit->second; 366b28990f3SDeepak Kodihalli object.emplace(std::move(ifaceName), std::move(propertyMap)); 367b28990f3SDeepak Kodihalli } 368b28990f3SDeepak Kodihalli else 369b28990f3SDeepak Kodihalli { 370b28990f3SDeepak Kodihalli Object object; 371b28990f3SDeepak Kodihalli object.emplace(std::move(ifaceName), std::move(propertyMap)); 372b28990f3SDeepak Kodihalli objects.emplace(std::move(objPath), std::move(object)); 373b28990f3SDeepak Kodihalli } 374b28990f3SDeepak Kodihalli } 375b28990f3SDeepak Kodihalli } 376b28990f3SDeepak Kodihalli if (!objects.empty()) 377b28990f3SDeepak Kodihalli { 378b28990f3SDeepak Kodihalli auto restoreFromCache = true; 379b28990f3SDeepak Kodihalli updateObjects(objects, restoreFromCache); 380*59521e87SMatt Spinler 381*59521e87SMatt Spinler #ifdef CREATE_ASSOCIATIONS 382*59521e87SMatt Spinler // There may be conditional associations waiting to be loaded 383*59521e87SMatt Spinler // based on certain path/interface/property values. Now that 384*59521e87SMatt Spinler // _refs contains all objects with their property values, check 385*59521e87SMatt Spinler // which property values the conditions need and set them in the 386*59521e87SMatt Spinler // condition structure entries, using the actualValue field. Then 387*59521e87SMatt Spinler // the associations manager can check if the conditions are met. 388*59521e87SMatt Spinler if (_associations.pendingCondition()) 389*59521e87SMatt Spinler { 390*59521e87SMatt Spinler ObjectReferences::iterator refIt; 391*59521e87SMatt Spinler InterfaceComposite::iterator ifaceIt; 392*59521e87SMatt Spinler 393*59521e87SMatt Spinler auto& conditions = _associations.getConditions(); 394*59521e87SMatt Spinler for (auto& condition : conditions) 395*59521e87SMatt Spinler { 396*59521e87SMatt Spinler refIt = _refs.find(_root + condition.path); 397*59521e87SMatt Spinler if (refIt != _refs.end()) 398*59521e87SMatt Spinler { 399*59521e87SMatt Spinler ifaceIt = refIt->second.find(condition.interface); 400*59521e87SMatt Spinler } 401*59521e87SMatt Spinler 402*59521e87SMatt Spinler if ((refIt != _refs.end()) && (ifaceIt != refIt->second.end())) 403*59521e87SMatt Spinler { 404*59521e87SMatt Spinler const auto& maker = _makers.find(condition.interface); 405*59521e87SMatt Spinler if (maker != _makers.end()) 406*59521e87SMatt Spinler { 407*59521e87SMatt Spinler auto& getProperty = 408*59521e87SMatt Spinler std::get<GetPropertyValueType>(maker->second); 409*59521e87SMatt Spinler 410*59521e87SMatt Spinler condition.actualValue = 411*59521e87SMatt Spinler getProperty(condition.property, ifaceIt->second); 412*59521e87SMatt Spinler } 413*59521e87SMatt Spinler } 414*59521e87SMatt Spinler } 415*59521e87SMatt Spinler 416*59521e87SMatt Spinler // Check if a property value in a condition matches an 417*59521e87SMatt Spinler // actual property value just saved. If one did, now the 418*59521e87SMatt Spinler // associations file is valid so create its associations. 419*59521e87SMatt Spinler if (_associations.conditionMatch()) 420*59521e87SMatt Spinler { 421*59521e87SMatt Spinler std::for_each( 422*59521e87SMatt Spinler _refs.begin(), _refs.end(), [this](const auto& ref) { 423*59521e87SMatt Spinler _associations.createAssociations( 424*59521e87SMatt Spinler ref.first, _status != ManagerStatus::RUNNING); 425*59521e87SMatt Spinler }); 426*59521e87SMatt Spinler } 427*59521e87SMatt Spinler } 428*59521e87SMatt Spinler #endif 429b28990f3SDeepak Kodihalli } 430b28990f3SDeepak Kodihalli } 431b28990f3SDeepak Kodihalli 43249aefb31SBrad Bishop } // namespace manager 43349aefb31SBrad Bishop } // namespace inventory 43449aefb31SBrad Bishop } // namespace phosphor 43549aefb31SBrad Bishop 43649aefb31SBrad Bishop // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 437