| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 1 | #include <fstream> | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 2 | #include <set> | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 3 | #include <string> | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 4 | #include <phosphor-logging/log.hpp> | 
| Saqib Khan | dcbfa04 | 2017-09-18 13:08:39 -0500 | [diff] [blame] | 5 | #include <phosphor-logging/elog.hpp> | 
 | 6 | #include <elog-errors.hpp> | 
 | 7 | #include <xyz/openbmc_project/Software/Version/error.hpp> | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 8 | #include "config.h" | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 9 | #include "item_updater.hpp" | 
 | 10 | #include "xyz/openbmc_project/Software/Version/server.hpp" | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 11 | #include <experimental/filesystem> | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 12 | #include "version.hpp" | 
| Saqib Khan | 5d53267 | 2017-08-09 10:44:50 -0500 | [diff] [blame] | 13 | #include "serialize.hpp" | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 14 |  | 
 | 15 | namespace phosphor | 
 | 16 | { | 
 | 17 | namespace software | 
 | 18 | { | 
 | 19 | namespace updater | 
 | 20 | { | 
 | 21 |  | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 22 | // When you see server:: you know we're referencing our base class | 
 | 23 | namespace server = sdbusplus::xyz::openbmc_project::Software::server; | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 24 | namespace control = sdbusplus::xyz::openbmc_project::Control::server; | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 25 |  | 
 | 26 | using namespace phosphor::logging; | 
| Saqib Khan | dcbfa04 | 2017-09-18 13:08:39 -0500 | [diff] [blame] | 27 | using namespace sdbusplus::xyz::openbmc_project::Software::Version::Error; | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 28 | namespace fs = std::experimental::filesystem; | 
 | 29 |  | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 30 | const std::vector<std::string> bmcImages = { "image-kernel", | 
 | 31 |                                              "image-rofs", | 
 | 32 |                                              "image-rwfs", | 
 | 33 |                                              "image-u-boot" }; | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 34 |  | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 35 | void ItemUpdater::createActivation(sdbusplus::message::message& msg) | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 36 | { | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 37 |  | 
 | 38 |     using SVersion = server::Version; | 
 | 39 |     using VersionPurpose = SVersion::VersionPurpose; | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 40 |     using VersionClass = phosphor::software::manager::Version; | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 41 |     namespace mesg = sdbusplus::message; | 
 | 42 |     namespace variant_ns = mesg::variant_ns; | 
 | 43 |  | 
 | 44 |     mesg::object_path objPath; | 
 | 45 |     auto purpose = VersionPurpose::Unknown; | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 46 |     std::string version; | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 47 |     std::map<std::string, | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 48 |              std::map<std::string, | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 49 |                       mesg::variant<std::string>>> interfaces; | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 50 |     msg.read(objPath, interfaces); | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 51 |     std::string path(std::move(objPath)); | 
| Saqib Khan | 19177d3 | 2017-06-20 08:11:49 -0500 | [diff] [blame] | 52 |     std::string filePath; | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 53 |  | 
 | 54 |     for (const auto& intf : interfaces) | 
 | 55 |     { | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 56 |         if (intf.first == VERSION_IFACE) | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 57 |         { | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 58 |             for (const auto& property : intf.second) | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 59 |             { | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 60 |                 if (property.first == "Purpose") | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 61 |                 { | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 62 |                     auto value = SVersion::convertVersionPurposeFromString( | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 63 |                             variant_ns::get<std::string>(property.second)); | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 64 |                     if (value == VersionPurpose::BMC || | 
 | 65 |                         value == VersionPurpose::System) | 
 | 66 |                     { | 
 | 67 |                         purpose = value; | 
 | 68 |                     } | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 69 |                 } | 
 | 70 |                 else if (property.first == "Version") | 
 | 71 |                 { | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 72 |                     version = variant_ns::get<std::string>(property.second); | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 73 |                 } | 
 | 74 |             } | 
 | 75 |         } | 
| Saqib Khan | 19177d3 | 2017-06-20 08:11:49 -0500 | [diff] [blame] | 76 |         else if (intf.first == FILEPATH_IFACE) | 
 | 77 |         { | 
 | 78 |             for (const auto& property : intf.second) | 
 | 79 |             { | 
 | 80 |                 if (property.first == "Path") | 
 | 81 |                 { | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 82 |                     filePath = variant_ns::get<std::string>(property.second); | 
| Saqib Khan | 19177d3 | 2017-06-20 08:11:49 -0500 | [diff] [blame] | 83 |                 } | 
 | 84 |             } | 
 | 85 |         } | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 86 |     } | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 87 |     if (version.empty() || | 
| Saqib Khan | 19177d3 | 2017-06-20 08:11:49 -0500 | [diff] [blame] | 88 |         filePath.empty() || | 
| Saqib Khan | 84a0e69 | 2017-06-28 17:27:01 -0500 | [diff] [blame] | 89 |         purpose == VersionPurpose::Unknown) | 
| Saqib Khan | 705f1bf | 2017-06-09 23:58:38 -0500 | [diff] [blame] | 90 |     { | 
 | 91 |         return; | 
 | 92 |     } | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 93 |  | 
 | 94 |     // Version id is the last item in the path | 
 | 95 |     auto pos = path.rfind("/"); | 
 | 96 |     if (pos == std::string::npos) | 
 | 97 |     { | 
 | 98 |         log<level::ERR>("No version id found in object path", | 
| Adriana Kobylak | 596466b | 2018-02-13 14:48:53 -0600 | [diff] [blame^] | 99 |                         entry("OBJPATH=%s", path.c_str())); | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 100 |         return; | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 101 |     } | 
 | 102 |  | 
 | 103 |     auto versionId = path.substr(pos + 1); | 
 | 104 |  | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 105 |     if (activations.find(versionId) == activations.end()) | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 106 |     { | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 107 |         // Determine the Activation state by processing the given image dir. | 
 | 108 |         auto activationState = server::Activation::Activations::Invalid; | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 109 |         ItemUpdater::ActivationStatus result = | 
 | 110 |                 ItemUpdater::validateSquashFSImage(filePath); | 
| Gunnar Mills | 43b25cd | 2017-09-07 13:19:34 -0500 | [diff] [blame] | 111 |         AssociationList associations = {}; | 
 | 112 |  | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 113 |         if (result == ItemUpdater::ActivationStatus::ready) | 
 | 114 |         { | 
 | 115 |             activationState = server::Activation::Activations::Ready; | 
| Gunnar Mills | 43b25cd | 2017-09-07 13:19:34 -0500 | [diff] [blame] | 116 |             // Create an association to the BMC inventory item | 
 | 117 |             associations.emplace_back(std::make_tuple( | 
 | 118 |                                               ACTIVATION_FWD_ASSOCIATION, | 
 | 119 |                                               ACTIVATION_REV_ASSOCIATION, | 
 | 120 |                                               bmcInventoryPath)); | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 121 |         } | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 122 |  | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 123 |         activations.insert(std::make_pair( | 
 | 124 |                                    versionId, | 
 | 125 |                                    std::make_unique<Activation>( | 
 | 126 |                                            bus, | 
 | 127 |                                            path, | 
 | 128 |                                            *this, | 
 | 129 |                                            versionId, | 
 | 130 |                                            activationState, | 
 | 131 |                                            associations))); | 
| Michael Tritz | 4254bec | 2017-10-03 17:18:22 -0500 | [diff] [blame] | 132 |  | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 133 |         auto versionPtr = std::make_unique<VersionClass>( | 
 | 134 |                                   bus, | 
 | 135 |                                   path, | 
 | 136 |                                   version, | 
 | 137 |                                   purpose, | 
 | 138 |                                   filePath, | 
 | 139 |                                   std::bind(&ItemUpdater::erase, | 
 | 140 |                                             this, | 
 | 141 |                                             std::placeholders::_1)); | 
 | 142 |         versionPtr->deleteObject = | 
 | 143 |                 std::make_unique<phosphor::software::manager::Delete>( | 
 | 144 |                         bus, path, *versionPtr); | 
 | 145 |         versions.insert(std::make_pair(versionId, std::move(versionPtr))); | 
| Gunnar Mills | 2ce7da2 | 2017-05-04 15:37:56 -0500 | [diff] [blame] | 146 |     } | 
| Patrick Williams | e75d10f | 2017-05-30 16:56:32 -0500 | [diff] [blame] | 147 |     return; | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 148 | } | 
 | 149 |  | 
| Saqib Khan | ba23988 | 2017-05-26 08:41:54 -0500 | [diff] [blame] | 150 | void ItemUpdater::processBMCImage() | 
 | 151 | { | 
| Gunnar Mills | 88e8a32 | 2017-09-13 11:09:28 -0500 | [diff] [blame] | 152 |     using VersionClass = phosphor::software::manager::Version; | 
 | 153 |     // Read os-release from /etc/ to get the functional BMC version | 
 | 154 |     auto functionalVersion = VersionClass::getBMCVersion(OS_RELEASE_FILE); | 
 | 155 |  | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 156 |     // Read os-release from folders under /media/ to get | 
 | 157 |     // BMC Software Versions. | 
| Gunnar Mills | d16bcbd | 2017-10-08 16:50:42 -0500 | [diff] [blame] | 158 |     for (const auto& iter : fs::directory_iterator(MEDIA_DIR)) | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 159 |     { | 
 | 160 |         auto activationState = server::Activation::Activations::Active; | 
| Saqib Khan | 6fab70d | 2017-09-07 00:13:50 -0500 | [diff] [blame] | 161 |         static const auto BMC_RO_PREFIX_LEN = strlen(BMC_ROFS_PREFIX); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 162 |  | 
 | 163 |         // Check if the BMC_RO_PREFIXis the prefix of the iter.path | 
 | 164 |         if (0 == iter.path().native().compare(0, BMC_RO_PREFIX_LEN, | 
| Saqib Khan | 6fab70d | 2017-09-07 00:13:50 -0500 | [diff] [blame] | 165 |                                               BMC_ROFS_PREFIX)) | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 166 |         { | 
| Saqib Khan | 021c365 | 2017-09-26 12:11:02 -0500 | [diff] [blame] | 167 |             // The versionId is extracted from the path | 
 | 168 |             // for example /media/ro-2a1022fe. | 
 | 169 |             auto id = iter.path().native().substr(BMC_RO_PREFIX_LEN); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 170 |             auto osRelease = iter.path() / OS_RELEASE_FILE; | 
 | 171 |             if (!fs::is_regular_file(osRelease)) | 
 | 172 |             { | 
| Gunnar Mills | 2ad1b55 | 2017-10-19 15:58:52 -0500 | [diff] [blame] | 173 |                 log<level::ERR>("Failed to read osRelease", | 
| Adriana Kobylak | 596466b | 2018-02-13 14:48:53 -0600 | [diff] [blame^] | 174 |                                 entry("FILENAME=%s", osRelease.string().c_str())); | 
| Saqib Khan | 021c365 | 2017-09-26 12:11:02 -0500 | [diff] [blame] | 175 |                 ItemUpdater::erase(id); | 
 | 176 |                 continue; | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 177 |             } | 
| Gunnar Mills | 88e8a32 | 2017-09-13 11:09:28 -0500 | [diff] [blame] | 178 |             auto version = VersionClass::getBMCVersion(osRelease); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 179 |             if (version.empty()) | 
 | 180 |             { | 
 | 181 |                 log<level::ERR>("Failed to read version from osRelease", | 
| Adriana Kobylak | 596466b | 2018-02-13 14:48:53 -0600 | [diff] [blame^] | 182 |                                 entry("FILENAME=%s", osRelease.string().c_str())); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 183 |                 activationState = server::Activation::Activations::Invalid; | 
 | 184 |             } | 
| Saqib Khan | 021c365 | 2017-09-26 12:11:02 -0500 | [diff] [blame] | 185 |  | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 186 |             auto purpose = server::Version::VersionPurpose::BMC; | 
 | 187 |             auto path = fs::path(SOFTWARE_OBJPATH) / id; | 
 | 188 |  | 
| Gunnar Mills | 88e8a32 | 2017-09-13 11:09:28 -0500 | [diff] [blame] | 189 |             // Create functional association if this is the functional version | 
 | 190 |             if (version.compare(functionalVersion) == 0) | 
 | 191 |             { | 
 | 192 |                 createFunctionalAssociation(path); | 
 | 193 |             } | 
 | 194 |  | 
| Gunnar Mills | 43b25cd | 2017-09-07 13:19:34 -0500 | [diff] [blame] | 195 |             AssociationList associations = {}; | 
 | 196 |  | 
 | 197 |             if (activationState == server::Activation::Activations::Active) | 
 | 198 |             { | 
 | 199 |                 // Create an association to the BMC inventory item | 
 | 200 |                 associations.emplace_back(std::make_tuple( | 
 | 201 |                                                   ACTIVATION_FWD_ASSOCIATION, | 
 | 202 |                                                   ACTIVATION_REV_ASSOCIATION, | 
 | 203 |                                                   bmcInventoryPath)); | 
 | 204 |  | 
 | 205 |                 // Create an active association since this image is active | 
 | 206 |                 createActiveAssociation(path); | 
 | 207 |             } | 
 | 208 |  | 
| Adriana Kobylak | ee590c7 | 2017-09-26 15:16:06 -0500 | [diff] [blame] | 209 |             // Create Version instance for this version. | 
 | 210 |             auto versionPtr = std::make_unique<VersionClass>( | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 211 |                                       bus, | 
 | 212 |                                       path, | 
 | 213 |                                       version, | 
 | 214 |                                       purpose, | 
 | 215 |                                       "", | 
 | 216 |                                       std::bind(&ItemUpdater::erase, | 
 | 217 |                                                 this, | 
 | 218 |                                                 std::placeholders::_1)); | 
| Adriana Kobylak | ee590c7 | 2017-09-26 15:16:06 -0500 | [diff] [blame] | 219 |             auto isVersionFunctional = versionPtr->isFunctional(); | 
| Michael Tritz | 4254bec | 2017-10-03 17:18:22 -0500 | [diff] [blame] | 220 |             if (!isVersionFunctional) | 
 | 221 |             { | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 222 |                 versionPtr->deleteObject = | 
 | 223 |                         std::make_unique<phosphor::software::manager::Delete>( | 
 | 224 |                                 bus, path, *versionPtr); | 
| Michael Tritz | 4254bec | 2017-10-03 17:18:22 -0500 | [diff] [blame] | 225 |             } | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 226 |             versions.insert(std::make_pair( | 
 | 227 |                                     id, | 
 | 228 |                                     std::move(versionPtr))); | 
| Michael Tritz | 4254bec | 2017-10-03 17:18:22 -0500 | [diff] [blame] | 229 |  | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 230 |             // Create Activation instance for this version. | 
 | 231 |             activations.insert(std::make_pair( | 
 | 232 |                                id, | 
 | 233 |                                std::make_unique<Activation>( | 
 | 234 |                                         bus, | 
 | 235 |                                         path, | 
 | 236 |                                         *this, | 
 | 237 |                                         id, | 
 | 238 |                                         activationState, | 
 | 239 |                                         associations))); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 240 |  | 
 | 241 |             // If Active, create RedundancyPriority instance for this version. | 
 | 242 |             if (activationState == server::Activation::Activations::Active) | 
 | 243 |             { | 
 | 244 |                 uint8_t priority = std::numeric_limits<uint8_t>::max(); | 
 | 245 |                 if (!restoreFromFile(id, priority)) | 
 | 246 |                 { | 
| Adriana Kobylak | ee590c7 | 2017-09-26 15:16:06 -0500 | [diff] [blame] | 247 |                     if (isVersionFunctional) | 
 | 248 |                     { | 
 | 249 |                         priority = 0; | 
 | 250 |                     } | 
 | 251 |                     else | 
 | 252 |                     { | 
 | 253 |                         log<level::ERR>("Unable to restore priority from file.", | 
| Adriana Kobylak | 596466b | 2018-02-13 14:48:53 -0600 | [diff] [blame^] | 254 |                                 entry("VERSIONID=%s", id.c_str())); | 
| Adriana Kobylak | ee590c7 | 2017-09-26 15:16:06 -0500 | [diff] [blame] | 255 |                     } | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 256 |                 } | 
 | 257 |                 activations.find(id)->second->redundancyPriority = | 
 | 258 |                         std::make_unique<RedundancyPriority>( | 
| Saqib Khan | ba23988 | 2017-05-26 08:41:54 -0500 | [diff] [blame] | 259 |                              bus, | 
 | 260 |                              path, | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 261 |                              *(activations.find(id)->second), | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 262 |                              priority, | 
 | 263 |                              false); | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 264 |             } | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 265 |         } | 
 | 266 |     } | 
| Saqib Khan | dcbfa04 | 2017-09-18 13:08:39 -0500 | [diff] [blame] | 267 |  | 
 | 268 |     // If there is no ubi volume for bmc version then read the /etc/os-release | 
 | 269 |     // and create rofs-<versionId> under /media | 
 | 270 |     if (activations.size() == 0) | 
 | 271 |     { | 
| Gunnar Mills | d16bcbd | 2017-10-08 16:50:42 -0500 | [diff] [blame] | 272 |         auto version = VersionClass::getBMCVersion(OS_RELEASE_FILE); | 
| Saqib Khan | dcbfa04 | 2017-09-18 13:08:39 -0500 | [diff] [blame] | 273 |         auto id = phosphor::software::manager::Version::getId(version); | 
 | 274 |         auto versionFileDir = BMC_ROFS_PREFIX + id + "/etc/"; | 
 | 275 |         try | 
 | 276 |         { | 
| Gunnar Mills | d16bcbd | 2017-10-08 16:50:42 -0500 | [diff] [blame] | 277 |             if (!fs::is_directory(versionFileDir)) | 
| Saqib Khan | dcbfa04 | 2017-09-18 13:08:39 -0500 | [diff] [blame] | 278 |             { | 
 | 279 |                 fs::create_directories(versionFileDir); | 
 | 280 |             } | 
 | 281 |             auto versionFilePath = BMC_ROFS_PREFIX + id + OS_RELEASE_FILE; | 
 | 282 |             fs::create_directory_symlink(OS_RELEASE_FILE, versionFilePath); | 
 | 283 |             ItemUpdater::processBMCImage(); | 
 | 284 |         } | 
 | 285 |         catch (const std::exception& e) | 
 | 286 |         { | 
 | 287 |             log<level::ERR>(e.what()); | 
 | 288 |         } | 
 | 289 |     } | 
| Saqib Khan | ba23988 | 2017-05-26 08:41:54 -0500 | [diff] [blame] | 290 |     return; | 
 | 291 | } | 
 | 292 |  | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 293 | void ItemUpdater::erase(std::string entryId) | 
 | 294 | { | 
| Eddie James | 6d87371 | 2017-09-01 11:29:07 -0500 | [diff] [blame] | 295 |     // Find entry in versions map | 
 | 296 |     auto it = versions.find(entryId); | 
 | 297 |     if (it != versions.end()) | 
 | 298 |     { | 
 | 299 |         if (it->second->isFunctional()) | 
 | 300 |         { | 
 | 301 |             log<level::ERR>(("Error: Version " + entryId + \ | 
 | 302 |                              " is currently running on the BMC." \ | 
 | 303 |                              " Unable to remove.").c_str()); | 
| Gunnar Mills | d16bcbd | 2017-10-08 16:50:42 -0500 | [diff] [blame] | 304 |             return; | 
| Eddie James | 6d87371 | 2017-09-01 11:29:07 -0500 | [diff] [blame] | 305 |         } | 
 | 306 |  | 
 | 307 |         // Delete ReadOnly partitions if it's not active | 
 | 308 |         removeReadOnlyPartition(entryId); | 
 | 309 |         removeFile(entryId); | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 310 |  | 
 | 311 |         // Removing entry in versions map | 
 | 312 |         this->versions.erase(entryId); | 
| Eddie James | 6d87371 | 2017-09-01 11:29:07 -0500 | [diff] [blame] | 313 |     } | 
 | 314 |     else | 
 | 315 |     { | 
 | 316 |         // Delete ReadOnly partitions even if we can't find the version | 
 | 317 |         removeReadOnlyPartition(entryId); | 
 | 318 |         removeFile(entryId); | 
 | 319 |  | 
 | 320 |         log<level::ERR>(("Error: Failed to find version " + entryId + \ | 
 | 321 |                          " in item updater versions map." \ | 
 | 322 |                          " Unable to remove.").c_str()); | 
| Eddie James | 6d87371 | 2017-09-01 11:29:07 -0500 | [diff] [blame] | 323 |     } | 
| Saqib Khan | 1eef62d | 2017-08-10 15:29:34 -0500 | [diff] [blame] | 324 |  | 
 | 325 |     // Remove the priority environment variable. | 
 | 326 |     auto serviceFile = "obmc-flash-bmc-setenv@" + entryId + ".service"; | 
 | 327 |     auto method = bus.new_method_call( | 
 | 328 |             SYSTEMD_BUSNAME, | 
 | 329 |             SYSTEMD_PATH, | 
 | 330 |             SYSTEMD_INTERFACE, | 
 | 331 |             "StartUnit"); | 
 | 332 |     method.append(serviceFile, "replace"); | 
 | 333 |     bus.call_noreply(method); | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 334 |  | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 335 |     // Removing entry in activations map | 
 | 336 |     auto ita = activations.find(entryId); | 
 | 337 |     if (ita == activations.end()) | 
 | 338 |     { | 
 | 339 |         log<level::ERR>(("Error: Failed to find version " + entryId + \ | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 340 |                          " in item updater activations map." \ | 
 | 341 |                          " Unable to remove.").c_str()); | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 342 |     } | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 343 |     else | 
 | 344 |     { | 
 | 345 |         this->activations.erase(entryId); | 
 | 346 |     } | 
| Saqib Khan | 49446ae | 2017-10-02 10:54:20 -0500 | [diff] [blame] | 347 |     ItemUpdater::resetUbootEnvVars(); | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 348 |     return; | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Michael Tritz | bc1bf3a | 2017-09-18 16:38:23 -0500 | [diff] [blame] | 351 | void ItemUpdater::deleteAll() | 
 | 352 | { | 
| Michael Tritz | bc1bf3a | 2017-09-18 16:38:23 -0500 | [diff] [blame] | 353 |     for (const auto& versionIt : versions) | 
 | 354 |     { | 
 | 355 |         if (!versionIt.second->isFunctional()) | 
 | 356 |         { | 
| Saqib Khan | ee13e83 | 2017-10-23 12:53:11 -0500 | [diff] [blame] | 357 |             ItemUpdater::erase(versionIt.first); | 
| Michael Tritz | bc1bf3a | 2017-09-18 16:38:23 -0500 | [diff] [blame] | 358 |         } | 
 | 359 |     } | 
 | 360 |  | 
| Michael Tritz | bc1bf3a | 2017-09-18 16:38:23 -0500 | [diff] [blame] | 361 |     // Remove any volumes that do not match current versions. | 
 | 362 |     auto method = bus.new_method_call( | 
 | 363 |             SYSTEMD_BUSNAME, | 
 | 364 |             SYSTEMD_PATH, | 
 | 365 |             SYSTEMD_INTERFACE, | 
 | 366 |             "StartUnit"); | 
 | 367 |     method.append("obmc-flash-bmc-cleanup.service", "replace"); | 
 | 368 |     bus.call_noreply(method); | 
 | 369 | } | 
 | 370 |  | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 371 | ItemUpdater::ActivationStatus ItemUpdater::validateSquashFSImage( | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 372 |         const std::string& filePath) | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 373 | { | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 374 |     bool invalid = false; | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 375 |  | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 376 |     for (auto& bmcImage : bmcImages) | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 377 |     { | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 378 |         fs::path file(filePath); | 
 | 379 |         file /= bmcImage; | 
 | 380 |         std::ifstream efile(file.c_str()); | 
 | 381 |         if (efile.good() != 1) | 
 | 382 |         { | 
 | 383 |             log<level::ERR>("Failed to find the BMC image.", | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 384 |                             entry("IMAGE=%s", bmcImage.c_str())); | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 385 |             invalid = true; | 
 | 386 |         } | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 387 |     } | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 388 |  | 
 | 389 |     if (invalid) | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 390 |     { | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 391 |         return ItemUpdater::ActivationStatus::invalid; | 
 | 392 |     } | 
| Michael Tritz | b1cfdf9 | 2017-08-14 14:33:30 -0500 | [diff] [blame] | 393 |  | 
 | 394 |     return ItemUpdater::ActivationStatus::ready; | 
| Saqib Khan | 35e83f3 | 2017-05-22 11:37:32 -0500 | [diff] [blame] | 395 | } | 
 | 396 |  | 
| Saqib Khan | b9da663 | 2017-09-13 09:48:37 -0500 | [diff] [blame] | 397 | void ItemUpdater::freePriority(uint8_t value, const std::string& versionId) | 
| Saqib Khan | 4c1aec0 | 2017-07-06 11:46:13 -0500 | [diff] [blame] | 398 | { | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 399 |     std::map<std::string, uint8_t> priorityMap; | 
 | 400 |  | 
 | 401 |     // Insert the requested version and priority, it may not exist yet. | 
 | 402 |     priorityMap.insert(std::make_pair(versionId, value)); | 
 | 403 |  | 
| Saqib Khan | 4c1aec0 | 2017-07-06 11:46:13 -0500 | [diff] [blame] | 404 |     for (const auto& intf : activations) | 
 | 405 |     { | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 406 |         if (intf.second->redundancyPriority) | 
| Saqib Khan | 4c1aec0 | 2017-07-06 11:46:13 -0500 | [diff] [blame] | 407 |         { | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 408 |             priorityMap.insert(std::make_pair( | 
 | 409 |                     intf.first, | 
 | 410 |                     intf.second->redundancyPriority.get()->priority())); | 
| Saqib Khan | 4c1aec0 | 2017-07-06 11:46:13 -0500 | [diff] [blame] | 411 |         } | 
 | 412 |     } | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 413 |  | 
 | 414 |     // Lambda function to compare 2 priority values, use <= to allow duplicates | 
 | 415 |     typedef std::function<bool( | 
 | 416 |             std::pair<std::string, uint8_t>, | 
 | 417 |             std::pair<std::string, uint8_t>)> cmpPriority; | 
 | 418 |     cmpPriority cmpPriorityFunc = []( | 
 | 419 |             std::pair<std::string, uint8_t> priority1, | 
 | 420 |             std::pair<std::string, uint8_t> priority2) | 
 | 421 |     { | 
 | 422 |         return priority1.second <= priority2.second; | 
 | 423 |     }; | 
 | 424 |  | 
 | 425 |     // Sort versions by ascending priority | 
 | 426 |     std::set<std::pair<std::string, uint8_t>, cmpPriority> prioritySet( | 
 | 427 |             priorityMap.begin(), priorityMap.end(), cmpPriorityFunc); | 
 | 428 |  | 
 | 429 |     auto freePriorityValue = value; | 
 | 430 |     for (auto& element : prioritySet) | 
 | 431 |     { | 
 | 432 |         if (element.first == versionId) | 
 | 433 |         { | 
 | 434 |             continue; | 
 | 435 |         } | 
 | 436 |         if (element.second == freePriorityValue) | 
 | 437 |         { | 
 | 438 |             ++freePriorityValue; | 
 | 439 |             auto it = activations.find(element.first); | 
 | 440 |             it->second->redundancyPriority.get()->sdbusPriority( | 
 | 441 |                     freePriorityValue); | 
 | 442 |         } | 
 | 443 |     } | 
 | 444 |  | 
 | 445 |     auto lowestVersion = prioritySet.begin()->first; | 
 | 446 |     if (value == prioritySet.begin()->second) | 
 | 447 |     { | 
 | 448 |         lowestVersion = versionId; | 
 | 449 |     } | 
 | 450 |     updateUbootEnvVars(lowestVersion); | 
| Saqib Khan | 4c1aec0 | 2017-07-06 11:46:13 -0500 | [diff] [blame] | 451 | } | 
 | 452 |  | 
| Michael Tritz | 37a5904 | 2017-07-12 13:44:53 -0500 | [diff] [blame] | 453 | void ItemUpdater::reset() | 
 | 454 | { | 
 | 455 |     // Mark the read-write partition for recreation upon reboot. | 
 | 456 |     auto method = bus.new_method_call( | 
 | 457 |             SYSTEMD_BUSNAME, | 
 | 458 |             SYSTEMD_PATH, | 
 | 459 |             SYSTEMD_INTERFACE, | 
 | 460 |             "StartUnit"); | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 461 |     method.append("obmc-flash-bmc-setenv@rwreset\\x3dtrue.service", "replace"); | 
| Michael Tritz | 37a5904 | 2017-07-12 13:44:53 -0500 | [diff] [blame] | 462 |     bus.call_noreply(method); | 
 | 463 |  | 
 | 464 |     log<level::INFO>("BMC factory reset will take effect upon reboot."); | 
 | 465 |  | 
 | 466 |     return; | 
 | 467 | } | 
 | 468 |  | 
| Leonel Gonzalez | 3526ef7 | 2017-07-07 14:38:25 -0500 | [diff] [blame] | 469 | void ItemUpdater::removeReadOnlyPartition(std::string versionId) | 
 | 470 | { | 
 | 471 |     auto serviceFile = "obmc-flash-bmc-ubiro-remove@" + versionId + | 
 | 472 |             ".service"; | 
 | 473 |  | 
 | 474 |     // Remove the read-only partitions. | 
 | 475 |     auto method = bus.new_method_call( | 
 | 476 |             SYSTEMD_BUSNAME, | 
 | 477 |             SYSTEMD_PATH, | 
 | 478 |             SYSTEMD_INTERFACE, | 
 | 479 |             "StartUnit"); | 
 | 480 |     method.append(serviceFile, "replace"); | 
 | 481 |     bus.call_noreply(method); | 
 | 482 | } | 
 | 483 |  | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 484 | bool ItemUpdater::fieldModeEnabled(bool value) | 
 | 485 | { | 
 | 486 |     // enabling field mode is intended to be one way: false -> true | 
 | 487 |     if (value && !control::FieldMode::fieldModeEnabled()) | 
 | 488 |     { | 
 | 489 |         control::FieldMode::fieldModeEnabled(value); | 
 | 490 |  | 
 | 491 |         auto method = bus.new_method_call( | 
 | 492 |                 SYSTEMD_BUSNAME, | 
 | 493 |                 SYSTEMD_PATH, | 
 | 494 |                 SYSTEMD_INTERFACE, | 
 | 495 |                 "StartUnit"); | 
 | 496 |         method.append("obmc-flash-bmc-setenv@fieldmode\\x3dtrue.service", | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 497 |                       "replace"); | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 498 |         bus.call_noreply(method); | 
 | 499 |  | 
 | 500 |         method = bus.new_method_call( | 
 | 501 |                 SYSTEMD_BUSNAME, | 
 | 502 |                 SYSTEMD_PATH, | 
 | 503 |                 SYSTEMD_INTERFACE, | 
 | 504 |                 "StopUnit"); | 
 | 505 |         method.append("usr-local.mount", "replace"); | 
 | 506 |         bus.call_noreply(method); | 
 | 507 |  | 
 | 508 |         std::vector<std::string> usrLocal = {"usr-local.mount"}; | 
 | 509 |  | 
 | 510 |         method = bus.new_method_call( | 
 | 511 |                 SYSTEMD_BUSNAME, | 
 | 512 |                 SYSTEMD_PATH, | 
 | 513 |                 SYSTEMD_INTERFACE, | 
 | 514 |                 "MaskUnitFiles"); | 
 | 515 |         method.append(usrLocal, false, true); | 
 | 516 |         bus.call_noreply(method); | 
 | 517 |     } | 
 | 518 |  | 
 | 519 |     return control::FieldMode::fieldModeEnabled(); | 
 | 520 | } | 
 | 521 |  | 
 | 522 | void ItemUpdater::restoreFieldModeStatus() | 
 | 523 | { | 
| Michael Tritz | ff0b421 | 2017-10-24 17:38:09 -0500 | [diff] [blame] | 524 |     std::ifstream input("/dev/mtd/u-boot-env"); | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 525 |     std::string envVar; | 
 | 526 |     std::getline(input, envVar); | 
 | 527 |  | 
| Gunnar Mills | 9a78224 | 2017-08-22 16:23:15 -0500 | [diff] [blame] | 528 |     if (envVar.find("fieldmode=true") != std::string::npos) | 
| Michael Tritz | 0129d92 | 2017-08-10 19:33:46 -0500 | [diff] [blame] | 529 |     { | 
 | 530 |         ItemUpdater::fieldModeEnabled(true); | 
 | 531 |     } | 
 | 532 | } | 
 | 533 |  | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 534 | void ItemUpdater::setBMCInventoryPath() | 
 | 535 | { | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 536 |     auto depth = 0; | 
 | 537 |     auto mapperCall = bus.new_method_call(MAPPER_BUSNAME, | 
 | 538 |                                           MAPPER_PATH, | 
 | 539 |                                           MAPPER_INTERFACE, | 
 | 540 |                                           "GetSubTreePaths"); | 
 | 541 |  | 
| Adriana Kobylak | 1254c62 | 2017-12-07 12:24:56 -0600 | [diff] [blame] | 542 |     mapperCall.append(INVENTORY_PATH); | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 543 |     mapperCall.append(depth); | 
| Adriana Kobylak | 1254c62 | 2017-12-07 12:24:56 -0600 | [diff] [blame] | 544 |     std::vector<std::string> filter = {BMC_INVENTORY_INTERFACE}; | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 545 |     mapperCall.append(filter); | 
 | 546 |  | 
 | 547 |     auto response = bus.call(mapperCall); | 
 | 548 |     if (response.is_method_error()) | 
 | 549 |     { | 
 | 550 |         log<level::ERR>("Error in mapper GetSubTreePath"); | 
 | 551 |         return; | 
 | 552 |     } | 
 | 553 |  | 
 | 554 |     using ObjectPaths = std::vector<std::string>; | 
 | 555 |     ObjectPaths result; | 
 | 556 |     response.read(result); | 
 | 557 |  | 
| Adriana Kobylak | 1254c62 | 2017-12-07 12:24:56 -0600 | [diff] [blame] | 558 |     if (!result.empty()) | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 559 |     { | 
| Adriana Kobylak | 1254c62 | 2017-12-07 12:24:56 -0600 | [diff] [blame] | 560 |         bmcInventoryPath = result.front(); | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 561 |     } | 
 | 562 |  | 
| Adriana Kobylak | 1254c62 | 2017-12-07 12:24:56 -0600 | [diff] [blame] | 563 |     return; | 
| Gunnar Mills | b60add1 | 2017-08-24 16:41:42 -0500 | [diff] [blame] | 564 | } | 
 | 565 |  | 
| Gunnar Mills | f10b232 | 2017-09-21 15:31:55 -0500 | [diff] [blame] | 566 | void ItemUpdater::createActiveAssociation(const std::string& path) | 
| Gunnar Mills | ded875d | 2017-08-28 16:44:52 -0500 | [diff] [blame] | 567 | { | 
 | 568 |     assocs.emplace_back(std::make_tuple(ACTIVE_FWD_ASSOCIATION, | 
 | 569 |                                         ACTIVE_REV_ASSOCIATION, | 
 | 570 |                                         path)); | 
 | 571 |     associations(assocs); | 
 | 572 | } | 
 | 573 |  | 
| Gunnar Mills | 88e8a32 | 2017-09-13 11:09:28 -0500 | [diff] [blame] | 574 | void ItemUpdater::createFunctionalAssociation(const std::string& path) | 
 | 575 | { | 
 | 576 |     assocs.emplace_back(std::make_tuple(FUNCTIONAL_FWD_ASSOCIATION, | 
 | 577 |                                         FUNCTIONAL_REV_ASSOCIATION, | 
 | 578 |                                         path)); | 
 | 579 |     associations(assocs); | 
 | 580 | } | 
 | 581 |  | 
| Gunnar Mills | f10b232 | 2017-09-21 15:31:55 -0500 | [diff] [blame] | 582 | void ItemUpdater::removeActiveAssociation(const std::string& path) | 
| Gunnar Mills | ded875d | 2017-08-28 16:44:52 -0500 | [diff] [blame] | 583 | { | 
 | 584 |     for (auto iter = assocs.begin(); iter != assocs.end();) | 
 | 585 |     { | 
| Gunnar Mills | 88e8a32 | 2017-09-13 11:09:28 -0500 | [diff] [blame] | 586 |         // Since there could be multiple associations to the same path, | 
 | 587 |         // only remove ones that have an active forward association. | 
 | 588 |         if ((std::get<0>(*iter)).compare(ACTIVE_FWD_ASSOCIATION) == 0 && | 
 | 589 |             (std::get<2>(*iter)).compare(path) == 0) | 
| Gunnar Mills | ded875d | 2017-08-28 16:44:52 -0500 | [diff] [blame] | 590 |         { | 
 | 591 |             iter = assocs.erase(iter); | 
 | 592 |             associations(assocs); | 
 | 593 |         } | 
 | 594 |         else | 
 | 595 |         { | 
 | 596 |             ++iter; | 
 | 597 |         } | 
 | 598 |     } | 
 | 599 | } | 
 | 600 |  | 
| Saqib Khan | b9da663 | 2017-09-13 09:48:37 -0500 | [diff] [blame] | 601 | bool ItemUpdater::isLowestPriority(uint8_t value) | 
 | 602 | { | 
 | 603 |     for (const auto& intf : activations) | 
 | 604 |     { | 
| Gunnar Mills | d16bcbd | 2017-10-08 16:50:42 -0500 | [diff] [blame] | 605 |         if (intf.second->redundancyPriority) | 
| Saqib Khan | b9da663 | 2017-09-13 09:48:37 -0500 | [diff] [blame] | 606 |         { | 
 | 607 |             if (intf.second->redundancyPriority.get()->priority() < value) | 
 | 608 |             { | 
 | 609 |                 return false; | 
 | 610 |             } | 
 | 611 |         } | 
 | 612 |     } | 
 | 613 |     return true; | 
 | 614 | } | 
 | 615 |  | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 616 | void ItemUpdater::updateUbootEnvVars(const std::string& versionId) | 
 | 617 | { | 
 | 618 |     auto method = bus.new_method_call( | 
 | 619 |             SYSTEMD_BUSNAME, | 
 | 620 |             SYSTEMD_PATH, | 
 | 621 |             SYSTEMD_INTERFACE, | 
 | 622 |             "StartUnit"); | 
 | 623 |     auto updateEnvVarsFile = "obmc-flash-bmc-updateubootvars@" + versionId + | 
 | 624 |             ".service"; | 
 | 625 |     method.append(updateEnvVarsFile, "replace"); | 
 | 626 |     auto result = bus.call(method); | 
 | 627 |  | 
 | 628 |     //Check that the bus call didn't result in an error | 
 | 629 |     if (result.is_method_error()) | 
 | 630 |     { | 
 | 631 |         log<level::ERR>("Failed to update u-boot env variables", | 
| Adriana Kobylak | 596466b | 2018-02-13 14:48:53 -0600 | [diff] [blame^] | 632 |                         entry("VERSIONID=%s", versionId.c_str())); | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 633 |     } | 
 | 634 | } | 
 | 635 |  | 
| Saqib Khan | 49446ae | 2017-10-02 10:54:20 -0500 | [diff] [blame] | 636 | void ItemUpdater::resetUbootEnvVars() | 
 | 637 | { | 
 | 638 |     decltype(activations.begin()->second->redundancyPriority.get()->priority()) | 
 | 639 |              lowestPriority = std::numeric_limits<uint8_t>::max(); | 
 | 640 |     decltype(activations.begin()->second->versionId) lowestPriorityVersion; | 
 | 641 |     for (const auto& intf : activations) | 
 | 642 |     { | 
 | 643 |         if (!intf.second->redundancyPriority.get()) | 
 | 644 |         { | 
 | 645 |             // Skip this version if the redundancyPriority is not initialized. | 
 | 646 |             continue; | 
 | 647 |         } | 
 | 648 |  | 
 | 649 |         if (intf.second->redundancyPriority.get()->priority() | 
 | 650 |             <= lowestPriority) | 
 | 651 |         { | 
 | 652 |             lowestPriority = intf.second->redundancyPriority.get()->priority(); | 
 | 653 |             lowestPriorityVersion = intf.second->versionId; | 
 | 654 |         } | 
 | 655 |     } | 
 | 656 |  | 
| Saqib Khan | f0382c3 | 2017-10-24 13:36:22 -0500 | [diff] [blame] | 657 |     // Update the U-boot environment variable to point to the lowest priority | 
| Adriana Kobylak | b77551c | 2017-10-27 12:46:23 -0500 | [diff] [blame] | 658 |     updateUbootEnvVars(lowestPriorityVersion); | 
| Saqib Khan | 49446ae | 2017-10-02 10:54:20 -0500 | [diff] [blame] | 659 | } | 
 | 660 |  | 
| Gunnar Mills | ec1b41c | 2017-05-02 12:20:36 -0500 | [diff] [blame] | 661 | } // namespace updater | 
 | 662 | } // namespace software | 
 | 663 | } // namespace phosphor |