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