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