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