| Matt Spinler | 711d51d | 2019-11-06 09:36:51 -0600 | [diff] [blame] | 1 | /** | 
|  | 2 | * Copyright © 2019 IBM Corporation | 
|  | 3 | * | 
|  | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 5 | * you may not use this file except in compliance with the License. | 
|  | 6 | * You may obtain a copy of the License at | 
|  | 7 | * | 
|  | 8 | *     http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 9 | * | 
|  | 10 | * Unless required by applicable law or agreed to in writing, software | 
|  | 11 | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 13 | * See the License for the specific language governing permissions and | 
|  | 14 | * limitations under the License. | 
|  | 15 | */ | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 16 | #include "manager.hpp" | 
|  | 17 |  | 
|  | 18 | #include "additional_data.hpp" | 
| Matt Spinler | 05c2c6c | 2019-12-18 14:02:09 -0600 | [diff] [blame] | 19 | #include "json_utils.hpp" | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 20 | #include "pel.hpp" | 
| Vijay Lobo | 2fb1021 | 2021-08-22 23:24:16 -0500 | [diff] [blame] | 21 | #include "pel_entry.hpp" | 
| Matt Spinler | 1962e08 | 2020-08-05 13:44:53 -0500 | [diff] [blame] | 22 | #include "service_indicators.hpp" | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 23 |  | 
| Matt Spinler | 22421b9 | 2020-07-17 09:41:08 -0500 | [diff] [blame] | 24 | #include <fmt/format.h> | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 25 | #include <sys/inotify.h> | 
| Matt Spinler | 6b1a5c8 | 2020-01-07 08:48:53 -0600 | [diff] [blame] | 26 | #include <unistd.h> | 
|  | 27 |  | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 28 | #include <filesystem> | 
|  | 29 | #include <fstream> | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 30 | #include <xyz/openbmc_project/Common/error.hpp> | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 31 | #include <xyz/openbmc_project/Logging/Create/server.hpp> | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 32 |  | 
|  | 33 | namespace openpower | 
|  | 34 | { | 
|  | 35 | namespace pels | 
|  | 36 | { | 
|  | 37 |  | 
|  | 38 | using namespace phosphor::logging; | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 39 | namespace fs = std::filesystem; | 
| Harisuddin Mohamed Isa | 0f717e1 | 2020-01-15 20:05:33 +0800 | [diff] [blame] | 40 | namespace rg = openpower::pels::message; | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 41 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 42 | namespace common_error = sdbusplus::xyz::openbmc_project::Common::Error; | 
|  | 43 |  | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 44 | using Create = sdbusplus::xyz::openbmc_project::Logging::server::Create; | 
|  | 45 |  | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 46 | namespace additional_data | 
|  | 47 | { | 
|  | 48 | constexpr auto rawPEL = "RAWPEL"; | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 49 | constexpr auto esel = "ESEL"; | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 50 | constexpr auto error = "ERROR_NAME"; | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 51 | } // namespace additional_data | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 52 |  | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 53 | constexpr auto defaultLogMessage = "xyz.openbmc_project.Logging.Error.Default"; | 
|  | 54 |  | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 55 | Manager::~Manager() | 
|  | 56 | { | 
|  | 57 | if (_pelFileDeleteFD != -1) | 
|  | 58 | { | 
|  | 59 | if (_pelFileDeleteWatchFD != -1) | 
|  | 60 | { | 
|  | 61 | inotify_rm_watch(_pelFileDeleteFD, _pelFileDeleteWatchFD); | 
|  | 62 | } | 
|  | 63 | close(_pelFileDeleteFD); | 
|  | 64 | } | 
|  | 65 | } | 
|  | 66 |  | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 67 | void Manager::create(const std::string& message, uint32_t obmcLogID, | 
|  | 68 | uint64_t timestamp, Entry::Level severity, | 
|  | 69 | const std::vector<std::string>& additionalData, | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 70 | const std::vector<std::string>& associations, | 
|  | 71 | const FFDCEntries& ffdc) | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 72 | { | 
|  | 73 | AdditionalData ad{additionalData}; | 
|  | 74 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 75 | // If a PEL was passed in via a filename or in an ESEL, | 
|  | 76 | // use that.  Otherwise, create one. | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 77 | auto rawPelPath = ad.getValue(additional_data::rawPEL); | 
|  | 78 | if (rawPelPath) | 
|  | 79 | { | 
|  | 80 | addRawPEL(*rawPelPath, obmcLogID); | 
|  | 81 | } | 
|  | 82 | else | 
|  | 83 | { | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 84 | auto esel = ad.getValue(additional_data::esel); | 
|  | 85 | if (esel) | 
|  | 86 | { | 
|  | 87 | addESELPEL(*esel, obmcLogID); | 
|  | 88 | } | 
|  | 89 | else | 
|  | 90 | { | 
|  | 91 | createPEL(message, obmcLogID, timestamp, severity, additionalData, | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 92 | associations, ffdc); | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 93 | } | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 94 | } | 
| Adriana Kobylak | e7d271a | 2020-12-07 14:32:44 -0600 | [diff] [blame] | 95 |  | 
|  | 96 | setEntryPath(obmcLogID); | 
| Vijay Lobo | cbc93a4 | 2021-05-20 19:04:07 -0500 | [diff] [blame] | 97 | setServiceProviderNotifyFlag(obmcLogID); | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 98 | } | 
|  | 99 |  | 
|  | 100 | void Manager::addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID) | 
|  | 101 | { | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 102 | if (fs::exists(rawPelPath)) | 
|  | 103 | { | 
|  | 104 | std::ifstream file(rawPelPath, std::ios::in | std::ios::binary); | 
|  | 105 |  | 
|  | 106 | auto data = std::vector<uint8_t>(std::istreambuf_iterator<char>(file), | 
|  | 107 | std::istreambuf_iterator<char>()); | 
|  | 108 | if (file.fail()) | 
|  | 109 | { | 
|  | 110 | log<level::ERR>("Filesystem error reading a raw PEL", | 
|  | 111 | entry("PELFILE=%s", rawPelPath.c_str()), | 
|  | 112 | entry("OBMCLOGID=%d", obmcLogID)); | 
|  | 113 | // TODO, Decide what to do here. Maybe nothing. | 
|  | 114 | return; | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | file.close(); | 
|  | 118 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 119 | addPEL(data, obmcLogID); | 
| Matt Spinler | 6741692 | 2021-07-19 12:34:57 -0600 | [diff] [blame] | 120 |  | 
|  | 121 | std::error_code ec; | 
|  | 122 | fs::remove(rawPelPath, ec); | 
| Matt Spinler | 89fa082 | 2019-07-17 13:54:30 -0500 | [diff] [blame] | 123 | } | 
|  | 124 | else | 
|  | 125 | { | 
|  | 126 | log<level::ERR>("Raw PEL file from BMC event log does not exist", | 
|  | 127 | entry("PELFILE=%s", (rawPelPath).c_str()), | 
|  | 128 | entry("OBMCLOGID=%d", obmcLogID)); | 
|  | 129 | } | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 130 | } | 
|  | 131 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 132 | void Manager::addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID) | 
|  | 133 | { | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 134 | auto pel = std::make_unique<openpower::pels::PEL>(pelData, obmcLogID); | 
|  | 135 | if (pel->valid()) | 
|  | 136 | { | 
| Sumit Kumar | a1e4084 | 2021-06-23 09:52:25 -0500 | [diff] [blame] | 137 | // Assign Id other than to Hostbot PEL | 
|  | 138 | if ((pel->privateHeader()).creatorID() != | 
|  | 139 | static_cast<uint8_t>(CreatorID::hostboot)) | 
|  | 140 | { | 
|  | 141 | pel->assignID(); | 
|  | 142 | } | 
| Sumit Kumar | 2ccdcef | 2021-07-31 10:04:58 -0500 | [diff] [blame] | 143 | else | 
|  | 144 | { | 
|  | 145 | const Repository::LogID id{Repository::LogID::Pel(pel->id())}; | 
|  | 146 | auto result = _repo.hasPEL(id); | 
|  | 147 | if (result) | 
|  | 148 | { | 
|  | 149 | log<level::WARNING>( | 
|  | 150 | fmt::format("Duplicate HostBoot PEL Id {:#X} found; " | 
|  | 151 | "moving it to archive folder", | 
|  | 152 | pel->id()) | 
|  | 153 | .c_str()); | 
|  | 154 |  | 
|  | 155 | _repo.archivePEL(*pel); | 
|  | 156 | return; | 
|  | 157 | } | 
|  | 158 | } | 
| Sumit Kumar | a1e4084 | 2021-06-23 09:52:25 -0500 | [diff] [blame] | 159 |  | 
|  | 160 | // PELs created by others still need this field set by us. | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 161 | pel->setCommitTime(); | 
|  | 162 |  | 
| Sumit Kumar | 3160a54 | 2021-04-26 08:07:04 -0500 | [diff] [blame] | 163 | // Update System Info to Extended User Data | 
|  | 164 | pel->updateSysInfoInExtendedUserDataSection(*_dataIface); | 
|  | 165 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 166 | try | 
|  | 167 | { | 
| Matt Spinler | d0ab1cf | 2021-02-10 13:26:18 -0600 | [diff] [blame] | 168 | log<level::DEBUG>( | 
| Matt Spinler | 6321ba3 | 2020-07-17 09:58:19 -0500 | [diff] [blame] | 169 | fmt::format("Adding external PEL {:#x} (BMC ID {}) to repo", | 
|  | 170 | pel->id(), obmcLogID) | 
|  | 171 | .c_str()); | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 172 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 173 | _repo.add(pel); | 
| Matt Spinler | 7e727a3 | 2020-07-07 15:00:17 -0500 | [diff] [blame] | 174 |  | 
|  | 175 | if (_repo.sizeWarning()) | 
|  | 176 | { | 
|  | 177 | scheduleRepoPrune(); | 
|  | 178 | } | 
| Matt Spinler | 1962e08 | 2020-08-05 13:44:53 -0500 | [diff] [blame] | 179 |  | 
|  | 180 | // Activate any resulting service indicators if necessary | 
|  | 181 | auto policy = service_indicators::getPolicy(*_dataIface); | 
|  | 182 | policy->activate(*pel); | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 183 | } | 
|  | 184 | catch (std::exception& e) | 
|  | 185 | { | 
|  | 186 | // Probably a full or r/o filesystem, not much we can do. | 
|  | 187 | log<level::ERR>("Unable to add PEL to Repository", | 
|  | 188 | entry("PEL_ID=0x%X", pel->id())); | 
|  | 189 | } | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 190 |  | 
|  | 191 | // Check if firmware should quiesce system due to error | 
|  | 192 | checkPelAndQuiesce(pel); | 
| Vijay Lobo | d354a39 | 2021-06-01 16:21:02 -0500 | [diff] [blame] | 193 | updateEventId(pel); | 
| Vijay Lobo | 593a4c6 | 2021-06-16 14:25:26 -0500 | [diff] [blame] | 194 | updateResolution(pel); | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 195 | createPELEntry(obmcLogID); | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 196 | } | 
|  | 197 | else | 
|  | 198 | { | 
|  | 199 | log<level::ERR>("Invalid PEL received from the host", | 
|  | 200 | entry("OBMCLOGID=%d", obmcLogID)); | 
|  | 201 |  | 
|  | 202 | AdditionalData ad; | 
|  | 203 | ad.add("PLID", getNumberString("0x%08X", pel->plid())); | 
|  | 204 | ad.add("OBMC_LOG_ID", std::to_string(obmcLogID)); | 
|  | 205 | ad.add("PEL_SIZE", std::to_string(pelData.size())); | 
|  | 206 |  | 
|  | 207 | std::string asciiString; | 
|  | 208 | auto src = pel->primarySRC(); | 
|  | 209 | if (src) | 
|  | 210 | { | 
|  | 211 | asciiString = (*src)->asciiString(); | 
|  | 212 | } | 
|  | 213 |  | 
|  | 214 | ad.add("SRC", asciiString); | 
|  | 215 |  | 
|  | 216 | _eventLogger.log("org.open_power.Logging.Error.BadHostPEL", | 
|  | 217 | Entry::Level::Error, ad); | 
| Matt Spinler | fe72189 | 2020-04-02 10:28:08 -0500 | [diff] [blame] | 218 |  | 
|  | 219 | // Save it to a file for debug in the lab.  Just keep the latest. | 
|  | 220 | // Not adding it to the PEL because it could already be max size | 
|  | 221 | // and don't want to truncate an already invalid PEL. | 
|  | 222 | std::ofstream pelFile{getPELRepoPath() / "badPEL"}; | 
|  | 223 | pelFile.write(reinterpret_cast<const char*>(pelData.data()), | 
|  | 224 | pelData.size()); | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 225 | } | 
|  | 226 | } | 
|  | 227 |  | 
|  | 228 | void Manager::addESELPEL(const std::string& esel, uint32_t obmcLogID) | 
|  | 229 | { | 
|  | 230 | std::vector<uint8_t> data; | 
|  | 231 |  | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 232 | log<level::DEBUG>("Adding PEL from ESEL", | 
|  | 233 | entry("OBMC_LOG_ID=%d", obmcLogID)); | 
|  | 234 |  | 
| Matt Spinler | 19e7290 | 2020-01-24 11:05:20 -0600 | [diff] [blame] | 235 | try | 
|  | 236 | { | 
|  | 237 | data = std::move(eselToRawData(esel)); | 
|  | 238 | } | 
|  | 239 | catch (std::exception& e) | 
|  | 240 | { | 
|  | 241 | // Try to add it below anyway, so it follows the usual bad data path. | 
|  | 242 | log<level::ERR>("Problems converting ESEL string to a byte vector"); | 
|  | 243 | } | 
|  | 244 |  | 
|  | 245 | addPEL(data, obmcLogID); | 
|  | 246 | } | 
|  | 247 |  | 
|  | 248 | std::vector<uint8_t> Manager::eselToRawData(const std::string& esel) | 
|  | 249 | { | 
|  | 250 | std::vector<uint8_t> data; | 
|  | 251 | std::string byteString; | 
|  | 252 |  | 
|  | 253 | // As the eSEL string looks like: "50 48 00 ab ..." there are 3 | 
|  | 254 | // characters per raw byte, and since the actual PEL data starts | 
|  | 255 | // at the 16th byte, the code will grab the PEL data starting at | 
|  | 256 | // offset 48 in the string. | 
|  | 257 | static constexpr size_t pelStart = 16 * 3; | 
|  | 258 |  | 
|  | 259 | if (esel.size() <= pelStart) | 
|  | 260 | { | 
|  | 261 | log<level::ERR>("ESEL data too short", | 
|  | 262 | entry("ESEL_SIZE=%d", esel.size())); | 
|  | 263 |  | 
|  | 264 | throw std::length_error("ESEL data too short"); | 
|  | 265 | } | 
|  | 266 |  | 
|  | 267 | for (size_t i = pelStart; i < esel.size(); i += 3) | 
|  | 268 | { | 
|  | 269 | if (i + 1 < esel.size()) | 
|  | 270 | { | 
|  | 271 | byteString = esel.substr(i, 2); | 
|  | 272 | data.push_back(std::stoi(byteString, nullptr, 16)); | 
|  | 273 | } | 
|  | 274 | else | 
|  | 275 | { | 
|  | 276 | log<level::ERR>("ESEL data too short", | 
|  | 277 | entry("ESEL_SIZE=%d", esel.size())); | 
|  | 278 | throw std::length_error("ESEL data too short"); | 
|  | 279 | } | 
|  | 280 | } | 
|  | 281 |  | 
|  | 282 | return data; | 
|  | 283 | } | 
|  | 284 |  | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 285 | void Manager::erase(uint32_t obmcLogID) | 
|  | 286 | { | 
| Matt Spinler | 475e574 | 2019-07-18 16:09:49 -0500 | [diff] [blame] | 287 | Repository::LogID id{Repository::LogID::Obmc(obmcLogID)}; | 
|  | 288 |  | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 289 | auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID); | 
|  | 290 | _pelEntries.erase(path); | 
| Matt Spinler | 475e574 | 2019-07-18 16:09:49 -0500 | [diff] [blame] | 291 | _repo.remove(id); | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 292 | } | 
|  | 293 |  | 
| Patrick Williams | d26fa3e | 2021-04-21 15:22:23 -0500 | [diff] [blame] | 294 | bool Manager::isDeleteProhibited(uint32_t /*obmcLogID*/) | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 295 | { | 
|  | 296 | return false; | 
|  | 297 | } | 
|  | 298 |  | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 299 | PelFFDC Manager::convertToPelFFDC(const FFDCEntries& ffdc) | 
|  | 300 | { | 
|  | 301 | PelFFDC pelFFDC; | 
|  | 302 |  | 
|  | 303 | std::for_each(ffdc.begin(), ffdc.end(), [&pelFFDC](const auto& f) { | 
|  | 304 | PelFFDCfile pf; | 
|  | 305 | pf.subType = std::get<ffdcSubtypePos>(f); | 
|  | 306 | pf.version = std::get<ffdcVersionPos>(f); | 
|  | 307 | pf.fd = std::get<ffdcFDPos>(f); | 
|  | 308 |  | 
|  | 309 | switch (std::get<ffdcFormatPos>(f)) | 
|  | 310 | { | 
|  | 311 | case Create::FFDCFormat::JSON: | 
|  | 312 | pf.format = UserDataFormat::json; | 
|  | 313 | break; | 
|  | 314 | case Create::FFDCFormat::CBOR: | 
|  | 315 | pf.format = UserDataFormat::cbor; | 
|  | 316 | break; | 
|  | 317 | case Create::FFDCFormat::Text: | 
|  | 318 | pf.format = UserDataFormat::text; | 
|  | 319 | break; | 
|  | 320 | case Create::FFDCFormat::Custom: | 
|  | 321 | pf.format = UserDataFormat::custom; | 
|  | 322 | break; | 
|  | 323 | } | 
|  | 324 |  | 
|  | 325 | pelFFDC.push_back(pf); | 
|  | 326 | }); | 
|  | 327 |  | 
|  | 328 | return pelFFDC; | 
|  | 329 | } | 
|  | 330 |  | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 331 | void Manager::createPEL(const std::string& message, uint32_t obmcLogID, | 
|  | 332 | uint64_t timestamp, | 
|  | 333 | phosphor::logging::Entry::Level severity, | 
|  | 334 | const std::vector<std::string>& additionalData, | 
| Patrick Williams | d26fa3e | 2021-04-21 15:22:23 -0500 | [diff] [blame] | 335 | const std::vector<std::string>& /*associations*/, | 
| Matt Spinler | 56ad2a0 | 2020-03-26 14:00:52 -0500 | [diff] [blame] | 336 | const FFDCEntries& ffdc) | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 337 | { | 
| Harisuddin Mohamed Isa | 0f717e1 | 2020-01-15 20:05:33 +0800 | [diff] [blame] | 338 | auto entry = _registry.lookup(message, rg::LookupType::name); | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 339 | auto pelFFDC = convertToPelFFDC(ffdc); | 
|  | 340 | AdditionalData ad{additionalData}; | 
| Matt Spinler | 1d4c74a | 2019-12-16 14:40:21 -0600 | [diff] [blame] | 341 | std::string msg; | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 342 |  | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 343 | if (!entry) | 
| Matt Spinler | 67456c2 | 2019-10-21 12:22:49 -0500 | [diff] [blame] | 344 | { | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 345 | // Instead, get the default entry that means there is no | 
|  | 346 | // other matching entry.  This error will still use the | 
|  | 347 | // AdditionalData values of the original error, and this | 
|  | 348 | // code will add the error message value that wasn't found | 
|  | 349 | // to this AD.  This way, there will at least be a PEL, | 
|  | 350 | // possibly with callouts, to allow users to debug the | 
|  | 351 | // issue that caused the error even without its own PEL. | 
| Matt Spinler | 1d4c74a | 2019-12-16 14:40:21 -0600 | [diff] [blame] | 352 | msg = "Event not found in PEL message registry: " + message; | 
|  | 353 | log<level::INFO>(msg.c_str()); | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 354 |  | 
|  | 355 | entry = _registry.lookup(defaultLogMessage, rg::LookupType::name); | 
|  | 356 | if (!entry) | 
|  | 357 | { | 
|  | 358 | log<level::ERR>("Default event not found in PEL message registry"); | 
|  | 359 | return; | 
|  | 360 | } | 
|  | 361 |  | 
|  | 362 | ad.add(additional_data::error, message); | 
|  | 363 | } | 
|  | 364 |  | 
|  | 365 | auto pel = std::make_unique<openpower::pels::PEL>( | 
|  | 366 | *entry, obmcLogID, timestamp, severity, ad, pelFFDC, *_dataIface); | 
|  | 367 |  | 
|  | 368 | _repo.add(pel); | 
|  | 369 |  | 
|  | 370 | if (_repo.sizeWarning()) | 
|  | 371 | { | 
|  | 372 | scheduleRepoPrune(); | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | auto src = pel->primarySRC(); | 
|  | 376 | if (src) | 
|  | 377 | { | 
| Matt Spinler | 22421b9 | 2020-07-17 09:41:08 -0500 | [diff] [blame] | 378 | auto msg = | 
|  | 379 | fmt::format("Created PEL {:#x} (BMC ID {}) with SRC {}", pel->id(), | 
|  | 380 | pel->obmcLogID(), (*src)->asciiString()); | 
| Matt Spinler | 30ddc9f | 2020-07-16 15:39:59 -0500 | [diff] [blame] | 381 | while (msg.back() == ' ') | 
|  | 382 | { | 
|  | 383 | msg.pop_back(); | 
|  | 384 | } | 
|  | 385 | log<level::INFO>(msg.c_str()); | 
| Matt Spinler | 1d4c74a | 2019-12-16 14:40:21 -0600 | [diff] [blame] | 386 | } | 
| Matt Spinler | 1962e08 | 2020-08-05 13:44:53 -0500 | [diff] [blame] | 387 |  | 
|  | 388 | // Activate any resulting service indicators if necessary | 
|  | 389 | auto policy = service_indicators::getPolicy(*_dataIface); | 
|  | 390 | policy->activate(*pel); | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 391 |  | 
|  | 392 | // Check if firmware should quiesce system due to error | 
|  | 393 | checkPelAndQuiesce(pel); | 
| Vijay Lobo | d354a39 | 2021-06-01 16:21:02 -0500 | [diff] [blame] | 394 | updateEventId(pel); | 
| Vijay Lobo | 593a4c6 | 2021-06-16 14:25:26 -0500 | [diff] [blame] | 395 | updateResolution(pel); | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 396 | createPELEntry(obmcLogID); | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 397 | } | 
|  | 398 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 399 | sdbusplus::message::unix_fd Manager::getPEL(uint32_t pelID) | 
|  | 400 | { | 
|  | 401 | Repository::LogID id{Repository::LogID::Pel(pelID)}; | 
|  | 402 | std::optional<int> fd; | 
|  | 403 |  | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 404 | log<level::DEBUG>("getPEL", entry("PEL_ID=0x%X", pelID)); | 
|  | 405 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 406 | try | 
|  | 407 | { | 
|  | 408 | fd = _repo.getPELFD(id); | 
|  | 409 | } | 
|  | 410 | catch (std::exception& e) | 
|  | 411 | { | 
|  | 412 | throw common_error::InternalFailure(); | 
|  | 413 | } | 
|  | 414 |  | 
|  | 415 | if (!fd) | 
|  | 416 | { | 
|  | 417 | throw common_error::InvalidArgument(); | 
|  | 418 | } | 
|  | 419 |  | 
| Matt Spinler | 6b1a5c8 | 2020-01-07 08:48:53 -0600 | [diff] [blame] | 420 | scheduleFDClose(*fd); | 
|  | 421 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 422 | return *fd; | 
|  | 423 | } | 
|  | 424 |  | 
| Matt Spinler | 6b1a5c8 | 2020-01-07 08:48:53 -0600 | [diff] [blame] | 425 | void Manager::scheduleFDClose(int fd) | 
|  | 426 | { | 
|  | 427 | _fdCloserEventSource = std::make_unique<sdeventplus::source::Defer>( | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 428 | _event, std::bind(std::mem_fn(&Manager::closeFD), this, fd, | 
|  | 429 | std::placeholders::_1)); | 
| Matt Spinler | 6b1a5c8 | 2020-01-07 08:48:53 -0600 | [diff] [blame] | 430 | } | 
|  | 431 |  | 
| Patrick Williams | d26fa3e | 2021-04-21 15:22:23 -0500 | [diff] [blame] | 432 | void Manager::closeFD(int fd, sdeventplus::source::EventBase& /*source*/) | 
| Matt Spinler | 6b1a5c8 | 2020-01-07 08:48:53 -0600 | [diff] [blame] | 433 | { | 
|  | 434 | close(fd); | 
|  | 435 | _fdCloserEventSource.reset(); | 
|  | 436 | } | 
|  | 437 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 438 | std::vector<uint8_t> Manager::getPELFromOBMCID(uint32_t obmcLogID) | 
|  | 439 | { | 
|  | 440 | Repository::LogID id{Repository::LogID::Obmc(obmcLogID)}; | 
|  | 441 | std::optional<std::vector<uint8_t>> data; | 
|  | 442 |  | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 443 | log<level::DEBUG>("getPELFromOBMCID", entry("OBMC_LOG_ID=%d", obmcLogID)); | 
|  | 444 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 445 | try | 
|  | 446 | { | 
|  | 447 | data = _repo.getPELData(id); | 
|  | 448 | } | 
|  | 449 | catch (std::exception& e) | 
|  | 450 | { | 
|  | 451 | throw common_error::InternalFailure(); | 
|  | 452 | } | 
|  | 453 |  | 
|  | 454 | if (!data) | 
|  | 455 | { | 
|  | 456 | throw common_error::InvalidArgument(); | 
|  | 457 | } | 
|  | 458 |  | 
|  | 459 | return *data; | 
|  | 460 | } | 
|  | 461 |  | 
|  | 462 | void Manager::hostAck(uint32_t pelID) | 
|  | 463 | { | 
|  | 464 | Repository::LogID id{Repository::LogID::Pel(pelID)}; | 
|  | 465 |  | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 466 | log<level::DEBUG>("HostAck", entry("PEL_ID=0x%X", pelID)); | 
|  | 467 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 468 | if (!_repo.hasPEL(id)) | 
|  | 469 | { | 
|  | 470 | throw common_error::InvalidArgument(); | 
|  | 471 | } | 
|  | 472 |  | 
|  | 473 | if (_hostNotifier) | 
|  | 474 | { | 
|  | 475 | _hostNotifier->ackPEL(pelID); | 
|  | 476 | } | 
|  | 477 | } | 
|  | 478 |  | 
|  | 479 | void Manager::hostReject(uint32_t pelID, RejectionReason reason) | 
|  | 480 | { | 
|  | 481 | Repository::LogID id{Repository::LogID::Pel(pelID)}; | 
|  | 482 |  | 
| Matt Spinler | 5f5352e | 2020-03-05 16:23:27 -0600 | [diff] [blame] | 483 | log<level::DEBUG>("HostReject", entry("PEL_ID=0x%X", pelID), | 
|  | 484 | entry("REASON=%d", static_cast<int>(reason))); | 
|  | 485 |  | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 486 | if (!_repo.hasPEL(id)) | 
|  | 487 | { | 
|  | 488 | throw common_error::InvalidArgument(); | 
|  | 489 | } | 
|  | 490 |  | 
| Matt Spinler | 05c2c6c | 2019-12-18 14:02:09 -0600 | [diff] [blame] | 491 | if (reason == RejectionReason::BadPEL) | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 492 | { | 
| Matt Spinler | 05c2c6c | 2019-12-18 14:02:09 -0600 | [diff] [blame] | 493 | AdditionalData data; | 
|  | 494 | data.add("BAD_ID", getNumberString("0x%08X", pelID)); | 
|  | 495 | _eventLogger.log("org.open_power.Logging.Error.SentBadPELToHost", | 
|  | 496 | Entry::Level::Informational, data); | 
|  | 497 | if (_hostNotifier) | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 498 | { | 
|  | 499 | _hostNotifier->setBadPEL(pelID); | 
|  | 500 | } | 
| Matt Spinler | 05c2c6c | 2019-12-18 14:02:09 -0600 | [diff] [blame] | 501 | } | 
|  | 502 | else if ((reason == RejectionReason::HostFull) && _hostNotifier) | 
|  | 503 | { | 
|  | 504 | _hostNotifier->setHostFull(pelID); | 
| Matt Spinler | a34ab72 | 2019-12-16 10:39:32 -0600 | [diff] [blame] | 505 | } | 
|  | 506 | } | 
|  | 507 |  | 
| Matt Spinler | 7e727a3 | 2020-07-07 15:00:17 -0500 | [diff] [blame] | 508 | void Manager::scheduleRepoPrune() | 
|  | 509 | { | 
| Matt Spinler | 7e727a3 | 2020-07-07 15:00:17 -0500 | [diff] [blame] | 510 | _repoPrunerEventSource = std::make_unique<sdeventplus::source::Defer>( | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 511 | _event, std::bind(std::mem_fn(&Manager::pruneRepo), this, | 
|  | 512 | std::placeholders::_1)); | 
| Matt Spinler | 7e727a3 | 2020-07-07 15:00:17 -0500 | [diff] [blame] | 513 | } | 
|  | 514 |  | 
| Patrick Williams | d26fa3e | 2021-04-21 15:22:23 -0500 | [diff] [blame] | 515 | void Manager::pruneRepo(sdeventplus::source::EventBase& /*source*/) | 
| Matt Spinler | 7e727a3 | 2020-07-07 15:00:17 -0500 | [diff] [blame] | 516 | { | 
|  | 517 | auto idsToDelete = _repo.prune(); | 
|  | 518 |  | 
|  | 519 | // Remove the OpenBMC event logs for the PELs that were just removed. | 
|  | 520 | std::for_each(idsToDelete.begin(), idsToDelete.end(), | 
|  | 521 | [this](auto id) { this->_logManager.erase(id); }); | 
|  | 522 |  | 
|  | 523 | _repoPrunerEventSource.reset(); | 
|  | 524 | } | 
|  | 525 |  | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 526 | void Manager::setupPELDeleteWatch() | 
|  | 527 | { | 
|  | 528 | _pelFileDeleteFD = inotify_init1(IN_NONBLOCK); | 
|  | 529 | if (-1 == _pelFileDeleteFD) | 
|  | 530 | { | 
|  | 531 | auto e = errno; | 
|  | 532 | std::string msg = | 
|  | 533 | "inotify_init1 failed with errno " + std::to_string(e); | 
|  | 534 | log<level::ERR>(msg.c_str()); | 
|  | 535 | abort(); | 
|  | 536 | } | 
|  | 537 |  | 
|  | 538 | _pelFileDeleteWatchFD = inotify_add_watch( | 
|  | 539 | _pelFileDeleteFD, _repo.repoPath().c_str(), IN_DELETE); | 
|  | 540 | if (-1 == _pelFileDeleteWatchFD) | 
|  | 541 | { | 
|  | 542 | auto e = errno; | 
|  | 543 | std::string msg = | 
|  | 544 | "inotify_add_watch failed with error " + std::to_string(e); | 
|  | 545 | log<level::ERR>(msg.c_str()); | 
|  | 546 | abort(); | 
|  | 547 | } | 
|  | 548 |  | 
|  | 549 | _pelFileDeleteEventSource = std::make_unique<sdeventplus::source::IO>( | 
|  | 550 | _event, _pelFileDeleteFD, EPOLLIN, | 
|  | 551 | std::bind(std::mem_fn(&Manager::pelFileDeleted), this, | 
|  | 552 | std::placeholders::_1, std::placeholders::_2, | 
|  | 553 | std::placeholders::_3)); | 
|  | 554 | } | 
|  | 555 |  | 
| Patrick Williams | d26fa3e | 2021-04-21 15:22:23 -0500 | [diff] [blame] | 556 | void Manager::pelFileDeleted(sdeventplus::source::IO& /*io*/, int /*fd*/, | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 557 | uint32_t revents) | 
|  | 558 | { | 
|  | 559 | if (!(revents & EPOLLIN)) | 
|  | 560 | { | 
|  | 561 | return; | 
|  | 562 | } | 
|  | 563 |  | 
|  | 564 | // An event for 1 PEL uses 48B. When all PELs are deleted at once, | 
|  | 565 | // as many events as there is room for can be handled in one callback. | 
|  | 566 | // A size of 2000 will allow 41 to be processed, with additional | 
|  | 567 | // callbacks being needed to process the remaining ones. | 
| Matt Spinler | 9d59d58 | 2021-05-19 07:57:10 -0600 | [diff] [blame] | 568 | std::array<uint8_t, 2000> data{}; | 
| Matt Spinler | ff9cec2 | 2020-07-15 13:06:35 -0500 | [diff] [blame] | 569 | auto bytesRead = read(_pelFileDeleteFD, data.data(), data.size()); | 
|  | 570 | if (bytesRead < 0) | 
|  | 571 | { | 
|  | 572 | auto e = errno; | 
|  | 573 | std::string msg = "Failed reading data from inotify event, errno = " + | 
|  | 574 | std::to_string(e); | 
|  | 575 | log<level::ERR>(msg.c_str()); | 
|  | 576 | abort(); | 
|  | 577 | } | 
|  | 578 |  | 
|  | 579 | auto offset = 0; | 
|  | 580 | while (offset < bytesRead) | 
|  | 581 | { | 
|  | 582 | auto event = reinterpret_cast<inotify_event*>(&data[offset]); | 
|  | 583 | if (event->mask & IN_DELETE) | 
|  | 584 | { | 
|  | 585 | std::string filename{event->name}; | 
|  | 586 |  | 
|  | 587 | // Get the PEL ID from the filename and tell the | 
|  | 588 | // repo it's been removed, and then delete the BMC | 
|  | 589 | // event log if it's there. | 
|  | 590 | auto pos = filename.find_first_of('_'); | 
|  | 591 | if (pos != std::string::npos) | 
|  | 592 | { | 
|  | 593 | try | 
|  | 594 | { | 
|  | 595 | auto idString = filename.substr(pos + 1); | 
|  | 596 | auto pelID = std::stoul(idString, nullptr, 16); | 
|  | 597 |  | 
|  | 598 | Repository::LogID id{Repository::LogID::Pel(pelID)}; | 
|  | 599 | auto removedLogID = _repo.remove(id); | 
|  | 600 | if (removedLogID) | 
|  | 601 | { | 
|  | 602 | _logManager.erase(removedLogID->obmcID.id); | 
|  | 603 | } | 
|  | 604 | } | 
|  | 605 | catch (const std::exception& e) | 
|  | 606 | { | 
|  | 607 | log<level::INFO>("Could not find PEL ID from its filename", | 
|  | 608 | entry("FILENAME=%s", filename.c_str())); | 
|  | 609 | } | 
|  | 610 | } | 
|  | 611 | } | 
|  | 612 |  | 
|  | 613 | offset += offsetof(inotify_event, name) + event->len; | 
|  | 614 | } | 
|  | 615 | } | 
| Matt Spinler | 9cc3007 | 2020-09-16 15:39:34 -0500 | [diff] [blame] | 616 |  | 
|  | 617 | std::tuple<uint32_t, uint32_t> Manager::createPELWithFFDCFiles( | 
|  | 618 | std::string message, Entry::Level severity, | 
|  | 619 | std::map<std::string, std::string> additionalData, | 
|  | 620 | std::vector<std::tuple< | 
|  | 621 | sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat, | 
|  | 622 | uint8_t, uint8_t, sdbusplus::message::unix_fd>> | 
|  | 623 | fFDC) | 
|  | 624 | { | 
| Matt Spinler | 44893cc | 2020-08-26 11:34:17 -0500 | [diff] [blame] | 625 | _logManager.createWithFFDC(message, severity, additionalData, fFDC); | 
|  | 626 |  | 
|  | 627 | return {_logManager.lastEntryID(), _repo.lastPelID()}; | 
| Matt Spinler | 9cc3007 | 2020-09-16 15:39:34 -0500 | [diff] [blame] | 628 | } | 
|  | 629 |  | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 630 | void Manager::checkPelAndQuiesce(std::unique_ptr<openpower::pels::PEL>& pel) | 
|  | 631 | { | 
| Matt Spinler | b2abc04 | 2021-05-17 15:32:50 -0600 | [diff] [blame] | 632 | if ((pel->userHeader().severity() == | 
|  | 633 | static_cast<uint8_t>(SeverityType::nonError)) || | 
|  | 634 | (pel->userHeader().severity() == | 
|  | 635 | static_cast<uint8_t>(SeverityType::recovered))) | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 636 | { | 
| Matt Spinler | b2abc04 | 2021-05-17 15:32:50 -0600 | [diff] [blame] | 637 | log<level::DEBUG>( | 
|  | 638 | "PEL severity informational or recovered. no quiesce needed"); | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 639 | return; | 
|  | 640 | } | 
|  | 641 | if (!_logManager.isQuiesceOnErrorEnabled()) | 
|  | 642 | { | 
|  | 643 | log<level::DEBUG>("QuiesceOnHwError not enabled, no quiesce needed"); | 
|  | 644 | return; | 
|  | 645 | } | 
|  | 646 |  | 
|  | 647 | // Now check if it has any type of callout | 
|  | 648 | if (pel->isCalloutPresent()) | 
|  | 649 | { | 
| Matt Spinler | b2abc04 | 2021-05-17 15:32:50 -0600 | [diff] [blame] | 650 | log<level::INFO>( | 
|  | 651 | "QuiesceOnHwError enabled, PEL severity not nonError or recovered, " | 
|  | 652 | "and callout is present"); | 
| Andrew Geissler | 44fc316 | 2020-07-09 09:21:31 -0500 | [diff] [blame] | 653 |  | 
|  | 654 | _logManager.quiesceOnError(pel->obmcLogID()); | 
|  | 655 | } | 
|  | 656 | } | 
|  | 657 |  | 
| Vijay Lobo | d354a39 | 2021-06-01 16:21:02 -0500 | [diff] [blame] | 658 | std::string Manager::getEventId(const openpower::pels::PEL& pel) const | 
|  | 659 | { | 
|  | 660 | std::string str; | 
|  | 661 | auto src = pel.primarySRC(); | 
|  | 662 | if (src) | 
|  | 663 | { | 
|  | 664 | const auto& hexwords = (*src)->hexwordData(); | 
|  | 665 |  | 
|  | 666 | std::string refcode = (*src)->asciiString(); | 
|  | 667 | size_t pos = refcode.find_last_not_of(0x20); | 
|  | 668 | if (pos != std::string::npos) | 
|  | 669 | { | 
|  | 670 | refcode.erase(pos + 1); | 
|  | 671 | } | 
|  | 672 | str = refcode; | 
|  | 673 |  | 
|  | 674 | for (auto& value : hexwords) | 
|  | 675 | { | 
|  | 676 | str += " "; | 
|  | 677 | str += getNumberString("%08X", value); | 
|  | 678 | } | 
|  | 679 | } | 
|  | 680 | return str; | 
|  | 681 | } | 
|  | 682 |  | 
|  | 683 | void Manager::updateEventId(std::unique_ptr<openpower::pels::PEL>& pel) | 
|  | 684 | { | 
|  | 685 | std::string eventIdStr = getEventId(*pel); | 
|  | 686 |  | 
|  | 687 | auto entryN = _logManager.entries.find(pel->obmcLogID()); | 
|  | 688 | if (entryN != _logManager.entries.end()) | 
|  | 689 | { | 
|  | 690 | entryN->second->eventId(eventIdStr); | 
|  | 691 | } | 
|  | 692 | } | 
|  | 693 |  | 
| Vijay Lobo | 593a4c6 | 2021-06-16 14:25:26 -0500 | [diff] [blame] | 694 | std::string Manager::getResolution(const openpower::pels::PEL& pel) const | 
|  | 695 | { | 
|  | 696 | std::string str; | 
|  | 697 | std::string resolution; | 
|  | 698 | auto src = pel.primarySRC(); | 
|  | 699 | if (src) | 
|  | 700 | { | 
|  | 701 | // First extract the callout pointer and then go through | 
|  | 702 | const auto& callouts = (*src)->callouts(); | 
|  | 703 | namespace pv = openpower::pels::pel_values; | 
|  | 704 | // All PELs dont have callout, check before parsing callout data | 
|  | 705 | if (callouts) | 
|  | 706 | { | 
|  | 707 | const auto& entries = callouts->callouts(); | 
|  | 708 | // Entry starts with index 1 | 
|  | 709 | uint8_t index = 1; | 
|  | 710 | for (auto& entry : entries) | 
|  | 711 | { | 
|  | 712 | resolution += std::to_string(index) + ". "; | 
|  | 713 | // Adding Location code to resolution | 
|  | 714 | if (!entry->locationCode().empty()) | 
|  | 715 | resolution += | 
|  | 716 | "Location Code: " + entry->locationCode() + ", "; | 
|  | 717 | if (entry->fruIdentity()) | 
|  | 718 | { | 
|  | 719 | // Get priority and set the resolution string | 
|  | 720 | str = pv::getValue(entry->priority(), | 
|  | 721 | pel_values::calloutPriorityValues, | 
|  | 722 | pel_values::registryNamePos); | 
|  | 723 | str[0] = toupper(str[0]); | 
|  | 724 | resolution += "Priority: " + str + ", "; | 
|  | 725 | if (entry->fruIdentity()->getPN().has_value()) | 
|  | 726 | { | 
|  | 727 | resolution += | 
|  | 728 | "PN: " + entry->fruIdentity()->getPN().value() + | 
|  | 729 | ", "; | 
|  | 730 | } | 
|  | 731 | if (entry->fruIdentity()->getSN().has_value()) | 
|  | 732 | { | 
|  | 733 | resolution += | 
|  | 734 | "SN: " + entry->fruIdentity()->getSN().value() + | 
|  | 735 | ", "; | 
|  | 736 | } | 
|  | 737 | if (entry->fruIdentity()->getCCIN().has_value()) | 
|  | 738 | { | 
|  | 739 | resolution += | 
|  | 740 | "CCIN: " + entry->fruIdentity()->getCCIN().value() + | 
|  | 741 | ", "; | 
|  | 742 | } | 
|  | 743 | // Add the maintenance procedure | 
|  | 744 | if (entry->fruIdentity()->getMaintProc().has_value()) | 
|  | 745 | { | 
|  | 746 | resolution += | 
|  | 747 | "Procedure: " + | 
|  | 748 | entry->fruIdentity()->getMaintProc().value() + ", "; | 
|  | 749 | } | 
|  | 750 | } | 
|  | 751 | resolution.resize(resolution.size() - 2); | 
|  | 752 | resolution += "\n"; | 
|  | 753 | index++; | 
|  | 754 | } | 
|  | 755 | } | 
|  | 756 | } | 
|  | 757 | return resolution; | 
|  | 758 | } | 
|  | 759 |  | 
|  | 760 | void Manager::updateResolution(std::unique_ptr<openpower::pels::PEL>& pel) | 
|  | 761 | { | 
|  | 762 | std::string callouts = getResolution(*pel); | 
|  | 763 | auto entryN = _logManager.entries.find(pel->obmcLogID()); | 
|  | 764 | if (entryN != _logManager.entries.end()) | 
|  | 765 | { | 
|  | 766 | entryN->second->resolution(callouts); | 
|  | 767 | } | 
|  | 768 | } | 
|  | 769 |  | 
| Adriana Kobylak | e7d271a | 2020-12-07 14:32:44 -0600 | [diff] [blame] | 770 | void Manager::setEntryPath(uint32_t obmcLogID) | 
|  | 771 | { | 
|  | 772 | Repository::LogID id{Repository::LogID::Obmc(obmcLogID)}; | 
|  | 773 | if (auto attributes = _repo.getPELAttributes(id); attributes) | 
|  | 774 | { | 
|  | 775 | auto& attr = attributes.value().get(); | 
|  | 776 | auto entry = _logManager.entries.find(obmcLogID); | 
|  | 777 | if (entry != _logManager.entries.end()) | 
|  | 778 | { | 
|  | 779 | entry->second->path(attr.path); | 
|  | 780 | } | 
|  | 781 | } | 
|  | 782 | } | 
|  | 783 |  | 
| Vijay Lobo | cbc93a4 | 2021-05-20 19:04:07 -0500 | [diff] [blame] | 784 | void Manager::setServiceProviderNotifyFlag(uint32_t obmcLogID) | 
|  | 785 | { | 
|  | 786 | Repository::LogID id{Repository::LogID::Obmc(obmcLogID)}; | 
|  | 787 | if (auto attributes = _repo.getPELAttributes(id); attributes) | 
|  | 788 | { | 
|  | 789 | auto& attr = attributes.value().get(); | 
|  | 790 | auto entry = _logManager.entries.find(obmcLogID); | 
|  | 791 | if (entry != _logManager.entries.end()) | 
|  | 792 | { | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 793 | entry->second->serviceProviderNotify( | 
|  | 794 | attr.actionFlags.test(callHomeFlagBit)); | 
| Vijay Lobo | cbc93a4 | 2021-05-20 19:04:07 -0500 | [diff] [blame] | 795 | } | 
|  | 796 | } | 
|  | 797 | } | 
|  | 798 |  | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 799 | void Manager::createPELEntry(uint32_t obmcLogID) | 
|  | 800 | { | 
|  | 801 | std::map<std::string, PropertiesVariant> varData; | 
|  | 802 | Repository::LogID id{Repository::LogID::Obmc(obmcLogID)}; | 
|  | 803 | if (auto attributes = _repo.getPELAttributes(id); attributes) | 
|  | 804 | { | 
|  | 805 | namespace pv = openpower::pels::pel_values; | 
|  | 806 | auto& attr = attributes.value().get(); | 
| Vijay Lobo | b2e541e | 2021-08-31 23:12:47 -0500 | [diff] [blame] | 807 |  | 
|  | 808 | // get the hidden flag values | 
|  | 809 | auto sevType = static_cast<SeverityType>(attr.severity & 0xF0); | 
|  | 810 | auto isHidden = true; | 
|  | 811 | if (((sevType != SeverityType::nonError) && | 
|  | 812 | attr.actionFlags.test(reportFlagBit) && | 
|  | 813 | !attr.actionFlags.test(hiddenFlagBit)) || | 
|  | 814 | ((sevType == SeverityType::nonError) && | 
|  | 815 | attr.actionFlags.test(serviceActionFlagBit))) | 
|  | 816 | { | 
|  | 817 | isHidden = false; | 
|  | 818 | } | 
|  | 819 | varData.emplace(std::string("Hidden"), isHidden); | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 820 | varData.emplace( | 
|  | 821 | std::string("Subsystem"), | 
|  | 822 | pv::getValue(attr.subsystem, pel_values::subsystemValues)); | 
| Vijay Lobo | 2fb1021 | 2021-08-22 23:24:16 -0500 | [diff] [blame] | 823 |  | 
|  | 824 | varData.emplace( | 
|  | 825 | std::string("ManagementSystemAck"), | 
|  | 826 | (attr.hmcState == TransmissionState::acked ? true : false)); | 
|  | 827 |  | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 828 | // Path to create PELEntry Interface is same as PEL | 
|  | 829 | auto path = std::string(OBJ_ENTRY) + '/' + std::to_string(obmcLogID); | 
|  | 830 | // Create Interface for PELEntry and set properties | 
| Vijay Lobo | 2fb1021 | 2021-08-22 23:24:16 -0500 | [diff] [blame] | 831 | auto pelEntry = std::make_unique<PELEntry>(_logManager.getBus(), path, | 
|  | 832 | varData, obmcLogID, &_repo); | 
| Vijay Lobo | afb1b46 | 2021-07-21 23:29:13 -0500 | [diff] [blame] | 833 | _pelEntries.emplace(std::move(path), std::move(pelEntry)); | 
|  | 834 | } | 
|  | 835 | } | 
|  | 836 |  | 
| Ramesh Iyyar | f4203c4 | 2021-06-24 06:09:23 -0500 | [diff] [blame] | 837 | uint32_t Manager::getPELIdFromBMCLogId(uint32_t bmcLogId) | 
|  | 838 | { | 
|  | 839 | Repository::LogID id{Repository::LogID::Obmc(bmcLogId)}; | 
|  | 840 | if (auto logId = _repo.getLogID(id); !logId.has_value()) | 
|  | 841 | { | 
|  | 842 | throw common_error::InvalidArgument(); | 
|  | 843 | } | 
|  | 844 | else | 
|  | 845 | { | 
|  | 846 | return logId->pelID.id; | 
|  | 847 | } | 
|  | 848 | } | 
|  | 849 |  | 
| Ramesh Iyyar | 530efbf | 2021-06-24 06:22:22 -0500 | [diff] [blame] | 850 | uint32_t Manager::getBMCLogIdFromPELId(uint32_t pelId) | 
|  | 851 | { | 
|  | 852 | Repository::LogID id{Repository::LogID::Pel(pelId)}; | 
|  | 853 | if (auto logId = _repo.getLogID(id); !logId.has_value()) | 
|  | 854 | { | 
|  | 855 | throw common_error::InvalidArgument(); | 
|  | 856 | } | 
|  | 857 | else | 
|  | 858 | { | 
|  | 859 | return logId->obmcID.id; | 
|  | 860 | } | 
|  | 861 | } | 
|  | 862 |  | 
| Matt Spinler | 4e8078c | 2019-07-09 13:22:32 -0500 | [diff] [blame] | 863 | } // namespace pels | 
|  | 864 | } // namespace openpower |