1 /** 2 * Copyright © 2020 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 */ 16 #pragma once 17 18 #include "ffdc_file.hpp" 19 #include "journal.hpp" 20 #include "phase_fault.hpp" 21 #include "xyz/openbmc_project/Logging/Create/server.hpp" 22 #include "xyz/openbmc_project/Logging/Entry/server.hpp" 23 24 #include <sdbusplus/bus.hpp> 25 26 #include <cstdint> 27 #include <map> 28 #include <string> 29 #include <tuple> 30 #include <vector> 31 32 namespace phosphor::power::regulators 33 { 34 35 using namespace sdbusplus::xyz::openbmc_project::Logging::server; 36 using FFDCTuple = 37 std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>; 38 39 /** 40 * @class ErrorLogging 41 * 42 * Abstract base class that provides an error logging interface. 43 * 44 * The interface is used to create error logs. 45 */ 46 class ErrorLogging 47 { 48 public: 49 // Specify which compiler-generated methods we want 50 ErrorLogging() = default; 51 ErrorLogging(const ErrorLogging&) = delete; 52 ErrorLogging(ErrorLogging&&) = delete; 53 ErrorLogging& operator=(const ErrorLogging&) = delete; 54 ErrorLogging& operator=(ErrorLogging&&) = delete; 55 virtual ~ErrorLogging() = default; 56 57 /** 58 * Log a regulators configuration file error. 59 * 60 * This error is logged when the regulators configuration file could not be 61 * found, could not be read, or had invalid contents. 62 * 63 * @param severity severity level 64 * @param journal system journal 65 */ 66 virtual void logConfigFileError(Entry::Level severity, 67 Journal& journal) = 0; 68 69 /** 70 * Log a D-Bus error. 71 * 72 * This error is logged when D-Bus communication fails. 73 * 74 * @param severity severity level 75 * @param journal system journal 76 */ 77 virtual void logDBusError(Entry::Level severity, Journal& journal) = 0; 78 79 /** 80 * Log an I2C communication error. 81 * 82 * @param severity severity level 83 * @param journal system journal 84 * @param bus I2C bus in the form "/dev/i2c-X", where X is the 0-based bus 85 * number 86 * @param addr 7 bit I2C address 87 * @param errorNumber errno value from the failed I2C operation 88 */ 89 virtual void logI2CError(Entry::Level severity, Journal& journal, 90 const std::string& bus, uint8_t addr, 91 int errorNumber) = 0; 92 93 /** 94 * Log an internal firmware error. 95 * 96 * @param severity severity level 97 * @param journal system journal 98 */ 99 virtual void logInternalError(Entry::Level severity, Journal& journal) = 0; 100 101 /** 102 * Log a phase fault error. 103 * 104 * This error is logged when a regulator has lost a redundant phase. 105 * 106 * @param severity severity level 107 * @param journal system journal 108 * @param type phase fault type 109 * @param inventoryPath D-Bus inventory path of the device where the error 110 * occurred 111 * @param additionalData additional error data (if any) 112 */ 113 virtual void 114 logPhaseFault(Entry::Level severity, Journal& journal, 115 PhaseFaultType type, const std::string& inventoryPath, 116 std::map<std::string, std::string> additionalData) = 0; 117 118 /** 119 * Log a PMBus error. 120 * 121 * This error is logged when the I2C communication was successful, but the 122 * PMBus value read is invalid or unsupported. 123 * 124 * @param severity severity level 125 * @param journal system journal 126 * @param inventoryPath D-Bus inventory path of the device where the error 127 * occurred 128 */ 129 virtual void logPMBusError(Entry::Level severity, Journal& journal, 130 const std::string& inventoryPath) = 0; 131 132 /** 133 * Log a write verification error. 134 * 135 * This error is logged when a device register is written, read back, and 136 * the two values do not match. This is also called a read-back error. 137 * 138 * @param severity severity level 139 * @param journal system journal 140 * @param inventoryPath D-Bus inventory path of the device where the error 141 * occurred 142 */ 143 virtual void 144 logWriteVerificationError(Entry::Level severity, Journal& journal, 145 const std::string& inventoryPath) = 0; 146 }; 147 148 /** 149 * @class DBusErrorLogging 150 * 151 * Implementation of the ErrorLogging interface using D-Bus method calls. 152 */ 153 class DBusErrorLogging : public ErrorLogging 154 { 155 public: 156 // Specify which compiler-generated methods we want 157 DBusErrorLogging() = delete; 158 DBusErrorLogging(const DBusErrorLogging&) = delete; 159 DBusErrorLogging(DBusErrorLogging&&) = delete; 160 DBusErrorLogging& operator=(const DBusErrorLogging&) = delete; 161 DBusErrorLogging& operator=(DBusErrorLogging&&) = delete; 162 virtual ~DBusErrorLogging() = default; 163 164 /** 165 * Constructor. 166 * 167 * @param bus D-Bus bus object 168 */ 169 explicit DBusErrorLogging(sdbusplus::bus_t& bus) : bus{bus} 170 {} 171 172 /** @copydoc ErrorLogging::logConfigFileError() */ 173 virtual void logConfigFileError(Entry::Level severity, 174 Journal& journal) override; 175 176 /** @copydoc ErrorLogging::logDBusError() */ 177 virtual void logDBusError(Entry::Level severity, Journal& journal) override; 178 179 /** @copydoc ErrorLogging::logI2CError() */ 180 virtual void logI2CError(Entry::Level severity, Journal& journal, 181 const std::string& bus, uint8_t addr, 182 int errorNumber) override; 183 184 /** @copydoc ErrorLogging::logInternalError() */ 185 virtual void logInternalError(Entry::Level severity, 186 Journal& journal) override; 187 188 /** @copydoc ErrorLogging::logPhaseFault() */ 189 virtual void logPhaseFault( 190 Entry::Level severity, Journal& journal, PhaseFaultType type, 191 const std::string& inventoryPath, 192 std::map<std::string, std::string> additionalData) override; 193 194 /** @copydoc ErrorLogging::logPMBusError() */ 195 virtual void logPMBusError(Entry::Level severity, Journal& journal, 196 const std::string& inventoryPath) override; 197 198 /** @copydoc ErrorLogging::logWriteVerificationError() */ 199 virtual void 200 logWriteVerificationError(Entry::Level severity, Journal& journal, 201 const std::string& inventoryPath) override; 202 203 private: 204 /** 205 * Create an FFDCFile object containing the specified lines of text data. 206 * 207 * Throws an exception if an error occurs. 208 * 209 * @param lines lines of text data to write to file 210 * @return FFDCFile object 211 */ 212 FFDCFile createFFDCFile(const std::vector<std::string>& lines); 213 214 /** 215 * Create FFDCFile objects containing debug data to store in the error log. 216 * 217 * If an error occurs, the error is written to the journal but an exception 218 * is not thrown. 219 * 220 * @param journal system journal 221 * @return vector of FFDCFile objects 222 */ 223 std::vector<FFDCFile> createFFDCFiles(Journal& journal); 224 225 /** 226 * Create FFDCTuple objects corresponding to the specified FFDC files. 227 * 228 * The D-Bus method to create an error log requires a vector of tuples to 229 * pass in the FFDC file information. 230 * 231 * @param files FFDC files 232 * @return vector of FFDCTuple objects 233 */ 234 std::vector<FFDCTuple> createFFDCTuples(std::vector<FFDCFile>& files); 235 236 /** 237 * Logs an error using the D-Bus CreateWithFFDCFiles method. 238 * 239 * If logging fails, a message is written to the journal but an exception is 240 * not thrown. 241 * 242 * @param message Message property of the error log entry 243 * @param severity Severity property of the error log entry 244 * @param additionalData AdditionalData property of the error log entry 245 * @param journal system journal 246 */ 247 void logError(const std::string& message, Entry::Level severity, 248 std::map<std::string, std::string>& additionalData, 249 Journal& journal); 250 251 /** 252 * Removes the specified FFDC files from the file system. 253 * 254 * Also clears the specified vector, removing the FFDCFile objects. 255 * 256 * If an error occurs, the error is written to the journal but an exception 257 * is not thrown. 258 * 259 * @param files FFDC files to remove 260 * @param journal system journal 261 */ 262 void removeFFDCFiles(std::vector<FFDCFile>& files, Journal& journal); 263 264 /** 265 * D-Bus bus object. 266 */ 267 sdbusplus::bus_t& bus; 268 }; 269 270 } // namespace phosphor::power::regulators 271