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 {"com.ibm.Hardware.Chassis.Model.BlueRidge2U"s, 65 {".BLUERIDGE_2U_XML"s, ".P10"s}}, 66 {"com.ibm.Hardware.Chassis.Model.BlueRidge4U"s, 67 {".BLUERIDGE_4U_XML"s, ".P10"s}}, 68 {"com.ibm.Hardware.Chassis.Model.BlueRidge1S4U"s, 69 {".BLUERIDGE_4U_XML"s, ".P10"s}}, 70 {"com.ibm.Hardware.Chassis.Model.Bonnell"s, {".BONNELL_XML"s, ".P10"s}}, 71 {"com.ibm.Hardware.Chassis.Model.Everest"s, {".EVEREST_XML"s, ".P10"s}}, 72 {"com.ibm.Hardware.Chassis.Model.Fuji"s, {".FUJI_XML"s, ".P10"s}}, 73 {"com.ibm.Hardware.Chassis.Model.Rainier2U"s, 74 {".RAINIER_2U_XML"s, ".P10"s}}, 75 {"com.ibm.Hardware.Chassis.Model.Rainier4U"s, 76 {".RAINIER_4U_XML"s, ".P10"s}}, 77 {"com.ibm.Hardware.Chassis.Model.Rainier1S4U"s, 78 {".RAINIER_4U_XML"s, ".P10"s}}, 79 }}; 80 81 // subcommandContext allows program subcommand callbacks to add loop event 82 // callbacks (e.g. reception of a dbus signal) and then return to main, 83 // without the loop event callback being destroyed until the loop event 84 // callback has a chance to run and instruct the loop to exit. 85 std::vector<std::shared_ptr<void>> subcommandContext; 86 static_cast<void>( 87 app.add_subcommand("process-host-firmware", 88 "Point the host firmware at its data.") 89 ->callback([&bus, &loop, &subcommandContext, extensionMap]() { 90 auto hostFirmwareDirectory = "/media/hostfw/running"s; 91 auto logCallback = [](const auto& path, auto& ec) { 92 std::cerr << path << ": " << ec.message() << "\n"; 93 }; 94 subcommandContext.push_back( 95 functions::process_hostfirmware::processHostFirmware( 96 bus, extensionMap, std::move(hostFirmwareDirectory), 97 std::move(logCallback), loop)); 98 })); 99 static_cast<void>( 100 app.add_subcommand("update-bios-attr-table", 101 "Update the bios attribute table with the host " 102 "firmware data details.") 103 ->callback([&bus, &loop, &subcommandContext, extensionMap]() { 104 auto elementsJsonFilePath = "/usr/share/hostfw/elements.json"s; 105 auto subcommands = functions::process_hostfirmware::updateBiosAttrTable( 106 bus, extensionMap, std::move(elementsJsonFilePath), loop); 107 for (const auto& subcommand : subcommands) 108 { 109 subcommandContext.push_back(subcommand); 110 } 111 })); 112 113 CLI11_PARSE(app, argc, argv); 114 115 if (app.get_subcommands().size() == 0) 116 { 117 initializeService(bus); 118 } 119 120 try 121 { 122 auto rc = loop.loop(); 123 if (rc < 0) 124 { 125 log<level::ERR>("Error occurred during the sd_event_loop", 126 entry("RC=%d", rc)); 127 return -1; 128 } 129 } 130 catch (const std::system_error& e) 131 { 132 log<level::ERR>(e.what()); 133 return -1; 134 } 135 136 return 0; 137 } 138