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 {
initializeService(sdbusplus::bus_t & bus)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
main(int argc,char * argv[])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 =
106 functions::process_hostfirmware::updateBiosAttrTable(
107 bus, extensionMap, std::move(elementsJsonFilePath),
108 loop);
109 for (const auto& subcommand : subcommands)
110 {
111 subcommandContext.push_back(subcommand);
112 }
113 }));
114
115 CLI11_PARSE(app, argc, argv);
116
117 if (app.get_subcommands().size() == 0)
118 {
119 initializeService(bus);
120 }
121
122 try
123 {
124 auto rc = loop.loop();
125 if (rc < 0)
126 {
127 log<level::ERR>("Error occurred during the sd_event_loop",
128 entry("RC=%d", rc));
129 return -1;
130 }
131 }
132 catch (const std::system_error& e)
133 {
134 log<level::ERR>(e.what());
135 return -1;
136 }
137
138 return 0;
139 }
140