135e83f3eSSaqib Khan #include <fstream> 2ec1b41c4SGunnar Mills #include <string> 32ce7da29SGunnar Mills #include <phosphor-logging/log.hpp> 4ec1b41c4SGunnar Mills #include "config.h" 52ce7da29SGunnar Mills #include "item_updater.hpp" 62ce7da29SGunnar Mills #include "xyz/openbmc_project/Software/Version/server.hpp" 735e83f3eSSaqib Khan #include <experimental/filesystem> 8705f1bfcSSaqib Khan #include "version.hpp" 9ec1b41c4SGunnar Mills 10ec1b41c4SGunnar Mills namespace phosphor 11ec1b41c4SGunnar Mills { 12ec1b41c4SGunnar Mills namespace software 13ec1b41c4SGunnar Mills { 14ec1b41c4SGunnar Mills namespace updater 15ec1b41c4SGunnar Mills { 16ec1b41c4SGunnar Mills 172ce7da29SGunnar Mills // When you see server:: you know we're referencing our base class 182ce7da29SGunnar Mills namespace server = sdbusplus::xyz::openbmc_project::Software::server; 192ce7da29SGunnar Mills 202ce7da29SGunnar Mills using namespace phosphor::logging; 2135e83f3eSSaqib Khan namespace fs = std::experimental::filesystem; 2235e83f3eSSaqib Khan 2335e83f3eSSaqib Khan constexpr auto bmcImage = "image-rofs"; 242ce7da29SGunnar Mills 25e75d10f5SPatrick Williams void ItemUpdater::createActivation(sdbusplus::message::message& msg) 26ec1b41c4SGunnar Mills { 2784a0e693SSaqib Khan 2884a0e693SSaqib Khan using SVersion = server::Version; 2984a0e693SSaqib Khan using VersionPurpose = SVersion::VersionPurpose; 3084a0e693SSaqib Khan namespace mesg = sdbusplus::message; 3184a0e693SSaqib Khan namespace variant_ns = mesg::variant_ns; 3284a0e693SSaqib Khan 3384a0e693SSaqib Khan mesg::object_path objPath; 3484a0e693SSaqib Khan auto purpose = VersionPurpose::Unknown; 35705f1bfcSSaqib Khan std::string version; 362ce7da29SGunnar Mills std::map<std::string, 372ce7da29SGunnar Mills std::map<std::string, 3884a0e693SSaqib Khan mesg::variant<std::string>>> interfaces; 39e75d10f5SPatrick Williams msg.read(objPath, interfaces); 402ce7da29SGunnar Mills std::string path(std::move(objPath)); 4119177d3eSSaqib Khan std::string filePath; 422ce7da29SGunnar Mills 432ce7da29SGunnar Mills for (const auto& intf : interfaces) 442ce7da29SGunnar Mills { 45705f1bfcSSaqib Khan if (intf.first == VERSION_IFACE) 462ce7da29SGunnar Mills { 472ce7da29SGunnar Mills for (const auto& property : intf.second) 482ce7da29SGunnar Mills { 49705f1bfcSSaqib Khan if (property.first == "Purpose") 502ce7da29SGunnar Mills { 5184a0e693SSaqib Khan auto value = SVersion::convertVersionPurposeFromString( 5284a0e693SSaqib Khan variant_ns::get<std::string>(property.second)); 5384a0e693SSaqib Khan if (value == VersionPurpose::BMC || 5484a0e693SSaqib Khan value == VersionPurpose::System) 5584a0e693SSaqib Khan { 5684a0e693SSaqib Khan purpose = value; 5784a0e693SSaqib Khan } 58705f1bfcSSaqib Khan } 59705f1bfcSSaqib Khan else if (property.first == "Version") 60705f1bfcSSaqib Khan { 6184a0e693SSaqib Khan version = variant_ns::get<std::string>(property.second); 62705f1bfcSSaqib Khan } 63705f1bfcSSaqib Khan } 64705f1bfcSSaqib Khan } 6519177d3eSSaqib Khan else if (intf.first == FILEPATH_IFACE) 6619177d3eSSaqib Khan { 6719177d3eSSaqib Khan for (const auto& property : intf.second) 6819177d3eSSaqib Khan { 6919177d3eSSaqib Khan if (property.first == "Path") 7019177d3eSSaqib Khan { 7184a0e693SSaqib Khan filePath = variant_ns::get<std::string>(property.second); 7219177d3eSSaqib Khan } 7319177d3eSSaqib Khan } 7419177d3eSSaqib Khan } 75705f1bfcSSaqib Khan } 76705f1bfcSSaqib Khan if (version.empty() || 7719177d3eSSaqib Khan filePath.empty() || 7884a0e693SSaqib Khan purpose == VersionPurpose::Unknown) 792ce7da29SGunnar Mills { 80e75d10f5SPatrick Williams return; 812ce7da29SGunnar Mills } 822ce7da29SGunnar Mills 832ce7da29SGunnar Mills // Version id is the last item in the path 842ce7da29SGunnar Mills auto pos = path.rfind("/"); 852ce7da29SGunnar Mills if (pos == std::string::npos) 862ce7da29SGunnar Mills { 872ce7da29SGunnar Mills log<level::ERR>("No version id found in object path", 882ce7da29SGunnar Mills entry("OBJPATH=%s", path)); 89e75d10f5SPatrick Williams return; 902ce7da29SGunnar Mills } 912ce7da29SGunnar Mills 922ce7da29SGunnar Mills auto versionId = path.substr(pos + 1); 932ce7da29SGunnar Mills 94e75d10f5SPatrick Williams if (activations.find(versionId) == activations.end()) 952ce7da29SGunnar Mills { 9635e83f3eSSaqib Khan // Determine the Activation state by processing the given image dir. 9735e83f3eSSaqib Khan auto activationState = server::Activation::Activations::Invalid; 9835e83f3eSSaqib Khan ItemUpdater::ActivationStatus result = ItemUpdater:: 9919177d3eSSaqib Khan validateSquashFSImage(filePath); 10035e83f3eSSaqib Khan if (result == ItemUpdater::ActivationStatus::ready) 10135e83f3eSSaqib Khan { 10235e83f3eSSaqib Khan activationState = server::Activation::Activations::Ready; 10335e83f3eSSaqib Khan } 10435e83f3eSSaqib Khan activations.insert(std::make_pair( 1052ce7da29SGunnar Mills versionId, 106ec1b41c4SGunnar Mills std::make_unique<Activation>( 10735e83f3eSSaqib Khan bus, 10835e83f3eSSaqib Khan path, 109*4c1aec09SSaqib Khan *this, 11035e83f3eSSaqib Khan versionId, 11135e83f3eSSaqib Khan activationState))); 112705f1bfcSSaqib Khan versions.insert(std::make_pair( 113705f1bfcSSaqib Khan versionId, 114705f1bfcSSaqib Khan std::make_unique<phosphor::software:: 115705f1bfcSSaqib Khan manager::Version>( 116705f1bfcSSaqib Khan bus, 117705f1bfcSSaqib Khan path, 118705f1bfcSSaqib Khan version, 119705f1bfcSSaqib Khan purpose, 12019177d3eSSaqib Khan filePath))); 1212ce7da29SGunnar Mills } 122e75d10f5SPatrick Williams return; 123ec1b41c4SGunnar Mills } 124ec1b41c4SGunnar Mills 125ba239881SSaqib Khan void ItemUpdater::processBMCImage() 126ba239881SSaqib Khan { 127ba239881SSaqib Khan auto purpose = server::Version::VersionPurpose::BMC; 128ba239881SSaqib Khan auto version = phosphor::software::manager::Version::getBMCVersion(); 129ba239881SSaqib Khan auto id = phosphor::software::manager::Version::getId(version); 130ba239881SSaqib Khan auto path = std::string{SOFTWARE_OBJPATH} + '/' + id; 131ba239881SSaqib Khan activations.insert(std::make_pair( 132ba239881SSaqib Khan id, 133ba239881SSaqib Khan std::make_unique<Activation>( 134ba239881SSaqib Khan bus, 135ba239881SSaqib Khan path, 136*4c1aec09SSaqib Khan *this, 137ba239881SSaqib Khan id, 138ba239881SSaqib Khan server::Activation::Activations::Active))); 139ba239881SSaqib Khan versions.insert(std::make_pair( 140ba239881SSaqib Khan id, 141ba239881SSaqib Khan std::make_unique<phosphor::software:: 142ba239881SSaqib Khan manager::Version>( 143ba239881SSaqib Khan bus, 144ba239881SSaqib Khan path, 145ba239881SSaqib Khan version, 146ba239881SSaqib Khan purpose, 147ba239881SSaqib Khan ""))); 148ba239881SSaqib Khan return; 149ba239881SSaqib Khan } 150ba239881SSaqib Khan 15135e83f3eSSaqib Khan ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage( 15219177d3eSSaqib Khan const std::string& filePath) 15335e83f3eSSaqib Khan { 15435e83f3eSSaqib Khan 15519177d3eSSaqib Khan fs::path file(filePath); 15635e83f3eSSaqib Khan file /= bmcImage; 15735e83f3eSSaqib Khan std::ifstream efile(file.c_str()); 15835e83f3eSSaqib Khan 15935e83f3eSSaqib Khan if (efile.good() == 1) 16035e83f3eSSaqib Khan { 16135e83f3eSSaqib Khan return ItemUpdater::ActivationStatus::ready; 16235e83f3eSSaqib Khan } 16335e83f3eSSaqib Khan else 16435e83f3eSSaqib Khan { 16519177d3eSSaqib Khan log<level::ERR>("Failed to find the BMC image."); 16635e83f3eSSaqib Khan return ItemUpdater::ActivationStatus::invalid; 16735e83f3eSSaqib Khan } 16835e83f3eSSaqib Khan } 16935e83f3eSSaqib Khan 170*4c1aec09SSaqib Khan void ItemUpdater::freePriority(uint8_t value) 171*4c1aec09SSaqib Khan { 172*4c1aec09SSaqib Khan //TODO openbmc/openbmc#1896 Improve the performance of this function 173*4c1aec09SSaqib Khan for (const auto& intf : activations) 174*4c1aec09SSaqib Khan { 175*4c1aec09SSaqib Khan if(intf.second->redundancyPriority) 176*4c1aec09SSaqib Khan { 177*4c1aec09SSaqib Khan if (intf.second->redundancyPriority.get()->priority() == value) 178*4c1aec09SSaqib Khan { 179*4c1aec09SSaqib Khan intf.second->redundancyPriority.get()->priority(value+1); 180*4c1aec09SSaqib Khan } 181*4c1aec09SSaqib Khan } 182*4c1aec09SSaqib Khan } 183*4c1aec09SSaqib Khan } 184*4c1aec09SSaqib Khan 185ec1b41c4SGunnar Mills } // namespace updater 186ec1b41c4SGunnar Mills } // namespace software 187ec1b41c4SGunnar Mills } // namespace phosphor 188