1 #include "config.h" 2 3 #include "item_updater.hpp" 4 5 #include "xyz/openbmc_project/Common/error.hpp" 6 7 #include <phosphor-logging/elog-errors.hpp> 8 #include <phosphor-logging/log.hpp> 9 10 namespace openpower 11 { 12 namespace software 13 { 14 namespace updater 15 { 16 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 17 using namespace phosphor::logging; 18 19 void ItemUpdater::createActiveAssociation(const std::string& path) 20 { 21 assocs.emplace_back( 22 std::make_tuple(ACTIVE_FWD_ASSOCIATION, ACTIVE_REV_ASSOCIATION, path)); 23 associations(assocs); 24 } 25 26 void ItemUpdater::updateFunctionalAssociation(const std::string& versionId) 27 { 28 std::string path = std::string{SOFTWARE_OBJPATH} + '/' + versionId; 29 // remove all functional associations 30 for (auto iter = assocs.begin(); iter != assocs.end();) 31 { 32 if ((std::get<0>(*iter)).compare(FUNCTIONAL_FWD_ASSOCIATION) == 0) 33 { 34 iter = assocs.erase(iter); 35 } 36 else 37 { 38 ++iter; 39 } 40 } 41 assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION, 42 FUNCTIONAL_REV_ASSOCIATION, path)); 43 associations(assocs); 44 } 45 46 void ItemUpdater::removeAssociation(const std::string& path) 47 { 48 for (auto iter = assocs.begin(); iter != assocs.end();) 49 { 50 if ((std::get<2>(*iter)).compare(path) == 0) 51 { 52 iter = assocs.erase(iter); 53 associations(assocs); 54 } 55 else 56 { 57 ++iter; 58 } 59 } 60 } 61 62 bool ItemUpdater::erase(std::string entryId) 63 { 64 if (isVersionFunctional(entryId) && isChassisOn()) 65 { 66 log<level::ERR>(("Error: Version " + entryId + 67 " is currently active and running on the host." 68 " Unable to remove.") 69 .c_str()); 70 return false; 71 } 72 73 // Removing entry in versions map 74 auto it = versions.find(entryId); 75 if (it == versions.end()) 76 { 77 log<level::ERR>(("Error: Failed to find version " + entryId + 78 " in item updater versions map." 79 " Unable to remove.") 80 .c_str()); 81 } 82 else 83 { 84 versions.erase(entryId); 85 } 86 87 // Removing entry in activations map 88 auto ita = activations.find(entryId); 89 if (ita == activations.end()) 90 { 91 log<level::ERR>(("Error: Failed to find version " + entryId + 92 " in item updater activations map." 93 " Unable to remove.") 94 .c_str()); 95 } 96 else 97 { 98 removeAssociation(ita->second->path); 99 activations.erase(entryId); 100 } 101 return true; 102 } 103 104 bool ItemUpdater::isChassisOn() 105 { 106 auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, 107 MAPPER_INTERFACE, "GetObject"); 108 109 mapperCall.append(CHASSIS_STATE_PATH, 110 std::vector<std::string>({CHASSIS_STATE_OBJ})); 111 auto mapperResponseMsg = bus.call(mapperCall); 112 if (mapperResponseMsg.is_method_error()) 113 { 114 log<level::ERR>("Error in Mapper call"); 115 elog<InternalFailure>(); 116 } 117 using MapperResponseType = std::map<std::string, std::vector<std::string>>; 118 MapperResponseType mapperResponse; 119 mapperResponseMsg.read(mapperResponse); 120 if (mapperResponse.empty()) 121 { 122 log<level::ERR>("Invalid Response from mapper"); 123 elog<InternalFailure>(); 124 } 125 126 auto method = bus.new_method_call((mapperResponse.begin()->first).c_str(), 127 CHASSIS_STATE_PATH, 128 SYSTEMD_PROPERTY_INTERFACE, "Get"); 129 method.append(CHASSIS_STATE_OBJ, "CurrentPowerState"); 130 auto response = bus.call(method); 131 if (response.is_method_error()) 132 { 133 log<level::ERR>("Error in fetching current Chassis State", 134 entry("MAPPERRESPONSE=%s", 135 (mapperResponse.begin()->first).c_str())); 136 elog<InternalFailure>(); 137 } 138 sdbusplus::message::variant<std::string> currentChassisState; 139 response.read(currentChassisState); 140 auto strParam = 141 sdbusplus::message::variant_ns::get<std::string>(currentChassisState); 142 return (strParam != CHASSIS_STATE_OFF); 143 } 144 145 } // namespace updater 146 } // namespace software 147 } // namespace openpower 148