1 #include "config.h" 2 3 #ifdef UBIFS_LAYOUT 4 #include "ubi/item_updater_ubi.hpp" 5 #include "ubi/watch.hpp" 6 #elif defined MMC_LAYOUT 7 #include "mmc/item_updater_mmc.hpp" 8 #else 9 #include "static/item_updater_static.hpp" 10 #endif 11 #include "functions.hpp" 12 13 #include <CLI/CLI.hpp> 14 #include <phosphor-logging/log.hpp> 15 #include <sdbusplus/bus.hpp> 16 #include <sdbusplus/server/manager.hpp> 17 #include <sdeventplus/event.hpp> 18 19 #include <map> 20 #include <memory> 21 #include <string> 22 #include <system_error> 23 #include <vector> 24 25 namespace openpower 26 { 27 namespace software 28 { 29 namespace updater 30 { 31 void initializeService(sdbusplus::bus_t& bus) 32 { 33 static sdbusplus::server::manager_t objManager(bus, SOFTWARE_OBJPATH); 34 #ifdef UBIFS_LAYOUT 35 static ItemUpdaterUbi updater(bus, SOFTWARE_OBJPATH); 36 static Watch watch( 37 bus.get_event(), 38 std::bind(std::mem_fn(&ItemUpdater::updateFunctionalAssociation), 39 &updater, std::placeholders::_1)); 40 #elif defined MMC_LAYOUT 41 static ItemUpdaterMMC updater(bus, SOFTWARE_OBJPATH); 42 #else 43 static ItemUpdaterStatic updater(bus, SOFTWARE_OBJPATH); 44 #endif 45 bus.request_name(BUSNAME_UPDATER); 46 } 47 } // namespace updater 48 } // namespace software 49 } // namespace openpower 50 51 int main(int argc, char* argv[]) 52 { 53 using namespace openpower::software::updater; 54 using namespace phosphor::logging; 55 auto bus = sdbusplus::bus::new_default(); 56 auto loop = sdeventplus::Event::get_default(); 57 58 bus.attach_event(loop.get(), SD_EVENT_PRIORITY_NORMAL); 59 60 CLI::App app{"OpenPOWER host firmware manager"}; 61 62 using namespace std::string_literals; 63 std::map<std::string, std::vector<std::string>> extensionMap{{ 64 {"ibm,everest"s, {".EVEREST_XML"s, ".P10"s}}, 65 {"ibm,rainier-2u"s, {".RAINIER_2U_XML"s, ".P10"s}}, 66 {"ibm,rainier-4u"s, {".RAINIER_4U_XML"s, ".P10"s}}, 67 {"ibm,rainier-1s4u"s, {".RAINIER_4U_XML"s, ".P10"s}}, 68 }}; 69 70 // subcommandContext allows program subcommand callbacks to add loop event 71 // callbacks (e.g. reception of a dbus signal) and then return to main, 72 // without the loop event callback being destroyed until the loop event 73 // callback has a chance to run and instruct the loop to exit. 74 std::vector<std::shared_ptr<void>> subcommandContext; 75 static_cast<void>( 76 app.add_subcommand("process-host-firmware", 77 "Point the host firmware at its data.") 78 ->callback([&bus, &loop, &subcommandContext, extensionMap]() { 79 auto hostFirmwareDirectory = "/media/hostfw/running"s; 80 auto logCallback = [](const auto& path, auto& ec) { 81 std::cerr << path << ": " << ec.message() << "\n"; 82 }; 83 subcommandContext.push_back( 84 functions::process_hostfirmware::processHostFirmware( 85 bus, extensionMap, std::move(hostFirmwareDirectory), 86 std::move(logCallback), loop)); 87 })); 88 static_cast<void>( 89 app.add_subcommand("update-bios-attr-table", 90 "Update the bios attribute table with the host " 91 "firmware data details.") 92 ->callback([&bus, &loop, &subcommandContext, extensionMap]() { 93 auto elementsJsonFilePath = "/usr/share/hostfw/elements.json"s; 94 auto subcommands = 95 functions::process_hostfirmware::updateBiosAttrTable( 96 bus, extensionMap, std::move(elementsJsonFilePath), 97 loop); 98 for (const auto& subcommand : subcommands) 99 { 100 subcommandContext.push_back(subcommand); 101 } 102 })); 103 104 CLI11_PARSE(app, argc, argv); 105 106 if (app.get_subcommands().size() == 0) 107 { 108 initializeService(bus); 109 } 110 111 try 112 { 113 auto rc = loop.loop(); 114 if (rc < 0) 115 { 116 log<level::ERR>("Error occurred during the sd_event_loop", 117 entry("RC=%d", rc)); 118 return -1; 119 } 120 } 121 catch (const std::system_error& e) 122 { 123 log<level::ERR>(e.what()); 124 return -1; 125 } 126 127 return 0; 128 } 129