1 #include "config.h" 2 3 #include "item_updater_mmc.hpp" 4 5 #include "activation_mmc.hpp" 6 #include "utils.hpp" 7 #include "version.hpp" 8 9 #include <fmt/core.h> 10 11 #include <phosphor-logging/log.hpp> 12 13 #include <filesystem> 14 #include <iostream> 15 #include <thread> 16 17 namespace openpower 18 { 19 namespace software 20 { 21 namespace updater 22 { 23 24 using ::phosphor::logging::level; 25 using ::phosphor::logging::log; 26 // These functions are just a stub (empty) because the current eMMC 27 // implementation uses the BMC updater (repo phosphor-bmc-code-mgmt) to write 28 // the new host FW to flash since it's delivered as a "System" image in the 29 // same BMC tarball as the BMC image. 30 31 std::unique_ptr<Activation> ItemUpdaterMMC::createActivationObject( 32 const std::string& path, const std::string& versionId, 33 const std::string& extVersion, 34 sdbusplus::xyz::openbmc_project::Software::server::Activation::Activations 35 activationStatus, 36 AssociationList& assocs) 37 { 38 return std::make_unique<ActivationMMC>( 39 bus, path, *this, versionId, extVersion, activationStatus, assocs); 40 } 41 42 std::unique_ptr<Version> ItemUpdaterMMC::createVersionObject( 43 const std::string& objPath, const std::string& versionId, 44 const std::string& versionString, 45 sdbusplus::xyz::openbmc_project::Software::server::Version::VersionPurpose 46 versionPurpose, 47 const std::string& filePath) 48 { 49 auto version = std::make_unique<Version>( 50 bus, objPath, *this, versionId, versionString, versionPurpose, filePath, 51 std::bind(&ItemUpdaterMMC::erase, this, std::placeholders::_1)); 52 version->deleteObject = std::make_unique<Delete>(bus, objPath, *version); 53 return version; 54 } 55 56 bool ItemUpdaterMMC::validateImage(const std::string&) 57 { 58 return true; 59 } 60 61 void ItemUpdaterMMC::processPNORImage() 62 {} 63 64 void ItemUpdaterMMC::reset() 65 { 66 // Do not reset read-only files needed for reset or ext4 default files 67 const std::vector<std::string> exclusionList = {"alternate", "hostfw-a", 68 "hostfw-b", "lost+found", 69 "nvram", "running-ro"}; 70 std::filesystem::path dirPath(std::string(MEDIA_DIR "hostfw/")); 71 // Delete all files in /media/hostfw/ except for those on exclusionList 72 for (const auto& p : std::filesystem::directory_iterator(dirPath)) 73 { 74 if (std::find(exclusionList.begin(), exclusionList.end(), 75 p.path().stem().string()) == exclusionList.end()) 76 { 77 std::filesystem::remove_all(p); 78 } 79 } 80 81 // Delete all BMC error logs to avoid discrepancies with the host error logs 82 utils::deleteAllErrorLogs(bus); 83 84 // Set attribute to clear hypervisor NVRAM 85 utils::setClearNvram(bus); 86 87 // reset the enabled property of dimms/cpu after factory reset 88 gardReset->reset(); 89 90 // Remove files related to the Hardware Management Console / BMC web app 91 utils::clearHMCManaged(bus); 92 std::filesystem::path consolePath("/var/lib/bmcweb/ibm-management-console"); 93 if (std::filesystem::exists(consolePath)) 94 { 95 std::filesystem::remove_all(consolePath); 96 } 97 std::filesystem::path bmcdataPath("/home/root/bmcweb_persistent_data.json"); 98 if (std::filesystem::exists(bmcdataPath)) 99 { 100 std::filesystem::remove(bmcdataPath); 101 } 102 103 // Recreate default files. 104 // std::tuple<method, service_name> 105 const std::tuple<std::string, std::string> services[] = { 106 {"StartUnit", "obmc-flash-bios-init.service"}, 107 {"StartUnit", "obmc-flash-bios-patch.service"}, 108 {"StartUnit", "openpower-process-host-firmware.service"}, 109 {"StartUnit", "openpower-update-bios-attr-table.service"}, 110 {"RestartUnit", "org.open_power.HardwareIsolation.service"}}; 111 112 for (const auto& service : services) 113 { 114 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 115 SYSTEMD_INTERFACE, 116 std::get<0>(service).c_str()); 117 method.append(std::get<1>(service), "replace"); 118 // Ignore errors if the service is not found - not all systems 119 // may have these services 120 try 121 { 122 bus.call_noreply(method); 123 } 124 catch (const std::exception& e) 125 {} 126 } 127 128 // Wait a few seconds for the service files and reset operations to finish, 129 // otherwise the BMC may be rebooted and cause corruption. 130 constexpr auto resetWait = std::chrono::seconds(5); 131 std::this_thread::sleep_for(resetWait); 132 } 133 134 bool ItemUpdaterMMC::isVersionFunctional(const std::string& versionId) 135 { 136 return versionId == functionalVersionId; 137 } 138 139 void ItemUpdaterMMC::freePriority(uint8_t, const std::string&) 140 {} 141 142 void ItemUpdaterMMC::deleteAll() 143 {} 144 145 bool ItemUpdaterMMC::freeSpace() 146 { 147 return true; 148 } 149 150 void ItemUpdaterMMC::updateFunctionalAssociation(const std::string&) 151 {} 152 void GardResetMMC::enableInventoryItems() 153 { 154 (void)enableInventoryItemsHelper( 155 "xyz.openbmc_project.PLDM", 156 "xyz.openbmc_project.Inventory.Item.CpuCore", 157 "/xyz/openbmc_project/inventory/system/chassis/motherboard"); 158 159 (void)enableInventoryItemsHelper("xyz.openbmc_project.Inventory.Manager", 160 "xyz.openbmc_project.Inventory.Item.Dimm", 161 "/xyz/openbmc_project/inventory"); 162 } 163 164 void GardResetMMC::enableInventoryItemsHelper(const std::string& service, 165 const std::string& intf, 166 const std::string& objPath) 167 { 168 const std::vector<std::string> intflist{intf}; 169 170 std::vector<std::string> objs; 171 try 172 { 173 auto mapperCall = bus.new_method_call( 174 "xyz.openbmc_project.ObjectMapper", 175 "/xyz/openbmc_project/object_mapper", 176 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"); 177 mapperCall.append(objPath); 178 mapperCall.append(0); 179 mapperCall.append(intflist); 180 181 auto response = bus.call(mapperCall); 182 response.read(objs); 183 for (auto& obj : objs) 184 { 185 auto method = 186 bus.new_method_call(service.c_str(), obj.c_str(), 187 "org.freedesktop.DBus.Properties", "Set"); 188 std::variant<bool> propertyVal{true}; 189 method.append("xyz.openbmc_project.Object.Enable", "Enabled", 190 propertyVal); 191 bus.call_noreply(method); 192 } 193 } 194 catch (const sdbusplus::exception_t& e) 195 { 196 log<level::ERR>( 197 fmt::format("Failed to enable specified inventory items ex({}) " 198 "intf({}) objpath({})", 199 e.what(), intf, objPath) 200 .c_str()); 201 } 202 } 203 204 void GardResetMMC::reset() 205 { 206 log<level::INFO>("GardResetMMC::reset"); 207 (void)enableInventoryItems(); 208 } 209 210 } // namespace updater 211 } // namespace software 212 } // namespace openpower 213