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 logPhaseFault( 114 Entry::Level severity, Journal& journal, PhaseFaultType type, 115 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 logWriteVerificationError( 144 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 */ DBusErrorLogging(sdbusplus::bus_t & bus)169 explicit DBusErrorLogging(sdbusplus::bus_t& bus) : bus{bus} {} 170 171 /** @copydoc ErrorLogging::logConfigFileError() */ 172 virtual void logConfigFileError(Entry::Level severity, 173 Journal& journal) override; 174 175 /** @copydoc ErrorLogging::logDBusError() */ 176 virtual void logDBusError(Entry::Level severity, Journal& journal) override; 177 178 /** @copydoc ErrorLogging::logI2CError() */ 179 virtual void logI2CError(Entry::Level severity, Journal& journal, 180 const std::string& bus, uint8_t addr, 181 int errorNumber) override; 182 183 /** @copydoc ErrorLogging::logInternalError() */ 184 virtual void logInternalError(Entry::Level severity, 185 Journal& journal) override; 186 187 /** @copydoc ErrorLogging::logPhaseFault() */ 188 virtual void logPhaseFault( 189 Entry::Level severity, Journal& journal, PhaseFaultType type, 190 const std::string& inventoryPath, 191 std::map<std::string, std::string> additionalData) override; 192 193 /** @copydoc ErrorLogging::logPMBusError() */ 194 virtual void logPMBusError(Entry::Level severity, Journal& journal, 195 const std::string& inventoryPath) override; 196 197 /** @copydoc ErrorLogging::logWriteVerificationError() */ 198 virtual void logWriteVerificationError( 199 Entry::Level severity, Journal& journal, 200 const std::string& inventoryPath) override; 201 202 private: 203 /** 204 * Create an FFDCFile object containing the specified lines of text data. 205 * 206 * Throws an exception if an error occurs. 207 * 208 * @param lines lines of text data to write to file 209 * @return FFDCFile object 210 */ 211 FFDCFile createFFDCFile(const std::vector<std::string>& lines); 212 213 /** 214 * Create FFDCFile objects containing debug data to store in the error log. 215 * 216 * If an error occurs, the error is written to the journal but an exception 217 * is not thrown. 218 * 219 * @param journal system journal 220 * @return vector of FFDCFile objects 221 */ 222 std::vector<FFDCFile> createFFDCFiles(Journal& journal); 223 224 /** 225 * Create FFDCTuple objects corresponding to the specified FFDC files. 226 * 227 * The D-Bus method to create an error log requires a vector of tuples to 228 * pass in the FFDC file information. 229 * 230 * @param files FFDC files 231 * @return vector of FFDCTuple objects 232 */ 233 std::vector<FFDCTuple> createFFDCTuples(std::vector<FFDCFile>& files); 234 235 /** 236 * Logs an error using the D-Bus CreateWithFFDCFiles method. 237 * 238 * If logging fails, a message is written to the journal but an exception is 239 * not thrown. 240 * 241 * @param message Message property of the error log entry 242 * @param severity Severity property of the error log entry 243 * @param additionalData AdditionalData property of the error log entry 244 * @param journal system journal 245 */ 246 void logError(const std::string& message, Entry::Level severity, 247 std::map<std::string, std::string>& additionalData, 248 Journal& journal); 249 250 /** 251 * Removes the specified FFDC files from the file system. 252 * 253 * Also clears the specified vector, removing the FFDCFile objects. 254 * 255 * If an error occurs, the error is written to the journal but an exception 256 * is not thrown. 257 * 258 * @param files FFDC files to remove 259 * @param journal system journal 260 */ 261 void removeFFDCFiles(std::vector<FFDCFile>& files, Journal& journal); 262 263 /** 264 * D-Bus bus object. 265 */ 266 sdbusplus::bus_t& bus; 267 }; 268 269 } // namespace phosphor::power::regulators 270