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 void ItemUpdaterMMC::reset() 64 { 65 // Do not reset read-only files needed for reset or ext4 default files 66 const std::vector<std::string> exclusionList = {"alternate", "hostfw-a", 67 "hostfw-b", "lost+found", 68 "nvram", "running-ro"}; 69 std::filesystem::path dirPath(std::string(MEDIA_DIR "hostfw/")); 70 // Delete all files in /media/hostfw/ except for those on exclusionList 71 for (const auto& p : std::filesystem::directory_iterator(dirPath)) 72 { 73 if (std::find(exclusionList.begin(), exclusionList.end(), 74 p.path().stem().string()) == exclusionList.end()) 75 { 76 std::filesystem::remove_all(p); 77 } 78 } 79 80 // Delete all BMC error logs to avoid discrepancies with the host error logs 81 utils::deleteAllErrorLogs(bus); 82 83 // Set attribute to clear hypervisor NVRAM 84 utils::setClearNvram(bus); 85 86 // reset the enabled property of dimms/cpu after factory reset 87 gardReset->reset(); 88 89 // Remove files related to the Hardware Management Console / BMC web app 90 utils::clearHMCManaged(bus); 91 std::filesystem::path consolePath("/var/lib/bmcweb/ibm-management-console"); 92 if (std::filesystem::exists(consolePath)) 93 { 94 std::filesystem::remove_all(consolePath); 95 } 96 std::filesystem::path bmcdataPath("/home/root/bmcweb_persistent_data.json"); 97 if (std::filesystem::exists(bmcdataPath)) 98 { 99 std::filesystem::remove(bmcdataPath); 100 } 101 102 // Recreate default files. 103 // std::tuple<method, service_name> 104 const std::tuple<std::string, std::string> services[] = { 105 {"StartUnit", "obmc-flash-bios-init.service"}, 106 {"StartUnit", "obmc-flash-bios-patch.service"}, 107 {"StartUnit", "openpower-process-host-firmware.service"}, 108 {"StartUnit", "openpower-update-bios-attr-table.service"}, 109 {"RestartUnit", "org.open_power.HardwareIsolation.service"}}; 110 111 for (const auto& service : services) 112 { 113 auto method = bus.new_method_call(SYSTEMD_BUSNAME, SYSTEMD_PATH, 114 SYSTEMD_INTERFACE, 115 std::get<0>(service).c_str()); 116 method.append(std::get<1>(service), "replace"); 117 // Ignore errors if the service is not found - not all systems 118 // may have these services 119 try 120 { 121 bus.call_noreply(method); 122 } 123 catch (const std::exception& e) 124 {} 125 } 126 127 // Wait a few seconds for the service files and reset operations to finish, 128 // otherwise the BMC may be rebooted and cause corruption. 129 constexpr auto resetWait = std::chrono::seconds(5); 130 std::this_thread::sleep_for(resetWait); 131 } 132 133 bool ItemUpdaterMMC::isVersionFunctional(const std::string& versionId) 134 { 135 return versionId == functionalVersionId; 136 } 137 138 void ItemUpdaterMMC::freePriority(uint8_t, const std::string&) {} 139 140 void ItemUpdaterMMC::deleteAll() {} 141 142 bool ItemUpdaterMMC::freeSpace() 143 { 144 return true; 145 } 146 147 void ItemUpdaterMMC::updateFunctionalAssociation(const std::string&) {} 148 void GardResetMMC::enableInventoryItems() 149 { 150 (void)enableInventoryItemsHelper( 151 "xyz.openbmc_project.PLDM", 152 "xyz.openbmc_project.Inventory.Item.CpuCore", 153 "/xyz/openbmc_project/inventory/system/chassis/motherboard"); 154 155 (void)enableInventoryItemsHelper("xyz.openbmc_project.Inventory.Manager", 156 "xyz.openbmc_project.Inventory.Item.Dimm", 157 "/xyz/openbmc_project/inventory"); 158 } 159 160 void GardResetMMC::enableInventoryItemsHelper(const std::string& service, 161 const std::string& intf, 162 const std::string& objPath) 163 { 164 const std::vector<std::string> intflist{intf}; 165 166 std::vector<std::string> objs; 167 try 168 { 169 auto mapperCall = bus.new_method_call( 170 "xyz.openbmc_project.ObjectMapper", 171 "/xyz/openbmc_project/object_mapper", 172 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths"); 173 mapperCall.append(objPath); 174 mapperCall.append(0); 175 mapperCall.append(intflist); 176 177 auto response = bus.call(mapperCall); 178 response.read(objs); 179 for (auto& obj : objs) 180 { 181 auto method = bus.new_method_call(service.c_str(), obj.c_str(), 182 "org.freedesktop.DBus.Properties", 183 "Set"); 184 std::variant<bool> propertyVal{true}; 185 method.append("xyz.openbmc_project.Object.Enable", "Enabled", 186 propertyVal); 187 bus.call_noreply(method); 188 } 189 } 190 catch (const sdbusplus::exception_t& e) 191 { 192 log<level::ERR>( 193 fmt::format("Failed to enable specified inventory items ex({}) " 194 "intf({}) objpath({})", 195 e.what(), intf, objPath) 196 .c_str()); 197 } 198 } 199 200 void GardResetMMC::reset() 201 { 202 log<level::INFO>("GardResetMMC::reset"); 203 (void)enableInventoryItems(); 204 } 205 206 } // namespace updater 207 } // namespace software 208 } // namespace openpower 209